/*
 * Copyright (C) 2013 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 com.android.datetimepicker.time;

import android.animation.Keyframe;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.Log;
import android.view.View;

import com.android.datetimepicker.R;
import com.android.datetimepicker.Utils;

/**
 * View to show what number is selected. This will draw a blue circle over the number, with a blue
 * line coming from the center of the main circle to the edge of the blue selection.
 */
class RadialSelectorView extends View {
    private static final String TAG = "RadialSelectorView";

    // Alpha level for selected circle.
    private static final int SELECTED_ALPHA = Utils.SELECTED_ALPHA;
    private static final int SELECTED_ALPHA_THEME_DARK = Utils.SELECTED_ALPHA_THEME_DARK;
    // Alpha level for the line.
    private static final int FULL_ALPHA = Utils.FULL_ALPHA;

    private final Paint mPaint = new Paint();

    private boolean mIsInitialized;
    private boolean mDrawValuesReady;

    private float mCircleRadiusMultiplier;
    private float mAmPmCircleRadiusMultiplier;
    private float mInnerNumbersRadiusMultiplier;
    private float mOuterNumbersRadiusMultiplier;
    private float mNumbersRadiusMultiplier;
    private float mSelectionRadiusMultiplier;
    private float mAnimationRadiusMultiplier;
    private boolean mIs24HourMode;
    private boolean mHasInnerCircle;
    private int mSelectionAlpha;

    private int mXCenter;
    private int mYCenter;
    private int mCircleRadius;
    private float mTransitionMidRadiusMultiplier;
    private float mTransitionEndRadiusMultiplier;
    private int mLineLength;
    private int mSelectionRadius;
    private InvalidateUpdateListener mInvalidateUpdateListener;

    private int mSelectionDegrees;
    private double mSelectionRadians;
    private boolean mForceDrawDot;

    public RadialSelectorView(Context context) {
        super(context);
        mIsInitialized = false;
    }

    /**
     * Initialize this selector with the state of the picker.
     * @param context Current context.
     * @param is24HourMode Whether the selector is in 24-hour mode, which will tell us
     * whether the circle's center is moved up slightly to make room for the AM/PM circles.
     * @param hasInnerCircle Whether we have both an inner and an outer circle of numbers
     * that may be selected. Should be true for 24-hour mode in the hours circle.
     * @param disappearsOut Whether the numbers' animation will have them disappearing out
     * or disappearing in.
     * @param selectionDegrees The initial degrees to be selected.
     * @param isInnerCircle Whether the initial selection is in the inner or outer circle.
     * Will be ignored when hasInnerCircle is false.
     */
    public void initialize(Context context, boolean is24HourMode, boolean hasInnerCircle,
            boolean disappearsOut, int selectionDegrees, boolean isInnerCircle) {
        if (mIsInitialized) {
            Log.e(TAG, "This RadialSelectorView may only be initialized once.");
            return;
        }

        Resources res = context.getResources();

        int blue = res.getColor(R.color.blue);
        mPaint.setColor(blue);
        mPaint.setAntiAlias(true);
        mSelectionAlpha = SELECTED_ALPHA;

        // Calculate values for the circle radius size.
        mIs24HourMode = is24HourMode;
        if (is24HourMode) {
            mCircleRadiusMultiplier = Float.parseFloat(
                    res.getString(R.string.circle_radius_multiplier_24HourMode));
        } else {
            mCircleRadiusMultiplier = Float.parseFloat(
                    res.getString(R.string.circle_radius_multiplier));
            mAmPmCircleRadiusMultiplier =
                    Float.parseFloat(res.getString(R.string.ampm_circle_radius_multiplier));
        }

        // Calculate values for the radius size(s) of the numbers circle(s).
        mHasInnerCircle = hasInnerCircle;
        if (hasInnerCircle) {
            mInnerNumbersRadiusMultiplier =
                    Float.parseFloat(res.getString(R.string.numbers_radius_multiplier_inner));
            mOuterNumbersRadiusMultiplier =
                    Float.parseFloat(res.getString(R.string.numbers_radius_multiplier_outer));
        } else {
            mNumbersRadiusMultiplier =
                    Float.parseFloat(res.getString(R.string.numbers_radius_multiplier_normal));
        }
        mSelectionRadiusMultiplier =
                Float.parseFloat(res.getString(R.string.selection_radius_multiplier));

        // Calculate values for the transition mid-way states.
        mAnimationRadiusMultiplier = 1;
        mTransitionMidRadiusMultiplier = 1f + (0.05f * (disappearsOut? -1 : 1));
        mTransitionEndRadiusMultiplier = 1f + (0.3f * (disappearsOut? 1 : -1));
        mInvalidateUpdateListener = new InvalidateUpdateListener();

        setSelection(selectionDegrees, isInnerCircle, false);
        mIsInitialized = true;
    }

