package com.zhy.autolayout.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

import com.zhy.autolayout.AutoLayoutInfo;
import com.zhy.autolayout.R;
import com.zhy.autolayout.utils.AutoLayoutHelper;
import com.zhy.autolayout.utils.AutoUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * Created by zhy on 15/12/10.
 *
 * //do not use
 */
public class MetroLayout extends ViewGroup
{

    private final AutoLayoutHelper mHelper = new AutoLayoutHelper(this);

    private static class MetroBlock
    {
        int left;
        int top;
        int width;
    }

    private List<MetroBlock> mAvailablePos = new ArrayList<>();
    private int mDivider;

    public MetroLayout(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.MetroLayout);
        mDivider = a.getDimensionPixelOffset(R.styleable.MetroLayout_metro_divider, 0);
        mDivider = AutoUtils.getPercentWidthSizeBigger(mDivider);
        a.recycle();

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {

        if (true)
            randomColor();

        if (!isInEditMode())
            mHelper.adjustChildren();

        measureChildren(widthMeasureSpec, heightMeasureSpec);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    }

    private void randomColor()
    {
        Random r = new Random(255);

        for (int i = 0, n = getChildCount(); i < n; i++)
        {
            View v = getChildAt(i);

            v.setBackgroundColor(Color.argb(100, r.nextInt(), r.nextInt(), r.nextInt()));
        }
    }


    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b)
    {

        initAvailablePosition();

        int left = 0;
        int top = 0;
        int divider = mDivider;

        for (int i = 0, n = getChildCount(); i < n; i++)
        {
            View v = getChildAt(i);
            if (v.getVisibility() == View.GONE) continue;

            MetroBlock newPos = findAvailablePos(v);
            left = newPos.left;
            top = newPos.top;

            int childWidth = v.getMeasuredWidth();
            int childHeight = v.getMeasuredHeight();

            int right = left + childWidth;
            int bottom = top + childHeight;

            v.layout(left, top, right, bottom);

            if (childWidth + divider < newPos.width)
            {
                newPos.left += childWidth + divider;
                newPos.width -= childWidth + divider;
            } else
            {
                mAvailablePos.remove(newPos);
            }

            MetroBlock p = new MetroBlock();
            p.left = left;
            p.top = bottom + divider;
            p.width = childWidth;
            mAvailablePos.add(p);

            mergeAvailablePosition();

        }
    }

    private void mergeAvailablePosition()
    {
        if (mAvailablePos.size() <= 1) return;

        List<MetroBlock> needRemoveBlocks = new ArrayList<>();

        MetroBlock one = mAvailablePos.get(0);
        MetroBlock two = mAvailablePos.get(1);

        for (int i = 1, n = mAvailablePos.size(); i < n - 1; i++)
        {
            if (one.top == two.top)
            {
                one.width = one.width + two.width;
                needRemoveBlocks.add(one);
                two.left = one.left;
                two = mAvailablePos.get(i + 1);
            } else
            {
                one = mAvailablePos.get(i);
                two = mAvailablePos.get(i + 1);
            }
        }

        mAvailablePos.removeAll(needRemoveBlocks);

    }

    private void initAvailablePosition()
    {
        mAvailablePos.clear();
        MetroBlock first = new MetroBlock();
        first.left = getPaddingLeft();
        first.top = getPaddingTop();
        first.width = getMeasuredWidth();
        mAvailablePos.add(first);
    }

    private MetroBlock findAvailablePos(View view)
    {
        MetroBlock p = new MetroBlock();
        if (mAvailablePos.size() == 0)
        {
            p.left = getPaddingLeft();
            p.top = getPaddingTop();
            p.width = getMeasuredWidth();
            return p;
        }
        int min = mAvailablePos.get(0).top;
        MetroBlock minHeightPos = mAvailablePos.get(0);
        for (MetroBlock _p : mAvailablePos)
        {
            if (_p.top < min)
            {
                min = _p.top;
                minHeightPos = _p;
            }
        }
        return minHeightPos;
    }


    @Override
    public MetroLayout.LayoutParams generateLayoutParams(AttributeSet attrs)
    {
        return new LayoutParams(getContext(), attrs);
    }

    public static class LayoutParams extends ViewGroup.MarginLayoutParams
            implements AutoLayoutHelper.AutoLayoutParams
    {
        private AutoLayoutInfo mAutoLayoutInfo;

        public LayoutParams(Context c, AttributeSet attrs)
        {
            super(c, attrs);
            mAutoLayoutInfo = AutoLayoutHelper.getAutoLayoutInfo(c, attrs);
        }

        public LayoutParams(int width, int height)
        {
            super(width, height);
        }

        public LayoutParams(ViewGroup.LayoutParams source)
        {
            super(source);
        }

        public LayoutParams(MarginLayoutParams source)
        {
            super(source);
        }

        public LayoutParams(LayoutParams source)
        {
            this((ViewGroup.LayoutParams) source);
            mAutoLayoutInfo = source.mAutoLayoutInfo;
        }

        @Override
        public AutoLayoutInfo getAutoLayoutInfo()
        {
            return mAutoLayoutInfo;
        }


    }

}