
package org.zarroboogs.weibo.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

public class QuickRelativeLayout extends ViewGroup {

    private static final int AVATAR_INDEX = 0;
    private static final int COUNT_INDEX = 1;
    private static final int USERNAME_INDEX = 2;
    private static final int TIME_INDEX = 3;
    private static final int SOURCE_INDEX = 4;
    private static final int CONTENT_INDEX = 5;
    private static final int REPOST_FLAG_INDEX = 6;
    private static final int REPOST_CONTENT_INDEX = 7;
    private static final int REPOST_CONTENT_PIC_INDEX = 8;
    private static final int REPOST_CONTENT_PIC_MULTI_INDEX = 9;

    public QuickRelativeLayout(Context context) {
        super(context);
    }

    public QuickRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public QuickRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

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

        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);

        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);

        if (widthMode != MeasureSpec.EXACTLY || heightMode != MeasureSpec.UNSPECIFIED)
            throw new IllegalArgumentException(
                    "this viewgroup only can be used in ListView and its layout_width must be match_parent");

        int paddingLeft = getPaddingLeft();
        int paddingTop = getPaddingTop();
        int paddingBottom = getPaddingBottom();
        int paddingRight = getPaddingRight();

        int avatarHeight = 0;
        int avatarWidth = 0;

        int countHeight = 0;
        int countWidth = 0;

        int usernameHeight = 0;
        int usernameWidth = 0;

        int timeHeight = 0;
        int timeWidth = 0;

        int sourceHeight = 0;
        int sourceWidth = 0;

        int contentMaxWidth = widthSize - paddingLeft - paddingRight;

        int childCount = getChildCount();

        int contentHeight = 0;

        for (int i = 0; i < childCount; i++) {
            View child = getChildAt(i);

            if (child.getVisibility() == View.GONE)
                continue;

            final LayoutParams lp = (LayoutParams) child.getLayoutParams();
            int defaultWidth = lp.width;
            int defaultHeight = lp.height;

            int heightSpec = 0;
            int widthSpec = 0;

            switch (i) {

                case AVATAR_INDEX:
                    widthSpec = MeasureSpec.makeMeasureSpec(defaultWidth, MeasureSpec.EXACTLY);
                    heightSpec = MeasureSpec.makeMeasureSpec(defaultHeight, MeasureSpec.EXACTLY);
                    child.measure(widthSpec, heightSpec);

                    avatarWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
                    avatarHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;

                    lp.mLeft = paddingLeft + lp.leftMargin;
                    lp.mTop = paddingTop + lp.topMargin;
                    lp.mRight = lp.mLeft + child.getMeasuredWidth();
                    lp.mBottom = lp.mTop + child.getMeasuredHeight();
                    break;
                case COUNT_INDEX:
                    widthSpec = MeasureSpec.makeMeasureSpec(contentMaxWidth, MeasureSpec.AT_MOST);
                    heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
                    child.measure(widthSpec, heightSpec);

                    countWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
                    countHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;

                    lp.mRight = widthSize - paddingRight - lp.rightMargin;
                    lp.mLeft = lp.mRight - child.getMeasuredWidth();
                    lp.mTop = paddingTop + lp.topMargin;
                    lp.mBottom = lp.mTop + child.getMeasuredHeight();

                    break;
                case USERNAME_INDEX:
                    int childWidth = contentMaxWidth - avatarWidth - countWidth - lp.leftMargin - lp.rightMargin;
                    widthSpec = MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.AT_MOST);
                    heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
                    child.measure(widthSpec, heightSpec);

                    usernameWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
                    usernameHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;

                    lp.mLeft = paddingLeft + avatarWidth + lp.leftMargin;

                    lp.mRight = lp.mLeft + child.getMeasuredWidth();
                    lp.mTop = paddingTop + lp.topMargin;
                    lp.mBottom = lp.mTop + child.getMeasuredHeight();

                    break;
                case TIME_INDEX:
                    int timeChildMaxWidth = contentMaxWidth - avatarWidth - lp.leftMargin - lp.rightMargin;
                    widthSpec = MeasureSpec.makeMeasureSpec(timeChildMaxWidth, MeasureSpec.AT_MOST);
                    heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
                    child.measure(widthSpec, heightSpec);

                    timeWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
                    timeHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;

                    lp.mLeft = paddingLeft + avatarWidth + lp.leftMargin;
                    lp.mRight = lp.mLeft + child.getMeasuredWidth();

                    lp.mTop = paddingTop + usernameHeight + lp.topMargin;
                    lp.mBottom = lp.mTop + child.getMeasuredHeight();

                    break;
                case SOURCE_INDEX:
                    int sourceChildMaxWidth = contentMaxWidth - avatarWidth - timeWidth - lp.leftMargin - lp.rightMargin;
                    widthSpec = MeasureSpec.makeMeasureSpec(sourceChildMaxWidth, MeasureSpec.AT_MOST);
                    heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
                    child.measure(widthSpec, heightSpec);

                    sourceWidth = child.getMeasuredWidth() + lp.leftMargin + lp.rightMargin;
                    sourceHeight = child.getMeasuredHeight() + lp.topMargin + lp.bottomMargin;

                    lp.mLeft = paddingLeft + avatarWidth + timeWidth + lp.leftMargin;
                    lp.mRight = lp.mLeft + child.getMeasuredWidth();

                    lp.mTop = paddingTop + usernameHeight + lp.topMargin;
                    lp.mBottom = lp.mTop + child.getMeasuredHeight();

                    break;
                case CONTENT_INDEX:
                    int contentChildMaxWidth = contentMaxWidth - lp.leftMargin - lp.rightMargin;
                    widthSpec = MeasureSpec.makeMeasureSpec(contentChildMaxWidth, MeasureSpec.EXACTLY);
                    heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
                    child.measure(widthSpec, heightSpec);

                    lp.mLeft = paddingLeft + lp.leftMargin;
                    lp.mRight = lp.mLeft + child.getMeasuredWidth();

                    lp.mTop = paddingTop + avatarHeight + lp.topMargin;
                    lp.mBottom = lp.mTop + child.getMeasuredHeight();

                    contentHeight = lp.mBottom + lp.bottomMargin;

                    break;
                case REPOST_FLAG_INDEX:
                case REPOST_CONTENT_INDEX:
                    int repostContentChildMaxWidth = contentMaxWidth - lp.leftMargin - lp.rightMargin;
                    widthSpec = MeasureSpec.makeMeasureSpec(repostContentChildMaxWidth, MeasureSpec.EXACTLY);
                    heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
                    child.measure(widthSpec, heightSpec);

                    lp.mLeft = paddingLeft + lp.leftMargin;
                    lp.mRight = lp.mLeft + child.getMeasuredWidth();

                    lp.mTop = contentHeight + lp.topMargin;
                    lp.mBottom = lp.mTop + child.getMeasuredHeight();

                    contentHeight = lp.mBottom + lp.bottomMargin;
                    break;
                case REPOST_CONTENT_PIC_INDEX:
                    int repostContentPicChildMaxWidth = contentMaxWidth - lp.leftMargin - lp.rightMargin;
                    widthSpec = MeasureSpec.makeMeasureSpec(repostContentPicChildMaxWidth, MeasureSpec.EXACTLY);
                    heightSpec = MeasureSpec.makeMeasureSpec(defaultHeight, MeasureSpec.EXACTLY);
                    child.measure(widthSpec, heightSpec);

                    lp.mLeft = paddingLeft + lp.leftMargin;
                    lp.mRight = lp.mLeft + child.getMeasuredWidth();

                    lp.mTop = contentHeight + lp.topMargin;
                    lp.mBottom = lp.mTop + child.getMeasuredHeight();

                    contentHeight = lp.mBottom + lp.bottomMargin;
                    break;
                case REPOST_CONTENT_PIC_MULTI_INDEX:
                    int repostContentMultiPicChildMaxWidth = contentMaxWidth - lp.leftMargin - lp.rightMargin;
                    widthSpec = MeasureSpec.makeMeasureSpec(repostContentMultiPicChildMaxWidth, MeasureSpec.EXACTLY);
                    heightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
                    child.measure(widthSpec, heightSpec);

                    lp.mLeft = paddingLeft + lp.leftMargin;
                    lp.mRight = lp.mLeft + child.getMeasuredWidth();

                    lp.mTop = contentHeight + lp.topMargin;
                    lp.mBottom = lp.mTop + child.getMeasuredHeight();

                    contentHeight = lp.mBottom + lp.bottomMargin;
                    break;
            }

        }

        contentHeight += paddingBottom;

        setMeasuredDimension(widthSize, contentHeight);
    }

    @Override
    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
        return p instanceof LayoutParams;
    }

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

    @Override
    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
        return new LayoutParams(p);
    }

    @Override
    protected LayoutParams generateDefaultLayoutParams() {
        return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    }

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

        int childCount = getChildCount();

        for (int i = 0; i < childCount; i++) {

            View child = getChildAt(i);
            if (child.getVisibility() == View.GONE)
                continue;

            final LayoutParams lp = (LayoutParams) child.getLayoutParams();

            child.layout(lp.mLeft, lp.mTop, lp.mRight, lp.mBottom);
        }

    }

    public static class LayoutParams extends MarginLayoutParams {

        private int mLeft, mTop, mRight, mBottom;

        public LayoutParams(Context c, AttributeSet attrs) {
            super(c, attrs);

        }

        public LayoutParams(int w, int h) {
            super(w, h);
        }

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

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

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

        }

    }

}