    /* package */ void setTheme(Context context, boolean themeDark) {
        Resources res = context.getResources();
        int color;
        if (themeDark) {
            color = res.getColor(R.color.red);
            mSelectionAlpha = SELECTED_ALPHA_THEME_DARK;
        } else {
            color = res.getColor(R.color.blue);
            mSelectionAlpha = SELECTED_ALPHA;
        }
        mPaint.setColor(color);
    }

    /**
     * Set the selection.
     * @param selectionDegrees The degrees to be selected.
     * @param isInnerCircle Whether the selection should be in the inner circle or outer. Will be
     * ignored if hasInnerCircle was initialized to false.
     * @param forceDrawDot Whether to force the dot in the center of the selection circle to be
     * drawn. If false, the dot will be drawn only when the degrees is not a multiple of 30, i.e.
     * the selection is not on a visible number.
     */
    public void setSelection(int selectionDegrees, boolean isInnerCircle, boolean forceDrawDot) {
        mSelectionDegrees = selectionDegrees;
        mSelectionRadians = selectionDegrees * Math.PI / 180;
        mForceDrawDot = forceDrawDot;

        if (mHasInnerCircle) {
            if (isInnerCircle) {
                mNumbersRadiusMultiplier = mInnerNumbersRadiusMultiplier;
            } else {
                mNumbersRadiusMultiplier = mOuterNumbersRadiusMultiplier;
            }
        }
    }

    /**
     * Allows for smoother animations.
     */
    @Override
    public boolean hasOverlappingRendering() {
        return false;
    }

    /**
     * Set the multiplier for the radius. Will be used during animations to move in/out.
     */
    public void setAnimationRadiusMultiplier(float animationRadiusMultiplier) {
        mAnimationRadiusMultiplier = animationRadiusMultiplier;
    }

