content: /*
   * MIT License
   *
   * Copyright (c) 2018 Alibaba Group
   *
   * Permission is hereby granted, free of charge, to any person obtaining a copy
   * of this software and associated documentation files (the "Software"), to deal
   * in the Software without restriction, including without limitation the rights
   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   * copies of the Software, and to permit persons to whom the Software is
   * furnished to do so, subject to the following conditions:
   *
   * The above copyright notice and this permission notice shall be included in all
   * copies or substantial portions of the Software.
   *
   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
   * SOFTWARE.
   */
  
  package com.tmall.wireless.vaf.virtualview.layout;
  
  import android.util.Log;
  import android.view.View;
  
  import android.view.View.MeasureSpec;
  import com.libra.Utils;
  import com.libra.virtualview.common.StringBase;
  import com.tmall.wireless.vaf.framework.VafContext;
  import com.tmall.wireless.vaf.virtualview.Helper.RtlHelper;
  import com.tmall.wireless.vaf.virtualview.core.Layout;
  import com.tmall.wireless.vaf.virtualview.core.ViewBase;
  import com.tmall.wireless.vaf.virtualview.core.ViewCache;
  import com.tmall.wireless.vaf.virtualview.core.ViewCache.Item;
  import com.tmall.wireless.vaf.virtualview.layout.RatioLayout.Params;
  
  import static com.libra.virtualview.common.ViewBaseCommon.AUTO_DIM_DIR_X;
  import static com.libra.virtualview.common.ViewBaseCommon.AUTO_DIM_DIR_Y;
  
  /**
   * Created by gujicheng on 16/8/16.
   */
  public class GridLayout extends Layout {
      final static private String TAG = "GridLayout_TMTEST";
  
      protected int mColCount;
      protected int mItemWidth;
      protected int mItemHeight;
      protected int mItemHorizontalMargin = 0;
      protected int mItemVerticalMargin = 0;
  
      public GridLayout(VafContext context, ViewCache vc) {
          super(context, vc);
          mColCount = 1;
          mItemHeight = -1;
      }
  
      @Override
      public void onComMeasure(int widthMeasureSpec, int heightMeasureSpec) {
          if (mAutoDimDirection > 0) {
              switch (mAutoDimDirection) {
                  case AUTO_DIM_DIR_X:
                      if (View.MeasureSpec.EXACTLY == View.MeasureSpec.getMode(widthMeasureSpec)) {
                          heightMeasureSpec = View.MeasureSpec.makeMeasureSpec((int)((View.MeasureSpec.getSize(widthMeasureSpec) * mAutoDimY) / mAutoDimX), View.MeasureSpec.EXACTLY);
                      }
                      break;
  
                  case AUTO_DIM_DIR_Y:
                      if (View.MeasureSpec.EXACTLY == View.MeasureSpec.getMode(heightMeasureSpec)) {
                          widthMeasureSpec = View.MeasureSpec.makeMeasureSpec((int)((View.MeasureSpec.getSize(heightMeasureSpec) * mAutoDimX) / mAutoDimY), View.MeasureSpec.EXACTLY);
                      }
                      break;
              }
          }
  
          int width = View.MeasureSpec.getSize(widthMeasureSpec);
          int height = View.MeasureSpec.getSize(heightMeasureSpec);
  
          int widthMode = View.MeasureSpec.getMode(widthMeasureSpec);
          int heightMode = View.MeasureSpec.getMode(heightMeasureSpec);
  
          int space = mPaddingLeft + mPaddingRight + mItemHorizontalMargin * (mColCount - 1);
          mItemWidth = (width - space) / mColCount;
  
          for (int i = 0, size = mSubViews.size(); i < size; i++) {
              ViewBase child = mSubViews.get(i);
              if (child.isGone()) {
                  continue;
              }
              if (mItemHeight > 0) {
                  child.measureComponent(View.MeasureSpec.makeMeasureSpec(mItemWidth, MeasureSpec.EXACTLY),
                      View.MeasureSpec.makeMeasureSpec(mItemHeight, MeasureSpec.EXACTLY));
              } else {
                  GridLayout.Params childParam = child.getComLayoutParams();
                  child.measureComponent(View.MeasureSpec.makeMeasureSpec(mItemWidth, MeasureSpec.EXACTLY),
                      Layout.getChildMeasureSpec(heightMeasureSpec,
                          mPaddingLeft + mPaddingRight + (mBorderWidth << 1) + childParam.mLayoutMarginLeft
                              + childParam.mLayoutMarginRight, childParam.mLayoutHeight));
              }
          }
  
          setComMeasuredDimension(getRealWidth(widthMode, width),
                  getRealHeight(heightMode, height));
      }
  
      private int getRealWidth(int mode, int size) {
          int ret = size;
          if (View.MeasureSpec.AT_MOST == mode) {
              int childrenWidth = 0;
              Params p = (Params) mParams;
  
              childrenWidth = mPaddingLeft + mPaddingRight;
              int count = 0;
              for (int i = 0, length = mSubViews.size(); i < length; i++) {
                  ViewBase child = mSubViews.get(i);
                  childrenWidth += child.getComMeasuredWidthWithMargin();
                  if (++count >= mColCount) {
                      break;
                  } else {
                      childrenWidth += mItemHorizontalMargin;
                  }
              }
  
              ret = Math.min(size, childrenWidth);
          } else if (View.MeasureSpec.EXACTLY == mode) {
              ret = size;
          } else {
              Log.e(TAG, "getRealWidth error mode:" + mode);
          }
  
          return ret;
      }
  
      private int getRealHeight(int mode, int size) {
          int ret = size;
  
          switch (mode) {
              case View.MeasureSpec.AT_MOST:
              case View.MeasureSpec.UNSPECIFIED: {
                  int h = 0;
                  if (mSubViews.size() > 0) {
                      int count = mSubViews.size();
                      int row = count / mColCount + ((count % mColCount) > 0 ? 1 : 0);
                      if (mItemHeight > 0) {
                          h = row * mItemHeight + mPaddingTop + mPaddingBottom + (row - 1) * mItemVerticalMargin;
                      } else {
                          h = row * (mSubViews.get(0).getComMeasuredHeight()) + mPaddingTop + mPaddingBottom + (row - 1) * mItemVerticalMargin;
                      }
                  }
  
                  if (View.MeasureSpec.AT_MOST == mode) {
                      ret = Math.min(size, h);
                  } else {
                      ret = h;
                  }
                  break;
              }
          }
  
          return ret;
      }
  
      @Override
      public void onComLayout(boolean changed, int l, int t, int r, int b) {
          if (mSubViews.size() > 0) {
              Params p = (Params) mParams;
              int left = l + mPaddingLeft;
              int top = t + mPaddingTop;
  
              int count = mSubViews.size();
              ViewBase c = mSubViews.get(0);
              int totalWidth = this.getComMeasuredWidth();
              int itemWidth = c.getComMeasuredWidth();
              int itemHeight = c.getComMeasuredHeight();
              int rowCount = count / mColCount + ((count % mColCount) > 0 ? 1 : 0);
              int index = 0;
  
              //int padding = (totalWidth - itemWidth * mColCount) / (mColCount + 1);
  
              for (int row = 0; row < rowCount; ++row) {
                  int ll = left;
                  for (int col = 0; (col < mColCount) && (index < count); ++col) {
                      ViewBase child = mSubViews.get(index++);
                      if (child.isGone()) {
                          continue;
                      }
  
                      int realLeft = RtlHelper.getRealLeft(isRtl(), l, getWidth(), ll, itemWidth);
                      child.comLayout(realLeft, top, realLeft + itemWidth, top + itemHeight);
  
                      ll += itemWidth + mItemHorizontalMargin;
                  }
                  if (mItemHeight > 0) {
                      top += mItemHeight + mItemVerticalMargin;
                  } else {
                      top += itemHeight + mItemVerticalMargin;
                  }
              }
          }
      }
  
      @Override
      protected boolean setAttribute(int key, float value) {
          boolean ret = super.setAttribute(key, value);
  
          if (!ret) {
              ret = true;
              switch (key) {
                  case StringBase.STR_ID_itemHeight:
                      mItemHeight = Utils.dp2px(Math.round(value));
                      break;
                  case StringBase.STR_ID_itemHorizontalMargin:
                      mItemHorizontalMargin = Utils.dp2px(value);
                      break;
                  case StringBase.STR_ID_itemVerticalMargin:
                      mItemVerticalMargin = Utils.dp2px(value);
                      break;
                  default:
                      ret = false;
                      break;
              }
          }
  
          return ret;
      }
  
      @Override
      protected boolean setAttribute(int key, int value) {
          boolean ret = super.setAttribute(key, value);
  
          if (!ret) {
              ret = true;
              switch (key) {
                  case StringBase.STR_ID_colCount:
                      mColCount = value;
                      break;
                  case StringBase.STR_ID_itemHeight:
                      mItemHeight = Utils.dp2px(value);
                      break;
                  case StringBase.STR_ID_itemHorizontalMargin:
                      mItemHorizontalMargin = Utils.dp2px(value);
                      break;
                  case StringBase.STR_ID_itemVerticalMargin:
                      mItemVerticalMargin = Utils.dp2px(value);
                      break;
                  default:
                      ret = false;
                      break;
              }
          }
  
          return ret;
      }
  
      @Override
      protected boolean setAttribute(int key, String value) {
          boolean ret = true;
          switch (key) {
              case StringBase.STR_ID_itemHorizontalMargin:
                  mViewCache.put(this, StringBase.STR_ID_itemHorizontalMargin, value, Item.TYPE_FLOAT);
                  break;
              case StringBase.STR_ID_itemVerticalMargin:
                  mViewCache.put(this, StringBase.STR_ID_itemVerticalMargin, value, Item.TYPE_FLOAT);
                  break;
              default:
                  ret = super.setAttribute(key, value);
                  break;
          }
          return ret;
      }
  
      @Override
      protected boolean setRPAttribute(int key, float value) {
          boolean ret = super.setRPAttribute(key, value);
          if (!ret) {
              ret = true;
              switch (key) {
                  case StringBase.STR_ID_itemHeight:
                      mItemHeight = Utils.rp2px(value);
                      break;
                  case StringBase.STR_ID_itemHorizontalMargin:
                      mItemHorizontalMargin = Utils.rp2px(value);
                      break;
                  case StringBase.STR_ID_itemVerticalMargin:
                      mItemVerticalMargin = Utils.rp2px(value);
                      break;
                  default:
                      ret = false;
                      break;
              }
          }
          return ret;
      }
  
      @Override
      protected boolean setRPAttribute(int key, int value) {
          boolean ret = super.setRPAttribute(key, value);
          if (!ret) {
              ret = true;
              switch (key) {
                  case StringBase.STR_ID_itemHeight:
                      mItemHeight = Utils.rp2px(value);
                      break;
                  case StringBase.STR_ID_itemHorizontalMargin:
                      mItemHorizontalMargin = Utils.rp2px(value);
                      break;
                  case StringBase.STR_ID_itemVerticalMargin:
                      mItemVerticalMargin = Utils.rp2px(value);
                      break;
                  default:
                      ret = false;
                      break;
              }
          }
          return ret;
      }
  
      public static class Builder implements ViewBase.IBuilder {
  
          @Override
          public ViewBase build(VafContext context, ViewCache vc) {
              return new GridLayout(context, vc);
          }
      }
  
  }
  