/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

/**
 * @hide
 */
public class ButtonGroup extends LinearLayout {
    private static final String LOG = "ButtonGroup";

    private Drawable mDivider;
    private int mDividerWidth;
    private int mDividerHeight;
    private int mButtonBackgroundRes;
    private int mShowDividers;

    /**
     * Don't show any dividers.
     */
    public static final int SHOW_DIVIDER_NONE = 0;
    /**
     * Show a divider at the beginning of the group.
     */
    public static final int SHOW_DIVIDER_BEGINNING = 1;
    /**
     * Show dividers between each item in the group.
     */
    public static final int SHOW_DIVIDER_MIDDLE = 2;
    /**
     * Show a divider at the end of the group.
     */
    public static final int SHOW_DIVIDER_END = 4;

    private final Rect mTempRect = new Rect();

    public ButtonGroup(Context context) {
        this(context, null);
    }
    
    public ButtonGroup(Context context, AttributeSet attrs) {
        this(context, attrs, com.android.internal.R.attr.buttonGroupStyle);
    }
    
    public ButtonGroup(Context context, AttributeSet attrs, int defStyleRes) {
        super(context, attrs, defStyleRes);
        
        TypedArray a = context.obtainStyledAttributes(attrs,
                com.android.internal.R.styleable.ButtonGroup, defStyleRes, 0);
        
        setDividerDrawable(a.getDrawable(com.android.internal.R.styleable.ButtonGroup_divider));
        mButtonBackgroundRes = a.getResourceId(
                com.android.internal.R.styleable.ButtonGroup_buttonBackground, 0);
        setShowDividers(a.getInt(com.android.internal.R.styleable.ButtonGroup_showDividers,
                SHOW_DIVIDER_MIDDLE));
        a.recycle();
    }

    /**
     * Set how dividers should be shown between items in this button group.
     *
     * @param showDividers One or more of {@link #SHOW_DIVIDER_BEGINNING},
     *                     {@link #SHOW_DIVIDER_MIDDLE}, or {@link #SHOW_DIVIDER_END},
     *                     or {@link #SHOW_DIVIDER_NONE} to show no dividers.
     */
    public void setShowDividers(int showDividers) {
        if (showDividers != mShowDividers) {
            requestLayout();
        }
        mShowDividers = showDividers;
    }

    /**
     * @return A flag set indicating how dividers should be shown around items.
     * @see #setShowDividers(int)
     */
    public int getShowDividers() {
        return mShowDividers;
    }

    /**
     * Set a drawable to be used as a divider between items.
     * @param divider Drawable that will divide each item.
     */
    public void setDividerDrawable(Drawable divider) {
        if (divider == mDivider) {
            return;
        }
        mDivider = divider;
        if (divider != null) {
            mDividerWidth = divider.getIntrinsicWidth();
            mDividerHeight = divider.getIntrinsicHeight();
        } else {
            mDividerWidth = 0;
            mDividerHeight = 0;
        }
        requestLayout();
    }

    /**
     * Retrieve the drawable used to draw dividers between items.
     * @return The divider drawable
     */
    public Drawable getDividerDrawable() {
        return mDivider;
    }

    @Override
    public void addView(View child, int index, ViewGroup.LayoutParams params) {
        if (child instanceof Button && mButtonBackgroundRes != 0) {
            // Preserve original padding as we change the background
            final int paddingLeft = child.getPaddingLeft();
            final int paddingRight = child.getPaddingRight();
            final int paddingTop = child.getPaddingTop();
            final int paddingBottom = child.getPaddingBottom();
            child.setBackgroundResource(mButtonBackgroundRes);
            child.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
        }

        super.addView(child, index, params);
    }

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        // Add the extra size that dividers contribute.
        int dividerCount = 0;
        if ((mShowDividers & SHOW_DIVIDER_MIDDLE) == SHOW_DIVIDER_MIDDLE) {
            final int childCount = getChildCount();
            for (int i = 0; i < childCount; i++) {
                if (getChildAt(i).getVisibility() != GONE) {
                    dividerCount++;
                }
            }
            dividerCount = Math.max(0, dividerCount);
        }
        if ((mShowDividers & SHOW_DIVIDER_BEGINNING) == SHOW_DIVIDER_BEGINNING) {
            dividerCount++;
        }
        if ((mShowDividers & SHOW_DIVIDER_END) == SHOW_DIVIDER_END) {
            dividerCount++;
        }

        if (getOrientation() == VERTICAL) {
            final int dividerSize = mDividerHeight * dividerCount;
            setMeasuredDimension(getMeasuredWidth(),
                    resolveSize(getMeasuredHeight() + dividerSize, heightMeasureSpec));
        } else {
            final int dividerSize = mDividerWidth * dividerCount;
            setMeasuredDimension(resolveSize(getMeasuredWidth() + dividerSize, widthMeasureSpec),
                    getMeasuredHeight());
        }
    }

    @Override
    public void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);

        final boolean begin = (mShowDividers & SHOW_DIVIDER_BEGINNING) == SHOW_DIVIDER_BEGINNING;
        final boolean middle = (mShowDividers & SHOW_DIVIDER_MIDDLE) == SHOW_DIVIDER_MIDDLE;

        // Offset children to leave space for dividers.
        if (getOrientation() == VERTICAL) {
            int offset = begin ? mDividerHeight : 0;
            final int childCount = getChildCount();
            for (int i = 0; i < childCount; i++) {
                View child = getChildAt(i);
                child.offsetTopAndBottom(offset);
                if (middle && child.getVisibility() != GONE) {
                    offset += mDividerHeight;
                }
            }
        } else {
            int offset = begin ? mDividerWidth : 0;
            final int childCount = getChildCount();
            for (int i = 0; i < childCount; i++) {
                View child = getChildAt(i);
                child.offsetLeftAndRight(offset);
                if (middle && child.getVisibility() != GONE) {
                    offset += mDividerWidth;
                }
            }
        }
    }

    @Override
    public void dispatchDraw(Canvas canvas) {
        if (mDivider == null) {
            super.dispatchDraw(canvas);
            return;
        }

        final boolean begin = (mShowDividers & SHOW_DIVIDER_BEGINNING) == SHOW_DIVIDER_BEGINNING;
        final boolean middle = (mShowDividers & SHOW_DIVIDER_MIDDLE) == SHOW_DIVIDER_MIDDLE;
        final boolean end = (mShowDividers & SHOW_DIVIDER_END) == SHOW_DIVIDER_END;
        final boolean vertical = getOrientation() == VERTICAL;

        final Rect bounds = mTempRect;
        bounds.left = mPaddingLeft;
        bounds.right = mRight - mLeft - mPaddingRight;
        bounds.top = mPaddingTop;
        bounds.bottom = mBottom - mTop - mPaddingBottom;

        if (begin) {
            if (vertical) {
                bounds.bottom = bounds.top + mDividerHeight;
            } else {
                bounds.right = bounds.left + mDividerWidth;
            }
            mDivider.setBounds(bounds);
            mDivider.draw(canvas);
        }

        final int childCount = getChildCount();
        int i = 0;
        while (i < childCount) {
            final View child = getChildAt(i);
            i++;
            if ((middle && i < childCount && child.getVisibility() != GONE) || end) {
                if (vertical) {
                    bounds.top = child.getBottom();
                    bounds.bottom = bounds.top + mDividerHeight;
                } else {
                    bounds.left = child.getRight();
                    bounds.right = bounds.left + mDividerWidth;
                }
                mDivider.setBounds(bounds);
                mDivider.draw(canvas);
            }
        }

        super.dispatchDraw(canvas);
    }
}