    public int getDegreesFromCoords(float pointX, float pointY, boolean forceLegal,
            final Boolean[] isInnerCircle) {
        if (!mDrawValuesReady) {
            return -1;
        }

        double hypotenuse = Math.sqrt(
                (pointY - mYCenter)*(pointY - mYCenter) +
                (pointX - mXCenter)*(pointX - mXCenter));
        // Check if we're outside the range
        if (mHasInnerCircle) {
            if (forceLegal) {
                // If we're told to force the coordinates to be legal, we'll set the isInnerCircle
                // boolean based based off whichever number the coordinates are closer to.
                int innerNumberRadius = (int) (mCircleRadius * mInnerNumbersRadiusMultiplier);
                int distanceToInnerNumber = (int) Math.abs(hypotenuse - innerNumberRadius);
                int outerNumberRadius = (int) (mCircleRadius * mOuterNumbersRadiusMultiplier);
                int distanceToOuterNumber = (int) Math.abs(hypotenuse - outerNumberRadius);

                isInnerCircle[0] = (distanceToInnerNumber <= distanceToOuterNumber);
            } else {
                // Otherwise, if we're close enough to either number (with the space between the
                // two allotted equally), set the isInnerCircle boolean as the closer one.
                // appropriately, but otherwise return -1.
                int minAllowedHypotenuseForInnerNumber =
                        (int) (mCircleRadius * mInnerNumbersRadiusMultiplier) - mSelectionRadius;
                int maxAllowedHypotenuseForOuterNumber =
                        (int) (mCircleRadius * mOuterNumbersRadiusMultiplier) + mSelectionRadius;
                int halfwayHypotenusePoint = (int) (mCircleRadius *
                        ((mOuterNumbersRadiusMultiplier + mInnerNumbersRadiusMultiplier) / 2));

                if (hypotenuse >= minAllowedHypotenuseForInnerNumber &&
                        hypotenuse <= halfwayHypotenusePoint) {
                    isInnerCircle[0] = true;
                } else if (hypotenuse <= maxAllowedHypotenuseForOuterNumber &&
                        hypotenuse >= halfwayHypotenusePoint) {
                    isInnerCircle[0] = false;
                } else {
                    return -1;
                }
            }
        } else {
            // If there's just one circle, we'll need to return -1 if:
            // we're not told to force the coordinates to be legal, and
            // the coordinates' distance to the number is within the allowed distance.
            if (!forceLegal) {
                int distanceToNumber = (int) Math.abs(hypotenuse - mLineLength);
                // The max allowed distance will be defined as the distance from the center of the
                // number to the edge of the circle.
                int maxAllowedDistance = (int) (mCircleRadius * (1 - mNumbersRadiusMultiplier));
                if (distanceToNumber > maxAllowedDistance) {
                    return -1;
                }
            }
        }


        float opposite = Math.abs(pointY - mYCenter);
        double radians = Math.asin(opposite / hypotenuse);
        int degrees = (int) (radians * 180 / Math.PI);

        // Now we have to translate to the correct quadrant.
        boolean rightSide = (pointX > mXCenter);
        boolean topSide = (pointY < mYCenter);
        if (rightSide && topSide) {
            degrees = 90 - degrees;
        } else if (rightSide && !topSide) {
            degrees = 90 + degrees;
        } else if (!rightSide && !topSide) {
            degrees = 270 - degrees;
        } else if (!rightSide && topSide) {
            degrees = 270 + degrees;
        }
        return degrees;
    }

    @Override
    public void onDraw(Canvas canvas) {
        int viewWidth = getWidth();
        if (viewWidth == 0 || !mIsInitialized) {
            return;
        }

        if (!mDrawValuesReady) {
            mXCenter = getWidth() / 2;
            mYCenter = getHeight() / 2;
            mCircleRadius = (int) (Math.min(mXCenter, mYCenter) * mCircleRadiusMultiplier);

            if (!mIs24HourMode) {
                // We'll need to draw the AM/PM circles, so the main circle will need to have
                // a slightly higher center. To keep the entire view centered vertically, we'll
                // have to push it up by half the radius of the AM/PM circles.
                int amPmCircleRadius = (int) (mCircleRadius * mAmPmCircleRadiusMultiplier);
                mYCenter -= amPmCircleRadius / 2;
            }

            mSelectionRadius = (int) (mCircleRadius * mSelectionRadiusMultiplier);

            mDrawValuesReady = true;
        }

        // Calculate the current radius at which to place the selection circle.
        mLineLength = (int) (mCircleRadius * mNumbersRadiusMultiplier * mAnimationRadiusMultiplier);
        int pointX = mXCenter + (int) (mLineLength * Math.sin(mSelectionRadians));
        int pointY = mYCenter - (int) (mLineLength * Math.cos(mSelectionRadians));

        // Draw the selection circle.
        mPaint.setAlpha(mSelectionAlpha);
        canvas.drawCircle(pointX, pointY, mSelectionRadius, mPaint);

        if (mForceDrawDot | mSelectionDegrees % 30 != 0) {
            // We're not on a direct tick (or we've been told to draw the dot anyway).
            mPaint.setAlpha(FULL_ALPHA);
            canvas.drawCircle(pointX, pointY, (mSelectionRadius * 2 / 7), mPaint);
        } else {
            // We're not drawing the dot, so shorten the line to only go as far as the edge of the
            // selection circle.
            int lineLength = mLineLength;
            lineLength -= mSelectionRadius;
            pointX = mXCenter + (int) (lineLength * Math.sin(mSelectionRadians));
            pointY = mYCenter - (int) (lineLength * Math.cos(mSelectionRadians));
        }

        // Draw the line from the center of the circle.
        mPaint.setAlpha(255);
        mPaint.setStrokeWidth(1);
        canvas.drawLine(mXCenter, mYCenter, pointX, pointY, mPaint);
    }

