package com.guadou.ninegrid.nine_grid_layout;

import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.guadou.ninegrid.R;

import java.lang.reflect.Array;

/**
 * 抽象九宫格-具体的布局和测量在这里完成
 */
public abstract class AbstractNineGridLayout<T> extends ViewGroup {

    private static final int MAX_CHILDREN_COUNT = 9;
    private int itemWidth;
    private int itemHeight;
    private int horizontalSpacing;
    private int verticalSpacing;
    private boolean singleMode;
    private boolean fourGridMode;
    private int singleWidth;
    private int singleHeight;
    private boolean singleModeOverflowScale;
//    private NineGridItemCacheBean mNineGridItemCacheBean;

    public AbstractNineGridLayout(Context context) {
        this(context, null);
    }

    public AbstractNineGridLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        if (attrs != null) {
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NineGridLayout);
            int spacing = a.getDimensionPixelSize(R.styleable.NineGridLayout_spacing, 0);
            horizontalSpacing = a.getDimensionPixelSize(R.styleable.NineGridLayout_horizontal_spacing, spacing);
            verticalSpacing = a.getDimensionPixelSize(R.styleable.NineGridLayout_vertical_spacing, spacing);
            singleMode = a.getBoolean(R.styleable.NineGridLayout_single_mode, true);
            fourGridMode = a.getBoolean(R.styleable.NineGridLayout_four_gird_mode, true);
            singleWidth = a.getDimensionPixelSize(R.styleable.NineGridLayout_single_mode_width, 0);
            singleHeight = a.getDimensionPixelSize(R.styleable.NineGridLayout_single_mode_height, 0);
            singleModeOverflowScale = a.getBoolean(R.styleable.NineGridLayout_single_mode_overflow_scale, true);
            a.recycle();
        }

        //优先填充布局，再执行测量和绘制
        fill();
    }

    /**
     * 设置显示的数量
     */
    public void setDisplayCount(int count) {
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            getChildAt(i).setVisibility(i < count ? VISIBLE : GONE);
        }
    }

    /**
     * 设置单独布局的宽和高
     */
    public void setSingleModeSize(int w, int h) {
        if (w != 0 && h != 0) {
            this.singleWidth = w;
            this.singleHeight = h;
        }
    }

    protected void fill(ViewGetter viewGetter) {
        removeAllViews();
        for (int i = 0; i < MAX_CHILDREN_COUNT; i++) {
            addView(viewGetter.getView(i));
        }
    }

    /**
     * 一般用这个方法填充布局，每一个小布局的布局文件
     */
    protected void fill(int layoutId) {
        removeAllViews();
        for (int i = 0; i < MAX_CHILDREN_COUNT; i++) {
            LayoutInflater.from(getContext()).inflate(layoutId, this);
        }
    }

    /**
     * 返回每一个小布局的内部控件ID，用数组包装返回
     */
    @SuppressWarnings("unchecked")
    protected <V extends View> V[] findInChildren(int viewId, Class<V> clazz) {
        V[] result = (V[]) Array.newInstance(clazz, getChildCount());
        for (int i = 0; i < result.length; i++) {
            result[i] = (V) getChildAt(i).findViewById(viewId);
        }
        return result;
    }

    //子类去实现-填充布局文件
    protected abstract void fill();

    //子类去实现-对布局文件赋值（专门去给adapter去调用的）
    public abstract void render(Activity activity, T data);


    //提供缓存对象出去，给Adapter去保存索引
//    public NineGridItemCacheBean obtainNineGridItemCacheBean() {
//        return mNineGridItemCacheBean;
//    }
//
//    public void setNineGridItemCacheBean(NineGridItemCacheBean cacheBean, OnInflateFinishListener inflateFinish) {
//        mNineGridItemCacheBean = cacheBean;
//        mListener = inflateFinish;
//    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//        YYLogUtils.e("onMeasure");

