package com.android.deskclock;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;

/**
 * TODO: Insert description here. (generated by sblitz)
 */
public class CircleButtonsLinearLayout extends LinearLayout {
    private Context mContext;
    private int mCircleTimerViewId;
    private int mLeftButtonId;
    private int mRightButtonId;
    private int mStopButtonId;
    private int mLabelId;
    private int mLabelTextId;
    private float mLeftButtonPadding;
    private float mRightButtonPadding;
    private float mStrokeSize;
    private float mDiamOffset;
    private CircleTimerView mCtv;
    private ImageButton mLeft, mRight;
    private TextView mStop;
    private FrameLayout mLabel;
    private TextView mLabelText;

    public CircleButtonsLinearLayout(Context context) {
        this(context, null);
        mContext = context;
    }

    public CircleButtonsLinearLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
    }

    public void setCircleTimerViewIds(int circleTimerViewId, int leftButtonId, int rightButtonId,
            int stopButtonId, int leftButtonPaddingDimenId, int rightButtonPaddingDimenId,
            int labelId, int labelTextId) {
        mCircleTimerViewId = circleTimerViewId;
        mLeftButtonId = leftButtonId;
        mRightButtonId = rightButtonId;
        mStopButtonId = stopButtonId;
        mLabelId = labelId;
        mLabelTextId = labelTextId;
        mLeftButtonPadding = mContext.getResources().getDimension(leftButtonPaddingDimenId);
        mRightButtonPadding = mContext.getResources().getDimension(rightButtonPaddingDimenId);

        float diamondStrokeSize =
                mContext.getResources().getDimension(R.dimen.circletimer_diamond_size);
        float markerStrokeSize =
                mContext.getResources().getDimension(R.dimen.circletimer_marker_size);
        mStrokeSize = mContext.getResources().getDimension(R.dimen.circletimer_circle_size);
        mDiamOffset =
                Utils.calculateRadiusOffset(mStrokeSize, diamondStrokeSize, markerStrokeSize) * 2;
    }

    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // We must call onMeasure both before and after re-measuring our views because the circle
        // may not always be drawn here yet. The first onMeasure will force the circle to be drawn,
        // and the second will force our re-measurements to take effect.
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        remeasureViews();
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    protected void remeasureViews() {
        if (mCtv == null) {
            mCtv = (CircleTimerView) findViewById(mCircleTimerViewId);
            if (mCtv == null) {
                return;
            }
            mLeft = (ImageButton) findViewById(mLeftButtonId);
            mRight = (ImageButton) findViewById(mRightButtonId);
            mStop = (TextView) findViewById(mStopButtonId);
            mLabel = (FrameLayout) findViewById(mLabelId);
            mLabelText = (TextView) findViewById(mLabelTextId);
        }

        int frameWidth = mCtv.getMeasuredWidth();
        int frameHeight = mCtv.getMeasuredHeight();
        int minBound = Math.min(frameWidth, frameHeight);
        int circleDiam = (int) (minBound - mDiamOffset);

        MarginLayoutParams stopParams = (MarginLayoutParams) mStop.getLayoutParams();
        stopParams.bottomMargin = circleDiam/6;
        if (minBound == frameWidth) {
            stopParams.bottomMargin += (frameHeight-frameWidth)/2;
        }

        if (mLabel != null) {
            // label will be null if this is a stopwatch, which does not have a label.
            MarginLayoutParams labelParams = (MarginLayoutParams) mLabel.getLayoutParams();
            labelParams.topMargin = circleDiam/6;
            if (minBound == frameWidth) {
                labelParams.topMargin += (frameHeight-frameWidth)/2;
            }
            /* The following formula has been simplified based on the following:
             * Our goal is to calculate the maximum width for the label frame.
             * We may do this with the following diagram to represent the top half of the circle:
             *                 ___
             *            .     |     .
             *        ._________|         .
             *     .       ^    |            .
             *   /         x    |              \
             *  |_______________|_______________|
             *
             *  where x represents the value we would like to calculate, and the final width of the
             *  label will be w = 2 * x.
             *
             *  We may find x by drawing a right triangle from the center of the circle:
             *                 ___
             *            .     |     .
             *        ._________|         .
             *     .    .       |            .
             *   /          .   | }y           \
             *  |_____________.t|_______________|
             *
             *  where t represents the angle of that triangle, and y is the height of that triangle.
             *
             *  If r = radius of the circle, we know the following trigonometric identities:
             *        cos(t) = y / r
             *  and   sin(t) = x / r
             *     => r * sin(t) = x
             *  and   sin^2(t) = 1 - cos^2(t)
             *     => sin(t) = +/- sqrt(1 - cos^2(t))
             *  (note: because we need the positive value, we may drop the +/-).
             *
             *  To calculate the final width, we may combine our formulas:
             *        w = 2 * x
             *     => w = 2 * r * sin(t)
             *     => w = 2 * r * sqrt(1 - cos^2(t))
             *     => w = 2 * r * sqrt(1 - (y / r)^2)
             *
             *  Simplifying even further, to mitigate the complexity of the final formula:
             *        sqrt(1 - (y / r)^2)
             *     => sqrt(1 - (y^2 / r^2))
             *     => sqrt((r^2 / r^2) - (y^2 / r^2))
             *     => sqrt((r^2 - y^2) / (r^2))
             *     => sqrt(r^2 - y^2) / sqrt(r^2)
             *     => sqrt(r^2 - y^2) / r
             *     => sqrt((r + y)*(r - y)) / r
             *
             * Placing this back in our formula, we end up with, as our final, reduced equation:
             *        w = 2 * r * sqrt(1 - (y / r)^2)
             *     => w = 2 * r * sqrt((r + y)*(r - y)) / r
             *     => w = 2 * sqrt((r + y)*(r - y))
             */
            // Radius of the circle.
            int r = circleDiam / 2;
            // Y value of the top of the label, calculated from the center of the circle.
            int y = frameHeight / 2 - labelParams.topMargin;
            // New maximum width of the label.
            double w = 2 * Math.sqrt((r + y) * (r - y));

            mLabelText.setMaxWidth((int) w);
        }

        int sideMarginOffset = (int) ((frameWidth - circleDiam - mStrokeSize) / 2)
                - (int) mContext.getResources().getDimension(R.dimen.timer_button_extra_offset);
        int leftMarginOffset = Math.max(0, sideMarginOffset - (int) mLeftButtonPadding);
        int rightMarginOffset = Math.max(0, sideMarginOffset - (int) mRightButtonPadding);
        int bottomMarginOffset = (frameHeight - minBound) / 2;
        MarginLayoutParams leftParams = (MarginLayoutParams) mLeft.getLayoutParams();
        leftParams.leftMargin = leftMarginOffset;
        leftParams.bottomMargin = bottomMarginOffset;
        MarginLayoutParams rightParams = (MarginLayoutParams) mRight.getLayoutParams();
        rightParams.rightMargin = rightMarginOffset;
        rightParams.bottomMargin = bottomMarginOffset;
    }
}