    public ObjectAnimator getDisappearAnimator() {
        if (!mIsInitialized || !mDrawValuesReady) {
            Log.e(TAG, "RadialSelectorView was not ready for animation.");
            return null;
        }

        Keyframe kf0, kf1, kf2;
        float midwayPoint = 0.2f;
        int duration = 500;

        kf0 = Keyframe.ofFloat(0f, 1);
        kf1 = Keyframe.ofFloat(midwayPoint, mTransitionMidRadiusMultiplier);
        kf2 = Keyframe.ofFloat(1f, mTransitionEndRadiusMultiplier);
        PropertyValuesHolder radiusDisappear = PropertyValuesHolder.ofKeyframe(
                "animationRadiusMultiplier", kf0, kf1, kf2);

        kf0 = Keyframe.ofFloat(0f, 1f);
        kf1 = Keyframe.ofFloat(1f, 0f);
        PropertyValuesHolder fadeOut = PropertyValuesHolder.ofKeyframe("alpha", kf0, kf1);

        ObjectAnimator disappearAnimator = ObjectAnimator.ofPropertyValuesHolder(
                this, radiusDisappear, fadeOut).setDuration(duration);
        disappearAnimator.addUpdateListener(mInvalidateUpdateListener);

        return disappearAnimator;
    }

    public ObjectAnimator getReappearAnimator() {
        if (!mIsInitialized || !mDrawValuesReady) {
            Log.e(TAG, "RadialSelectorView was not ready for animation.");
            return null;
        }

        Keyframe kf0, kf1, kf2, kf3;
        float midwayPoint = 0.2f;
        int duration = 500;

        // The time points are half of what they would normally be, because this animation is
        // staggered against the disappear so they happen seamlessly. The reappear starts
        // halfway into the disappear.
        float delayMultiplier = 0.25f;
        float transitionDurationMultiplier = 1f;
        float totalDurationMultiplier = transitionDurationMultiplier + delayMultiplier;
        int totalDuration = (int) (duration * totalDurationMultiplier);
        float delayPoint = (delayMultiplier * duration) / totalDuration;
        midwayPoint = 1 - (midwayPoint * (1 - delayPoint));

        kf0 = Keyframe.ofFloat(0f, mTransitionEndRadiusMultiplier);
        kf1 = Keyframe.ofFloat(delayPoint, mTransitionEndRadiusMultiplier);
        kf2 = Keyframe.ofFloat(midwayPoint, mTransitionMidRadiusMultiplier);
        kf3 = Keyframe.ofFloat(1f, 1);
        PropertyValuesHolder radiusReappear = PropertyValuesHolder.ofKeyframe(
                "animationRadiusMultiplier", kf0, kf1, kf2, kf3);

        kf0 = Keyframe.ofFloat(0f, 0f);
        kf1 = Keyframe.ofFloat(delayPoint, 0f);
        kf2 = Keyframe.ofFloat(1f, 1f);
        PropertyValuesHolder fadeIn = PropertyValuesHolder.ofKeyframe("alpha", kf0, kf1, kf2);

        ObjectAnimator reappearAnimator = ObjectAnimator.ofPropertyValuesHolder(
                this, radiusReappear, fadeIn).setDuration(totalDuration);
        reappearAnimator.addUpdateListener(mInvalidateUpdateListener);
        return reappearAnimator;
    }

    /**
     * We'll need to invalidate during the animation.
     */
    private class InvalidateUpdateListener implements AnimatorUpdateListener {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            RadialSelectorView.this.invalidate();
        }
    }
}