//        if (mNineGridItemCacheBean == null)
//            mNineGridItemCacheBean = new NineGridItemCacheBean();
//
//        //判断缓存,如果可以，直接测量出来占位
//        if (mNineGridItemCacheBean.widgetWidth != 0 && mNineGridItemCacheBean.widgetHeight != 0) {
//
//            setMeasuredDimension(mNineGridItemCacheBean.widgetWidth, mNineGridItemCacheBean.widgetHeight);
//            YYLogUtils.e("测量完毕回调出去1");
//            //测量完毕回调出去
//            mListener.onFinish(mNineGridItemCacheBean);
//        } else {

        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec) - getPaddingLeft() - getPaddingRight();

        int notGoneChildCount = getNotGoneChildCount();

        //判断子布局的缓存
//            if (mNineGridItemCacheBean.childHeight != 0 && mNineGridItemCacheBean.childWidth != 0) {
//
//                itemWidth = mNineGridItemCacheBean.childWidth;
//                itemHeight = mNineGridItemCacheBean.childHeight;
//
//            } else {

        if (notGoneChildCount == 1 && singleMode) {
            itemWidth = singleWidth > 0 ? singleWidth : widthSize;
            itemHeight = singleHeight > 0 ? singleHeight : widthSize;
            if (itemWidth > widthSize && singleModeOverflowScale) {
                itemWidth = widthSize;  //单张图片先定宽度。
                itemHeight = (int) (widthSize * 1f / singleWidth * singleHeight);  //根据宽度计算高度
            }
        } else {
            itemWidth = (widthSize - horizontalSpacing * 2) / 3;
            itemHeight = itemWidth;
        }

        //缓存赋值
//                mNineGridItemCacheBean.childWidth = itemWidth;
//                mNineGridItemCacheBean.childHeight = itemHeight;

//            }

        //测量子布局
        measureChildren(MeasureSpec.makeMeasureSpec(itemWidth, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(itemHeight, MeasureSpec.EXACTLY));


        if (heightMode == MeasureSpec.EXACTLY) {
            setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
        } else {
            notGoneChildCount = Math.min(notGoneChildCount, MAX_CHILDREN_COUNT);
            int height = ((notGoneChildCount - 1) / 3 + 1) * (itemHeight + verticalSpacing) - verticalSpacing + getPaddingTop() + getPaddingBottom();

            setMeasuredDimension(widthMeasureSpec, MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));

            //缓存赋值
//                mNineGridItemCacheBean.widgetWidth = widthMeasureSpec;
//                mNineGridItemCacheBean.widgetHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);

//                YYLogUtils.e("测量完毕回调出去2");
            //测量完毕回调出去
//                if (mListener != null) mListener.onFinish(mNineGridItemCacheBean);
        }

//        }
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
//        YYLogUtils.e("onLayout");
        int childCount = getChildCount();
        int notGoneChildCount = getNotGoneChildCount();
        int position = 0;
        for (int i = 0; i < childCount; i++) {
            View child = getChildAt(i);
            if (child.getVisibility() == View.GONE) {
                continue;
            }
            int row = position / 3;
            int col = position % 3;

            if (notGoneChildCount == 4 && fourGridMode) {
                row = position / 2;
                col = position % 2;
            }

            int x = col * itemWidth + getPaddingLeft() + horizontalSpacing * col;
            int y = row * itemHeight + getPaddingTop() + verticalSpacing * row;
            child.layout(x, y, x + itemWidth, y + itemHeight);

            position++;
            if (position == MAX_CHILDREN_COUNT) {
                break;
            }
        }
    }

    //获取没有隐藏的子布局
    private int getNotGoneChildCount() {
        int childCount = getChildCount();
        int notGoneCount = 0;
        for (int i = 0; i < childCount; i++) {
            if (getChildAt(i).getVisibility() != View.GONE) {
                notGoneCount++;
            }
        }
        return notGoneCount;
    }


//    private OnInflateFinishListener mListener;
//
//    public interface OnInflateFinishListener {
//        void onFinish(NineGridItemCacheBean cacheBean);
//    }
}
