/*
 * 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 android.widget;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.Keyframe;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.graphics.RectF;
import android.os.Bundle;
import android.text.format.DateUtils;
import android.text.format.Time;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;

import com.android.internal.R;

import java.text.DateFormatSymbols;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Locale;

/**
 * View to show a clock circle picker (with one or two picking circles)
 *
 * @hide
 */
public class RadialTimePickerView extends View implements View.OnTouchListener {
    private static final String TAG = "ClockView";

    private static final boolean DEBUG = false;

    private static final int DEBUG_COLOR = 0x20FF0000;
    private static final int DEBUG_TEXT_COLOR = 0x60FF0000;
    private static final int DEBUG_STROKE_WIDTH = 2;

    private static final int HOURS = 0;
    private static final int MINUTES = 1;
    private static final int HOURS_INNER = 2;
    private static final int AMPM = 3;

    private static final int SELECTOR_CIRCLE = 0;
    private static final int SELECTOR_DOT = 1;
    private static final int SELECTOR_LINE = 2;

    private static final int AM = 0;
    private static final int PM = 1;

    // Opaque alpha level
    private static final int ALPHA_OPAQUE = 255;

    // Transparent alpha level
    private static final int ALPHA_TRANSPARENT = 0;

    // Alpha level of color for selector.
    private static final int ALPHA_SELECTOR = 60; // was 51

    // Alpha level of color for selected circle.
    private static final int ALPHA_AMPM_SELECTED = ALPHA_SELECTOR;

    // Alpha level of color for pressed circle.
    private static final int ALPHA_AMPM_PRESSED = 255; // was 175

    private static final float COSINE_30_DEGREES = ((float) Math.sqrt(3)) * 0.5f;
    private static final float SINE_30_DEGREES = 0.5f;

    private static final int DEGREES_FOR_ONE_HOUR = 30;
    private static final int DEGREES_FOR_ONE_MINUTE = 6;

    private static final int[] HOURS_NUMBERS = {12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
    private static final int[] HOURS_NUMBERS_24 = {0, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23};
    private static final int[] MINUTES_NUMBERS = {0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55};

    private static final int CENTER_RADIUS = 2;

    private static final int[] STATE_SET_SELECTED = new int[] {R.attr.state_selected};

    private static int[] sSnapPrefer30sMap = new int[361];

    private final String[] mHours12Texts = new String[12];
    private final String[] mOuterHours24Texts = new String[12];
    private final String[] mInnerHours24Texts = new String[12];
    private final String[] mMinutesTexts = new String[12];

    private final String[] mAmPmText = new String[2];

    private final Paint[] mPaint = new Paint[2];
    private final int[] mColor = new int[2];
    private final IntHolder[] mAlpha = new IntHolder[2];

    private final Paint mPaintCenter = new Paint();

    private final Paint[][] mPaintSelector = new Paint[2][3];
    private final int[][] mColorSelector = new int[2][3];
    private final IntHolder[][] mAlphaSelector = new IntHolder[2][3];

    private final Paint mPaintAmPmText = new Paint();
    private final Paint[] mPaintAmPmCircle = new Paint[2];

    private final Paint mPaintBackground = new Paint();
    private final Paint mPaintDisabled = new Paint();
    private final Paint mPaintDebug = new Paint();

    private Typeface mTypeface;

    private boolean mIs24HourMode;
    private boolean mShowHours;

    /**
     * When in 24-hour mode, indicates that the current hour is between
     * 1 and 12 (inclusive).
     */
    private boolean mIsOnInnerCircle;

    private int mXCenter;
    private int mYCenter;

    private float[] mCircleRadius = new float[3];

    private int mMinHypotenuseForInnerNumber;
    private int mMaxHypotenuseForOuterNumber;
    private int mHalfwayHypotenusePoint;

    private float[] mTextSize = new float[2];
    private float mInnerTextSize;

    private float[][] mTextGridHeights = new float[2][7];
    private float[][] mTextGridWidths = new float[2][7];

    private float[] mInnerTextGridHeights = new float[7];
    private float[] mInnerTextGridWidths = new float[7];

    private String[] mOuterTextHours;
    private String[] mInnerTextHours;
    private String[] mOuterTextMinutes;

    private float[] mCircleRadiusMultiplier = new float[2];
    private float[] mNumbersRadiusMultiplier = new float[3];

    private float[] mTextSizeMultiplier = new float[3];

    private float[] mAnimationRadiusMultiplier = new float[3];

    private float mTransitionMidRadiusMultiplier;
    private float mTransitionEndRadiusMultiplier;

    private AnimatorSet mTransition;
    private InvalidateUpdateListener mInvalidateUpdateListener = new InvalidateUpdateListener();

    private int[] mLineLength = new int[3];
    private int[] mSelectionRadius = new int[3];
    private float mSelectionRadiusMultiplier;
    private int[] mSelectionDegrees = new int[3];

    private int mAmPmCircleRadius;
    private float mAmPmYCenter;

    private float mAmPmCircleRadiusMultiplier;
    private int mAmPmTextColor;

    private float mLeftIndicatorXCenter;
    private float mRightIndicatorXCenter;

    private int mAmPmUnselectedColor;
    private int mAmPmSelectedColor;

    private int mAmOrPm;
    private int mAmOrPmPressed;

    private int mDisabledAlpha;

    private RectF mRectF = new RectF();
    private boolean mInputEnabled = true;
    private OnValueSelectedListener mListener;

    private final ArrayList<Animator> mHoursToMinutesAnims = new ArrayList<Animator>();
    private final ArrayList<Animator> mMinuteToHoursAnims = new ArrayList<Animator>();

    public interface OnValueSelectedListener {
        void onValueSelected(int pickerIndex, int newValue, boolean autoAdvance);
    }

    static {
        // Prepare mapping to snap touchable degrees to selectable degrees.
        preparePrefer30sMap();
    }

    /**
     * Split up the 360 degrees of the circle among the 60 selectable values. Assigns a larger
     * selectable area to each of the 12 visible values, such that the ratio of space apportioned
     * to a visible value : space apportioned to a non-visible value will be 14 : 4.
     * E.g. the output of 30 degrees should have a higher range of input associated with it than
     * the output of 24 degrees, because 30 degrees corresponds to a visible number on the clock
     * circle (5 on the minutes, 1 or 13 on the hours).
     */
    private static void preparePrefer30sMap() {
        // We'll split up the visible output and the non-visible output such that each visible
        // output will correspond to a range of 14 associated input degrees, and each non-visible
        // output will correspond to a range of 4 associate input degrees, so visible numbers
        // are more than 3 times easier to get than non-visible numbers:
        // {354-359,0-7}:0, {8-11}:6, {12-15}:12, {16-19}:18, {20-23}:24, {24-37}:30, etc.
        //
        // If an output of 30 degrees should correspond to a range of 14 associated degrees, then
        // we'll need any input between 24 - 37 to snap to 30. Working out from there, 20-23 should
        // snap to 24, while 38-41 should snap to 36. This is somewhat counter-intuitive, that you
        // can be touching 36 degrees but have the selection snapped to 30 degrees; however, this
        // inconsistency isn't noticeable at such fine-grained degrees, and it affords us the
        // ability to aggressively prefer the visible values by a factor of more than 3:1, which
        // greatly contributes to the selectability of these values.

        // The first output is 0, and each following output will increment by 6 {0, 6, 12, ...}.
        int snappedOutputDegrees = 0;
        // Count of how many inputs we've designated to the specified output.
        int count = 1;
        // How many input we expect for a specified output. This will be 14 for output divisible
        // by 30, and 4 for the remaining output. We'll special case the outputs of 0 and 360, so
        // the caller can decide which they need.
        int expectedCount = 8;
        // Iterate through the input.
        for (int degrees = 0; degrees < 361; degrees++) {
            // Save the input-output mapping.
            sSnapPrefer30sMap[degrees] = snappedOutputDegrees;
            // If this is the last input for the specified output, calculate the next output and
            // the next expected count.
            if (count == expectedCount) {
                snappedOutputDegrees += 6;
                if (snappedOutputDegrees == 360) {
                    expectedCount = 7;
                } else if (snappedOutputDegrees % 30 == 0) {
                    expectedCount = 14;
                } else {
                    expectedCount = 4;
                }
                count = 1;
            } else {
                count++;
            }
        }
    }

    /**
     * Returns mapping of any input degrees (0 to 360) to one of 60 selectable output degrees,
     * where the degrees corresponding to visible numbers (i.e. those divisible by 30) will be
     * weighted heavier than the degrees corresponding to non-visible numbers.
     * See {@link #preparePrefer30sMap()} documentation for the rationale and generation of the
     * mapping.
     */
    private static int snapPrefer30s(int degrees) {
        if (sSnapPrefer30sMap == null) {
            return -1;
        }
        return sSnapPrefer30sMap[degrees];
    }

    /**
     * Returns mapping of any input degrees (0 to 360) to one of 12 visible output degrees (all
     * multiples of 30), where the input will be "snapped" to the closest visible degrees.
     * @param degrees The input degrees
     * @param forceHigherOrLower The output may be forced to either the higher or lower step, or may
     * be allowed to snap to whichever is closer. Use 1 to force strictly higher, -1 to force
     * strictly lower, and 0 to snap to the closer one.
     * @return output degrees, will be a multiple of 30
     */
    private static int snapOnly30s(int degrees, int forceHigherOrLower) {
        final int stepSize = DEGREES_FOR_ONE_HOUR;
        int floor = (degrees / stepSize) * stepSize;
        final int ceiling = floor + stepSize;
        if (forceHigherOrLower == 1) {
            degrees = ceiling;
        } else if (forceHigherOrLower == -1) {
            if (degrees == floor) {
                floor -= stepSize;
            }
            degrees = floor;
        } else {
            if ((degrees - floor) < (ceiling - degrees)) {
                degrees = floor;
            } else {
                degrees = ceiling;
            }
        }
        return degrees;
    }

    public RadialTimePickerView(Context context, AttributeSet attrs)  {
        this(context, attrs, R.attr.timePickerStyle);
    }

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

        // Pull disabled alpha from theme.
        final TypedValue outValue = new TypedValue();
        context.getTheme().resolveAttribute(android.R.attr.disabledAlpha, outValue, true);
        mDisabledAlpha = (int) (outValue.getFloat() * 255 + 0.5f);

        // process style attributes
        final Resources res = getResources();
        final TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.TimePicker,
                defStyle, 0);

        ColorStateList amPmBackgroundColor = a.getColorStateList(
                R.styleable.TimePicker_amPmBackgroundColor);
        if (amPmBackgroundColor == null) {
            amPmBackgroundColor = res.getColorStateList(
                    R.color.timepicker_default_ampm_unselected_background_color_material);
        }

        // Obtain the backup selected color. If the background color state
        // list doesn't have a state for selected, we'll use this color.
        final int amPmSelectedColor = a.getColor(R.styleable.TimePicker_amPmSelectedBackgroundColor,
                res.getColor(R.color.timepicker_default_ampm_selected_background_color_material));
        amPmBackgroundColor = ColorStateList.addFirstIfMissing(
                amPmBackgroundColor, R.attr.state_selected, amPmSelectedColor);

        mAmPmSelectedColor = amPmBackgroundColor.getColorForState(
                STATE_SET_SELECTED, amPmSelectedColor);
        mAmPmUnselectedColor = amPmBackgroundColor.getDefaultColor();

        mAmPmTextColor = a.getColor(R.styleable.TimePicker_amPmTextColor,
                res.getColor(R.color.timepicker_default_text_color_material));

        mTypeface = Typeface.create("sans-serif", Typeface.NORMAL);

        // Initialize all alpha values to opaque.
        for (int i = 0; i < mAlpha.length; i++) {
            mAlpha[i] = new IntHolder(ALPHA_OPAQUE);
        }
        for (int i = 0; i < mAlphaSelector.length; i++) {
            for (int j = 0; j < mAlphaSelector[i].length; j++) {
                mAlphaSelector[i][j] = new IntHolder(ALPHA_OPAQUE);
            }
        }

        final int numbersTextColor = a.getColor(R.styleable.TimePicker_numbersTextColor,
                res.getColor(R.color.timepicker_default_text_color_material));

        mPaint[HOURS] = new Paint();
        mPaint[HOURS].setAntiAlias(true);
        mPaint[HOURS].setTextAlign(Paint.Align.CENTER);
        mColor[HOURS] = numbersTextColor;

        mPaint[MINUTES] = new Paint();
        mPaint[MINUTES].setAntiAlias(true);
        mPaint[MINUTES].setTextAlign(Paint.Align.CENTER);
        mColor[MINUTES] = numbersTextColor;

        mPaintCenter.setColor(numbersTextColor);
        mPaintCenter.setAntiAlias(true);
        mPaintCenter.setTextAlign(Paint.Align.CENTER);

        mPaintSelector[HOURS][SELECTOR_CIRCLE] = new Paint();
        mPaintSelector[HOURS][SELECTOR_CIRCLE].setAntiAlias(true);
        mColorSelector[HOURS][SELECTOR_CIRCLE] = a.getColor(
                R.styleable.TimePicker_numbersSelectorColor,
                R.color.timepicker_default_selector_color_material);

        mPaintSelector[HOURS][SELECTOR_DOT] = new Paint();
        mPaintSelector[HOURS][SELECTOR_DOT].setAntiAlias(true);
        mColorSelector[HOURS][SELECTOR_DOT] = a.getColor(
                R.styleable.TimePicker_numbersSelectorColor,
                R.color.timepicker_default_selector_color_material);

        mPaintSelector[HOURS][SELECTOR_LINE] = new Paint();
        mPaintSelector[HOURS][SELECTOR_LINE].setAntiAlias(true);
        mPaintSelector[HOURS][SELECTOR_LINE].setStrokeWidth(2);
        mColorSelector[HOURS][SELECTOR_LINE] = a.getColor(
                R.styleable.TimePicker_numbersSelectorColor,
                R.color.timepicker_default_selector_color_material);

        mPaintSelector[MINUTES][SELECTOR_CIRCLE] = new Paint();
        mPaintSelector[MINUTES][SELECTOR_CIRCLE].setAntiAlias(true);
        mColorSelector[MINUTES][SELECTOR_CIRCLE] = a.getColor(
                R.styleable.TimePicker_numbersSelectorColor,
                R.color.timepicker_default_selector_color_material);

        mPaintSelector[MINUTES][SELECTOR_DOT] = new Paint();
        mPaintSelector[MINUTES][SELECTOR_DOT].setAntiAlias(true);
        mColorSelector[MINUTES][SELECTOR_DOT] = a.getColor(
                R.styleable.TimePicker_numbersSelectorColor,
                R.color.timepicker_default_selector_color_material);

        mPaintSelector[MINUTES][SELECTOR_LINE] = new Paint();
        mPaintSelector[MINUTES][SELECTOR_LINE].setAntiAlias(true);
        mPaintSelector[MINUTES][SELECTOR_LINE].setStrokeWidth(2);
        mColorSelector[MINUTES][SELECTOR_LINE] = a.getColor(
                R.styleable.TimePicker_numbersSelectorColor,
                R.color.timepicker_default_selector_color_material);

        mPaintAmPmText.setColor(mAmPmTextColor);
        mPaintAmPmText.setTypeface(mTypeface);
        mPaintAmPmText.setAntiAlias(true);
        mPaintAmPmText.setTextAlign(Paint.Align.CENTER);

        mPaintAmPmCircle[AM] = new Paint();
        mPaintAmPmCircle[AM].setAntiAlias(true);
        mPaintAmPmCircle[PM] = new Paint();
        mPaintAmPmCircle[PM].setAntiAlias(true);

        mPaintBackground.setColor(a.getColor(R.styleable.TimePicker_numbersBackgroundColor,
                res.getColor(R.color.timepicker_default_numbers_background_color_material)));
        mPaintBackground.setAntiAlias(true);

        if (DEBUG) {
            mPaintDebug.setColor(DEBUG_COLOR);
            mPaintDebug.setAntiAlias(true);
            mPaintDebug.setStrokeWidth(DEBUG_STROKE_WIDTH);
            mPaintDebug.setStyle(Paint.Style.STROKE);
            mPaintDebug.setTextAlign(Paint.Align.CENTER);
        }

        mShowHours = true;
        mIs24HourMode = false;
        mAmOrPm = AM;
        mAmOrPmPressed = -1;

        initHoursAndMinutesText();
        initData();

        mTransitionMidRadiusMultiplier =  Float.parseFloat(
                res.getString(R.string.timepicker_transition_mid_radius_multiplier));
        mTransitionEndRadiusMultiplier = Float.parseFloat(
                res.getString(R.string.timepicker_transition_end_radius_multiplier));

        mTextGridHeights[HOURS] = new float[7];
        mTextGridHeights[MINUTES] = new float[7];

        mSelectionRadiusMultiplier = Float.parseFloat(
                res.getString(R.string.timepicker_selection_radius_multiplier));

        a.recycle();

        setOnTouchListener(this);
        setClickable(true);

        // Initial values
        final Calendar calendar = Calendar.getInstance(Locale.getDefault());
        final int currentHour = calendar.get(Calendar.HOUR_OF_DAY);
        final int currentMinute = calendar.get(Calendar.MINUTE);

        setCurrentHour(currentHour);
        setCurrentMinute(currentMinute);

        setHapticFeedbackEnabled(true);
    }

    /**
     * Measure the view to end up as a square, based on the minimum of the height and width.
     */
    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int measuredWidth = MeasureSpec.getSize(widthMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int measuredHeight = MeasureSpec.getSize(heightMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int minDimension = Math.min(measuredWidth, measuredHeight);

        super.onMeasure(MeasureSpec.makeMeasureSpec(minDimension, widthMode),
                MeasureSpec.makeMeasureSpec(minDimension, heightMode));
    }

    public void initialize(int hour, int minute, boolean is24HourMode) {
        mIs24HourMode = is24HourMode;
        setCurrentHour(hour);
        setCurrentMinute(minute);
    }

    public void setCurrentItemShowing(int item, boolean animate) {
        switch (item){
            case HOURS:
                showHours(animate);
                break;
            case MINUTES:
                showMinutes(animate);
                break;
            default:
                Log.e(TAG, "ClockView does not support showing item " + item);
        }
    }

    public int getCurrentItemShowing() {
        return mShowHours ? HOURS : MINUTES;
    }

    public void setOnValueSelectedListener(OnValueSelectedListener listener) {
        mListener = listener;
    }

    /**
     * Sets the current hour in 24-hour time.
     *
     * @param hour the current hour between 0 and 23 (inclusive)
     */
    public void setCurrentHour(int hour) {
        final int degrees = (hour % 12) * DEGREES_FOR_ONE_HOUR;
        mSelectionDegrees[HOURS] = degrees;
        mSelectionDegrees[HOURS_INNER] = degrees;

        // 0 is 12 AM (midnight) and 12 is 12 PM (noon).
        mAmOrPm = (hour == 0 || (hour % 24) < 12) ? AM : PM;

        if (mIs24HourMode) {
            // Inner circle is 1 through 12.
            mIsOnInnerCircle = hour >= 1 && hour <= 12;
        } else {
            mIsOnInnerCircle = false;
        }

        initData();
        updateLayoutData();
        invalidate();
    }

    /**
     * Returns the current hour in 24-hour time.
     *
     * @return the current hour between 0 and 23 (inclusive)
     */
    public int getCurrentHour() {
        int hour = (mSelectionDegrees[mIsOnInnerCircle ?
                HOURS_INNER : HOURS] / DEGREES_FOR_ONE_HOUR) % 12;
        if (mIs24HourMode) {
            // Convert the 12-hour value into 24-hour time based on where the
            // selector is positioned.
            if (mIsOnInnerCircle && hour == 0) {
                // Inner circle is 1 through 12.
                hour = 12;
            } else if (!mIsOnInnerCircle && hour != 0) {
                // Outer circle is 13 through 23 and 0.
                hour += 12;
            }
        } else if (mAmOrPm == PM) {
            hour += 12;
        }
        return hour;
    }

    public void setCurrentMinute(int minute) {
        mSelectionDegrees[MINUTES] = (minute % 60) * DEGREES_FOR_ONE_MINUTE;
        invalidate();
    }

    // Returns minutes in 0-59 range
    public int getCurrentMinute() {
        return (mSelectionDegrees[MINUTES] / DEGREES_FOR_ONE_MINUTE);
    }

    public void setAmOrPm(int val) {
        mAmOrPm = (val % 2);
        invalidate();
    }

    public int getAmOrPm() {
        return mAmOrPm;
    }

    public void swapAmPm() {
        mAmOrPm = (mAmOrPm == AM) ? PM : AM;
        invalidate();
    }

    public void showHours(boolean animate) {
        if (mShowHours) return;
        mShowHours = true;
        if (animate) {
            startMinutesToHoursAnimation();
        }
        initData();
        updateLayoutData();
        invalidate();
    }

    public void showMinutes(boolean animate) {
        if (!mShowHours) return;
        mShowHours = false;
        if (animate) {
            startHoursToMinutesAnimation();
        }
        initData();
        updateLayoutData();
        invalidate();
    }

    private void initHoursAndMinutesText() {
        // Initialize the hours and minutes numbers.
        for (int i = 0; i < 12; i++) {
            mHours12Texts[i] = String.format("%d", HOURS_NUMBERS[i]);
            mOuterHours24Texts[i] = String.format("%02d", HOURS_NUMBERS_24[i]);
            mInnerHours24Texts[i] = String.format("%d", HOURS_NUMBERS[i]);
            mMinutesTexts[i] = String.format("%02d", MINUTES_NUMBERS[i]);
        }

        String[] amPmStrings = TimePickerClockDelegate.getAmPmStrings(mContext);
        mAmPmText[AM] = amPmStrings[0];
        mAmPmText[PM] = amPmStrings[1];
    }

    private void initData() {
        if (mIs24HourMode) {
            mOuterTextHours = mOuterHours24Texts;
            mInnerTextHours = mInnerHours24Texts;
        } else {
            mOuterTextHours = mHours12Texts;
            mInnerTextHours = null;
        }

        mOuterTextMinutes = mMinutesTexts;

        final Resources res = getResources();

        if (mShowHours) {
            if (mIs24HourMode) {
                mCircleRadiusMultiplier[HOURS] = Float.parseFloat(
                        res.getString(R.string.timepicker_circle_radius_multiplier_24HourMode));
                mNumbersRadiusMultiplier[HOURS] = Float.parseFloat(
                        res.getString(R.string.timepicker_numbers_radius_multiplier_outer));
                mTextSizeMultiplier[HOURS] = Float.parseFloat(
                        res.getString(R.string.timepicker_text_size_multiplier_outer));

                mNumbersRadiusMultiplier[HOURS_INNER] = Float.parseFloat(
                        res.getString(R.string.timepicker_numbers_radius_multiplier_inner));
                mTextSizeMultiplier[HOURS_INNER] = Float.parseFloat(
                        res.getString(R.string.timepicker_text_size_multiplier_inner));
            } else {
                mCircleRadiusMultiplier[HOURS] = Float.parseFloat(
                        res.getString(R.string.timepicker_circle_radius_multiplier));
                mNumbersRadiusMultiplier[HOURS] = Float.parseFloat(
                        res.getString(R.string.timepicker_numbers_radius_multiplier_normal));
                mTextSizeMultiplier[HOURS] = Float.parseFloat(
                        res.getString(R.string.timepicker_text_size_multiplier_normal));
            }
        } else {
            mCircleRadiusMultiplier[MINUTES] = Float.parseFloat(
                    res.getString(R.string.timepicker_circle_radius_multiplier));
            mNumbersRadiusMultiplier[MINUTES] = Float.parseFloat(
                    res.getString(R.string.timepicker_numbers_radius_multiplier_normal));
            mTextSizeMultiplier[MINUTES] = Float.parseFloat(
                    res.getString(R.string.timepicker_text_size_multiplier_normal));
        }

        mAnimationRadiusMultiplier[HOURS] = 1;
        mAnimationRadiusMultiplier[HOURS_INNER] = 1;
        mAnimationRadiusMultiplier[MINUTES] = 1;

        mAmPmCircleRadiusMultiplier = Float.parseFloat(
                res.getString(R.string.timepicker_ampm_circle_radius_multiplier));

        mAlpha[HOURS].setValue(mShowHours ? ALPHA_OPAQUE : ALPHA_TRANSPARENT);
        mAlpha[MINUTES].setValue(mShowHours ? ALPHA_TRANSPARENT : ALPHA_OPAQUE);

        mAlphaSelector[HOURS][SELECTOR_CIRCLE].setValue(
                mShowHours ? ALPHA_SELECTOR : ALPHA_TRANSPARENT);
        mAlphaSelector[HOURS][SELECTOR_DOT].setValue(
                mShowHours ? ALPHA_OPAQUE : ALPHA_TRANSPARENT);
        mAlphaSelector[HOURS][SELECTOR_LINE].setValue(
                mShowHours ? ALPHA_SELECTOR : ALPHA_TRANSPARENT);

        mAlphaSelector[MINUTES][SELECTOR_CIRCLE].setValue(
                mShowHours ? ALPHA_TRANSPARENT : ALPHA_SELECTOR);
        mAlphaSelector[MINUTES][SELECTOR_DOT].setValue(
                mShowHours ? ALPHA_TRANSPARENT : ALPHA_OPAQUE);
        mAlphaSelector[MINUTES][SELECTOR_LINE].setValue(
                mShowHours ? ALPHA_TRANSPARENT : ALPHA_SELECTOR);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        updateLayoutData();
    }

    private void updateLayoutData() {
        mXCenter = getWidth() / 2;
        mYCenter = getHeight() / 2;

        final int min = Math.min(mXCenter, mYCenter);

        mCircleRadius[HOURS] = min * mCircleRadiusMultiplier[HOURS];
        mCircleRadius[HOURS_INNER] = min * mCircleRadiusMultiplier[HOURS];
        mCircleRadius[MINUTES] = min * mCircleRadiusMultiplier[MINUTES];

        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[HOURS] * mAmPmCircleRadiusMultiplier);
            mYCenter -= amPmCircleRadius / 2;
        }

        mMinHypotenuseForInnerNumber = (int) (mCircleRadius[HOURS]
                * mNumbersRadiusMultiplier[HOURS_INNER]) - mSelectionRadius[HOURS];
        mMaxHypotenuseForOuterNumber = (int) (mCircleRadius[HOURS]
                * mNumbersRadiusMultiplier[HOURS]) + mSelectionRadius[HOURS];
        mHalfwayHypotenusePoint = (int) (mCircleRadius[HOURS]
                * ((mNumbersRadiusMultiplier[HOURS] + mNumbersRadiusMultiplier[HOURS_INNER]) / 2));

        mTextSize[HOURS] = mCircleRadius[HOURS] * mTextSizeMultiplier[HOURS];
        mTextSize[MINUTES] = mCircleRadius[MINUTES] * mTextSizeMultiplier[MINUTES];

        if (mIs24HourMode) {
            mInnerTextSize = mCircleRadius[HOURS] * mTextSizeMultiplier[HOURS_INNER];
        }

        calculateGridSizesHours();
        calculateGridSizesMinutes();

        mSelectionRadius[HOURS] = (int) (mCircleRadius[HOURS] * mSelectionRadiusMultiplier);
        mSelectionRadius[HOURS_INNER] = mSelectionRadius[HOURS];
        mSelectionRadius[MINUTES] = (int) (mCircleRadius[MINUTES] * mSelectionRadiusMultiplier);

        mAmPmCircleRadius = (int) (mCircleRadius[HOURS] * mAmPmCircleRadiusMultiplier);
        mPaintAmPmText.setTextSize(mAmPmCircleRadius * 3 / 4);

        // Line up the vertical center of the AM/PM circles with the bottom of the main circle.
        mAmPmYCenter = mYCenter + mCircleRadius[HOURS];

        // Line up the horizontal edges of the AM/PM circles with the horizontal edges
        // of the main circle
        mLeftIndicatorXCenter = mXCenter - mCircleRadius[HOURS] + mAmPmCircleRadius;
        mRightIndicatorXCenter = mXCenter + mCircleRadius[HOURS] - mAmPmCircleRadius;
    }

    @Override
    public void onDraw(Canvas canvas) {
        if (!mInputEnabled) {
            canvas.saveLayerAlpha(0, 0, getWidth(), getHeight(), mDisabledAlpha);
        } else {
            canvas.save();
        }

        calculateGridSizesHours();
        calculateGridSizesMinutes();

        drawCircleBackground(canvas);
        drawSelector(canvas);

        drawTextElements(canvas, mTextSize[HOURS], mTypeface, mOuterTextHours,
                mTextGridWidths[HOURS], mTextGridHeights[HOURS], mPaint[HOURS],
                mColor[HOURS], mAlpha[HOURS].getValue());

        if (mIs24HourMode && mInnerTextHours != null) {
            drawTextElements(canvas, mInnerTextSize, mTypeface, mInnerTextHours,
                    mInnerTextGridWidths, mInnerTextGridHeights, mPaint[HOURS],
                    mColor[HOURS], mAlpha[HOURS].getValue());
        }

        drawTextElements(canvas, mTextSize[MINUTES], mTypeface, mOuterTextMinutes,
                mTextGridWidths[MINUTES], mTextGridHeights[MINUTES], mPaint[MINUTES],
                mColor[MINUTES], mAlpha[MINUTES].getValue());

        drawCenter(canvas);
        if (!mIs24HourMode) {
            drawAmPm(canvas);
        }

        if (DEBUG) {
            drawDebug(canvas);
        }

        canvas.restore();
    }

    private void drawCircleBackground(Canvas canvas) {
        canvas.drawCircle(mXCenter, mYCenter, mCircleRadius[HOURS], mPaintBackground);
    }

    private void drawCenter(Canvas canvas) {
        canvas.drawCircle(mXCenter, mYCenter, CENTER_RADIUS, mPaintCenter);
    }

    private void drawSelector(Canvas canvas) {
        drawSelector(canvas, mIsOnInnerCircle ? HOURS_INNER : HOURS);
        drawSelector(canvas, MINUTES);
    }

    private void drawAmPm(Canvas canvas) {
        final boolean isLayoutRtl = isLayoutRtl();

        int amColor = mAmPmUnselectedColor;
        int amAlpha = ALPHA_OPAQUE;
        int pmColor = mAmPmUnselectedColor;
        int pmAlpha = ALPHA_OPAQUE;
        if (mAmOrPm == AM) {
            amColor = mAmPmSelectedColor;
            amAlpha = ALPHA_AMPM_SELECTED;
        } else if (mAmOrPm == PM) {
            pmColor = mAmPmSelectedColor;
            pmAlpha = ALPHA_AMPM_SELECTED;
        }
        if (mAmOrPmPressed == AM) {
            amColor = mAmPmSelectedColor;
            amAlpha = ALPHA_AMPM_PRESSED;
        } else if (mAmOrPmPressed == PM) {
            pmColor = mAmPmSelectedColor;
            pmAlpha = ALPHA_AMPM_PRESSED;
        }

        // Draw the two circles
        mPaintAmPmCircle[AM].setColor(amColor);
        mPaintAmPmCircle[AM].setAlpha(getMultipliedAlpha(amColor, amAlpha));
        canvas.drawCircle(isLayoutRtl ? mRightIndicatorXCenter : mLeftIndicatorXCenter,
                mAmPmYCenter, mAmPmCircleRadius, mPaintAmPmCircle[AM]);

        mPaintAmPmCircle[PM].setColor(pmColor);
        mPaintAmPmCircle[PM].setAlpha(getMultipliedAlpha(pmColor, pmAlpha));
        canvas.drawCircle(isLayoutRtl ? mLeftIndicatorXCenter : mRightIndicatorXCenter,
                mAmPmYCenter, mAmPmCircleRadius, mPaintAmPmCircle[PM]);

        // Draw the AM/PM texts on top
        mPaintAmPmText.setColor(mAmPmTextColor);
        float textYCenter = mAmPmYCenter -
                (int) (mPaintAmPmText.descent() + mPaintAmPmText.ascent()) / 2;

        canvas.drawText(isLayoutRtl ? mAmPmText[PM] : mAmPmText[AM], mLeftIndicatorXCenter,
                textYCenter, mPaintAmPmText);
        canvas.drawText(isLayoutRtl ? mAmPmText[AM] : mAmPmText[PM], mRightIndicatorXCenter,
                textYCenter, mPaintAmPmText);
    }

    private int getMultipliedAlpha(int argb, int alpha) {
        return (int) (Color.alpha(argb) * (alpha / 255.0) + 0.5);
    }

    private void drawSelector(Canvas canvas, int index) {
        // Calculate the current radius at which to place the selection circle.
        mLineLength[index] = (int) (mCircleRadius[index]
                * mNumbersRadiusMultiplier[index] * mAnimationRadiusMultiplier[index]);

        double selectionRadians = Math.toRadians(mSelectionDegrees[index]);

        int pointX = mXCenter + (int) (mLineLength[index] * Math.sin(selectionRadians));
        int pointY = mYCenter - (int) (mLineLength[index] * Math.cos(selectionRadians));

        int color;
        int alpha;
        Paint paint;

        // Draw the selection circle
        color = mColorSelector[index % 2][SELECTOR_CIRCLE];
        alpha = mAlphaSelector[index % 2][SELECTOR_CIRCLE].getValue();
        paint = mPaintSelector[index % 2][SELECTOR_CIRCLE];
        paint.setColor(color);
        paint.setAlpha(getMultipliedAlpha(color, alpha));
        canvas.drawCircle(pointX, pointY, mSelectionRadius[index], paint);

        // Draw the dot if needed
        if (mSelectionDegrees[index] % 30 != 0) {
            // We're not on a direct tick
            color = mColorSelector[index % 2][SELECTOR_DOT];
            alpha = mAlphaSelector[index % 2][SELECTOR_DOT].getValue();
            paint = mPaintSelector[index % 2][SELECTOR_DOT];
            paint.setColor(color);
            paint.setAlpha(getMultipliedAlpha(color, alpha));
            canvas.drawCircle(pointX, pointY, (mSelectionRadius[index] * 2 / 7), paint);
        } 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[index] - mSelectionRadius[index];
            pointX = mXCenter + (int) (lineLength * Math.sin(selectionRadians));
            pointY = mYCenter - (int) (lineLength * Math.cos(selectionRadians));
        }

        // Draw the line
        color = mColorSelector[index % 2][SELECTOR_LINE];
        alpha = mAlphaSelector[index % 2][SELECTOR_LINE].getValue();
        paint = mPaintSelector[index % 2][SELECTOR_LINE];
        paint.setColor(color);
        paint.setAlpha(getMultipliedAlpha(color, alpha));
        canvas.drawLine(mXCenter, mYCenter, pointX, pointY, paint);
    }

    private void drawDebug(Canvas canvas) {
        // Draw outer numbers circle
        final float outerRadius = mCircleRadius[HOURS] * mNumbersRadiusMultiplier[HOURS];
        canvas.drawCircle(mXCenter, mYCenter, outerRadius, mPaintDebug);

        // Draw inner numbers circle
        final float innerRadius = mCircleRadius[HOURS] * mNumbersRadiusMultiplier[HOURS_INNER];
        canvas.drawCircle(mXCenter, mYCenter, innerRadius, mPaintDebug);

        // Draw outer background circle
        canvas.drawCircle(mXCenter, mYCenter, mCircleRadius[HOURS], mPaintDebug);

        // Draw outer rectangle for circles
        float left = mXCenter - outerRadius;
        float top = mYCenter - outerRadius;
        float right = mXCenter + outerRadius;
        float bottom = mYCenter + outerRadius;
        mRectF = new RectF(left, top, right, bottom);
        canvas.drawRect(mRectF, mPaintDebug);

        // Draw outer rectangle for background
        left = mXCenter - mCircleRadius[HOURS];
        top = mYCenter - mCircleRadius[HOURS];
        right = mXCenter + mCircleRadius[HOURS];
        bottom = mYCenter + mCircleRadius[HOURS];
        mRectF.set(left, top, right, bottom);
        canvas.drawRect(mRectF, mPaintDebug);

        // Draw outer view rectangle
        mRectF.set(0, 0, getWidth(), getHeight());
        canvas.drawRect(mRectF, mPaintDebug);

        // Draw selected time
        final String selected = String.format("%02d:%02d", getCurrentHour(), getCurrentMinute());

        ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        TextView tv = new TextView(getContext());
        tv.setLayoutParams(lp);
        tv.setText(selected);
        tv.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
        Paint paint = tv.getPaint();
        paint.setColor(DEBUG_TEXT_COLOR);

        final int width = tv.getMeasuredWidth();

        float height = paint.descent() - paint.ascent();
        float x = mXCenter - width / 2;
        float y = mYCenter + 1.5f * height;

        canvas.drawText(selected.toString(), x, y, paint);
    }

    private void calculateGridSizesHours() {
        // Calculate the text positions
        float numbersRadius = mCircleRadius[HOURS]
                * mNumbersRadiusMultiplier[HOURS] * mAnimationRadiusMultiplier[HOURS];

        // Calculate the positions for the 12 numbers in the main circle.
        calculateGridSizes(mPaint[HOURS], numbersRadius, mXCenter, mYCenter,
                mTextSize[HOURS], mTextGridHeights[HOURS], mTextGridWidths[HOURS]);

        // If we have an inner circle, calculate those positions too.
        if (mIs24HourMode) {
            float innerNumbersRadius = mCircleRadius[HOURS_INNER]
                    * mNumbersRadiusMultiplier[HOURS_INNER]
                    * mAnimationRadiusMultiplier[HOURS_INNER];

            calculateGridSizes(mPaint[HOURS], innerNumbersRadius, mXCenter, mYCenter,
                    mInnerTextSize, mInnerTextGridHeights, mInnerTextGridWidths);
        }
    }

    private void calculateGridSizesMinutes() {
        // Calculate the text positions
        float numbersRadius = mCircleRadius[MINUTES]
                * mNumbersRadiusMultiplier[MINUTES] * mAnimationRadiusMultiplier[MINUTES];

        // Calculate the positions for the 12 numbers in the main circle.
        calculateGridSizes(mPaint[MINUTES], numbersRadius, mXCenter, mYCenter,
                mTextSize[MINUTES], mTextGridHeights[MINUTES], mTextGridWidths[MINUTES]);
    }


    /**
     * Using the trigonometric Unit Circle, calculate the positions that the text will need to be
     * drawn at based on the specified circle radius. Place the values in the textGridHeights and
     * textGridWidths parameters.
     */
    private static void calculateGridSizes(Paint paint, float numbersRadius, float xCenter,
            float yCenter, float textSize, float[] textGridHeights, float[] textGridWidths) {
        /*
         * The numbers need to be drawn in a 7x7 grid, representing the points on the Unit Circle.
         */
        final float offset1 = numbersRadius;
        // cos(30) = a / r => r * cos(30)
        final float offset2 = numbersRadius * COSINE_30_DEGREES;
        // sin(30) = o / r => r * sin(30)
        final float offset3 = numbersRadius * SINE_30_DEGREES;

        paint.setTextSize(textSize);
        // We'll need yTextBase to be slightly lower to account for the text's baseline.
        yCenter -= (paint.descent() + paint.ascent()) / 2;

        textGridHeights[0] = yCenter - offset1;
        textGridWidths[0] = xCenter - offset1;
        textGridHeights[1] = yCenter - offset2;
        textGridWidths[1] = xCenter - offset2;
        textGridHeights[2] = yCenter - offset3;
        textGridWidths[2] = xCenter - offset3;
        textGridHeights[3] = yCenter;
        textGridWidths[3] = xCenter;
        textGridHeights[4] = yCenter + offset3;
        textGridWidths[4] = xCenter + offset3;
        textGridHeights[5] = yCenter + offset2;
        textGridWidths[5] = xCenter + offset2;
        textGridHeights[6] = yCenter + offset1;
        textGridWidths[6] = xCenter + offset1;
    }

    /**
     * Draw the 12 text values at the positions specified by the textGrid parameters.
     */
    private void drawTextElements(Canvas canvas, float textSize, Typeface typeface, String[] texts,
            float[] textGridWidths, float[] textGridHeights, Paint paint, int color, int alpha) {
        paint.setTextSize(textSize);
        paint.setTypeface(typeface);
        paint.setColor(color);
        paint.setAlpha(getMultipliedAlpha(color, alpha));
        canvas.drawText(texts[0], textGridWidths[3], textGridHeights[0], paint);
        canvas.drawText(texts[1], textGridWidths[4], textGridHeights[1], paint);
        canvas.drawText(texts[2], textGridWidths[5], textGridHeights[2], paint);
        canvas.drawText(texts[3], textGridWidths[6], textGridHeights[3], paint);
        canvas.drawText(texts[4], textGridWidths[5], textGridHeights[4], paint);
        canvas.drawText(texts[5], textGridWidths[4], textGridHeights[5], paint);
        canvas.drawText(texts[6], textGridWidths[3], textGridHeights[6], paint);
        canvas.drawText(texts[7], textGridWidths[2], textGridHeights[5], paint);
        canvas.drawText(texts[8], textGridWidths[1], textGridHeights[4], paint);
        canvas.drawText(texts[9], textGridWidths[0], textGridHeights[3], paint);
        canvas.drawText(texts[10], textGridWidths[1], textGridHeights[2], paint);
        canvas.drawText(texts[11], textGridWidths[2], textGridHeights[1], paint);
    }

    // Used for animating the hours by changing their radius
    private void setAnimationRadiusMultiplierHours(float animationRadiusMultiplier) {
        mAnimationRadiusMultiplier[HOURS] = animationRadiusMultiplier;
        mAnimationRadiusMultiplier[HOURS_INNER] = animationRadiusMultiplier;
    }

    // Used for animating the minutes by changing their radius
    private void setAnimationRadiusMultiplierMinutes(float animationRadiusMultiplier) {
        mAnimationRadiusMultiplier[MINUTES] = animationRadiusMultiplier;
    }

    private static ObjectAnimator getRadiusDisappearAnimator(Object target,
            String radiusPropertyName, InvalidateUpdateListener updateListener,
            float midRadiusMultiplier, float endRadiusMultiplier) {
        Keyframe kf0, kf1, kf2;
        float midwayPoint = 0.2f;
        int duration = 500;

        kf0 = Keyframe.ofFloat(0f, 1);
        kf1 = Keyframe.ofFloat(midwayPoint, midRadiusMultiplier);
        kf2 = Keyframe.ofFloat(1f, endRadiusMultiplier);
        PropertyValuesHolder radiusDisappear = PropertyValuesHolder.ofKeyframe(
                radiusPropertyName, kf0, kf1, kf2);

        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(
                target, radiusDisappear).setDuration(duration);
        animator.addUpdateListener(updateListener);
        return animator;
    }

    private static ObjectAnimator getRadiusReappearAnimator(Object target,
            String radiusPropertyName, InvalidateUpdateListener updateListener,
            float midRadiusMultiplier, float endRadiusMultiplier) {
        Keyframe kf0, kf1, kf2, kf3;
        float midwayPoint = 0.2f;
        int duration = 500;

        // Set up animator for reappearing.
        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, endRadiusMultiplier);
        kf1 = Keyframe.ofFloat(delayPoint, endRadiusMultiplier);
        kf2 = Keyframe.ofFloat(midwayPoint, midRadiusMultiplier);
        kf3 = Keyframe.ofFloat(1f, 1);
        PropertyValuesHolder radiusReappear = PropertyValuesHolder.ofKeyframe(
                radiusPropertyName, kf0, kf1, kf2, kf3);

        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(
                target, radiusReappear).setDuration(totalDuration);
        animator.addUpdateListener(updateListener);
        return animator;
    }

    private static ObjectAnimator getFadeOutAnimator(IntHolder target, int startAlpha, int endAlpha,
                InvalidateUpdateListener updateListener) {
        int duration = 500;
        ObjectAnimator animator = ObjectAnimator.ofInt(target, "value", startAlpha, endAlpha);
        animator.setDuration(duration);
        animator.addUpdateListener(updateListener);

        return animator;
    }

    private static ObjectAnimator getFadeInAnimator(IntHolder target, int startAlpha, int endAlpha,
                InvalidateUpdateListener updateListener) {
        Keyframe kf0, kf1, kf2;
        int duration = 500;

        // Set up animator for reappearing.
        float delayMultiplier = 0.25f;
        float transitionDurationMultiplier = 1f;
        float totalDurationMultiplier = transitionDurationMultiplier + delayMultiplier;
        int totalDuration = (int) (duration * totalDurationMultiplier);
        float delayPoint = (delayMultiplier * duration) / totalDuration;

        kf0 = Keyframe.ofInt(0f, startAlpha);
        kf1 = Keyframe.ofInt(delayPoint, startAlpha);
        kf2 = Keyframe.ofInt(1f, endAlpha);
        PropertyValuesHolder fadeIn = PropertyValuesHolder.ofKeyframe("value", kf0, kf1, kf2);

        ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(
                target, fadeIn).setDuration(totalDuration);
        animator.addUpdateListener(updateListener);
        return animator;
    }

    private class InvalidateUpdateListener implements ValueAnimator.AnimatorUpdateListener {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            RadialTimePickerView.this.invalidate();
        }
    }

    private void startHoursToMinutesAnimation() {
        if (mHoursToMinutesAnims.size() == 0) {
            mHoursToMinutesAnims.add(getRadiusDisappearAnimator(this,
                    "animationRadiusMultiplierHours", mInvalidateUpdateListener,
                    mTransitionMidRadiusMultiplier, mTransitionEndRadiusMultiplier));
            mHoursToMinutesAnims.add(getFadeOutAnimator(mAlpha[HOURS],
                    ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
            mHoursToMinutesAnims.add(getFadeOutAnimator(mAlphaSelector[HOURS][SELECTOR_CIRCLE],
                    ALPHA_SELECTOR, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
            mHoursToMinutesAnims.add(getFadeOutAnimator(mAlphaSelector[HOURS][SELECTOR_DOT],
                    ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
            mHoursToMinutesAnims.add(getFadeOutAnimator(mAlphaSelector[HOURS][SELECTOR_LINE],
                    ALPHA_SELECTOR, ALPHA_TRANSPARENT, mInvalidateUpdateListener));

            mHoursToMinutesAnims.add(getRadiusReappearAnimator(this,
                    "animationRadiusMultiplierMinutes", mInvalidateUpdateListener,
                    mTransitionMidRadiusMultiplier, mTransitionEndRadiusMultiplier));
            mHoursToMinutesAnims.add(getFadeInAnimator(mAlpha[MINUTES],
                    ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener));
            mHoursToMinutesAnims.add(getFadeInAnimator(mAlphaSelector[MINUTES][SELECTOR_CIRCLE],
                    ALPHA_TRANSPARENT, ALPHA_SELECTOR, mInvalidateUpdateListener));
            mHoursToMinutesAnims.add(getFadeInAnimator(mAlphaSelector[MINUTES][SELECTOR_DOT],
                    ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener));
            mHoursToMinutesAnims.add(getFadeInAnimator(mAlphaSelector[MINUTES][SELECTOR_LINE],
                    ALPHA_TRANSPARENT, ALPHA_SELECTOR, mInvalidateUpdateListener));
        }

        if (mTransition != null && mTransition.isRunning()) {
            mTransition.end();
        }
        mTransition = new AnimatorSet();
        mTransition.playTogether(mHoursToMinutesAnims);
        mTransition.start();
    }

    private void startMinutesToHoursAnimation() {
        if (mMinuteToHoursAnims.size() == 0) {
            mMinuteToHoursAnims.add(getRadiusDisappearAnimator(this,
                    "animationRadiusMultiplierMinutes", mInvalidateUpdateListener,
                    mTransitionMidRadiusMultiplier, mTransitionEndRadiusMultiplier));
            mMinuteToHoursAnims.add(getFadeOutAnimator(mAlpha[MINUTES],
                    ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
            mMinuteToHoursAnims.add(getFadeOutAnimator(mAlphaSelector[MINUTES][SELECTOR_CIRCLE],
                    ALPHA_SELECTOR, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
            mMinuteToHoursAnims.add(getFadeOutAnimator(mAlphaSelector[MINUTES][SELECTOR_DOT],
                    ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
            mMinuteToHoursAnims.add(getFadeOutAnimator(mAlphaSelector[MINUTES][SELECTOR_LINE],
                    ALPHA_SELECTOR, ALPHA_TRANSPARENT, mInvalidateUpdateListener));

            mMinuteToHoursAnims.add(getRadiusReappearAnimator(this,
                    "animationRadiusMultiplierHours", mInvalidateUpdateListener,
                    mTransitionMidRadiusMultiplier, mTransitionEndRadiusMultiplier));
            mMinuteToHoursAnims.add(getFadeInAnimator(mAlpha[HOURS],
                    ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener));
            mMinuteToHoursAnims.add(getFadeInAnimator(mAlphaSelector[HOURS][SELECTOR_CIRCLE],
                    ALPHA_TRANSPARENT, ALPHA_SELECTOR, mInvalidateUpdateListener));
            mMinuteToHoursAnims.add(getFadeInAnimator(mAlphaSelector[HOURS][SELECTOR_DOT],
                    ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener));
            mMinuteToHoursAnims.add(getFadeInAnimator(mAlphaSelector[HOURS][SELECTOR_LINE],
                    ALPHA_TRANSPARENT, ALPHA_SELECTOR, mInvalidateUpdateListener));
        }

        if (mTransition != null && mTransition.isRunning()) {
            mTransition.end();
        }
        mTransition = new AnimatorSet();
        mTransition.playTogether(mMinuteToHoursAnims);
        mTransition.start();
    }

    private int getDegreesFromXY(float x, float y) {
        final double hypotenuse = Math.sqrt(
                (y - mYCenter) * (y - mYCenter) + (x - mXCenter) * (x - mXCenter));

        // Basic check if we're outside the range of the disk
        if (hypotenuse > mCircleRadius[HOURS]) {
            return -1;
        }
        // Check
        if (mIs24HourMode && mShowHours) {
            if (hypotenuse >= mMinHypotenuseForInnerNumber
                    && hypotenuse <= mHalfwayHypotenusePoint) {
                mIsOnInnerCircle = true;
            } else if (hypotenuse <= mMaxHypotenuseForOuterNumber
                    && hypotenuse >= mHalfwayHypotenusePoint) {
                mIsOnInnerCircle = false;
            } else {
                return -1;
            }
        } else {
            final int index =  (mShowHours) ? HOURS : MINUTES;
            final float length = (mCircleRadius[index] * mNumbersRadiusMultiplier[index]);
            final int distanceToNumber = (int) Math.abs(hypotenuse - length);
            final int maxAllowedDistance =
                    (int) (mCircleRadius[index] * (1 - mNumbersRadiusMultiplier[index]));
            if (distanceToNumber > maxAllowedDistance) {
                return -1;
            }
        }

        final float opposite = Math.abs(y - mYCenter);
        double degrees = Math.toDegrees(Math.asin(opposite / hypotenuse));

        // Now we have to translate to the correct quadrant.
        boolean rightSide = (x > mXCenter);
        boolean topSide = (y < 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 (int) degrees;
    }

    private int getIsTouchingAmOrPm(float x, float y) {
        final boolean isLayoutRtl = isLayoutRtl();
        int squaredYDistance = (int) ((y - mAmPmYCenter) * (y - mAmPmYCenter));

        int distanceToAmCenter = (int) Math.sqrt(
                (x - mLeftIndicatorXCenter) * (x - mLeftIndicatorXCenter) + squaredYDistance);
        if (distanceToAmCenter <= mAmPmCircleRadius) {
            return (isLayoutRtl ? PM : AM);
        }

        int distanceToPmCenter = (int) Math.sqrt(
                (x - mRightIndicatorXCenter) * (x - mRightIndicatorXCenter) + squaredYDistance);
        if (distanceToPmCenter <= mAmPmCircleRadius) {
            return (isLayoutRtl ? AM : PM);
        }

        // Neither was close enough.
        return -1;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if(!mInputEnabled) {
            return true;
        }

        final float eventX = event.getX();
        final float eventY = event.getY();

        int degrees;
        int snapDegrees;
        boolean result = false;

        switch(event.getAction()) {
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_MOVE:
                mAmOrPmPressed = getIsTouchingAmOrPm(eventX, eventY);
                if (mAmOrPmPressed != -1) {
                    result = true;
                } else {
                    degrees = getDegreesFromXY(eventX, eventY);
                    if (degrees != -1) {
                        snapDegrees = (mShowHours ?
                                snapOnly30s(degrees, 0) : snapPrefer30s(degrees)) % 360;
                        if (mShowHours) {
                            mSelectionDegrees[HOURS] = snapDegrees;
                            mSelectionDegrees[HOURS_INNER] = snapDegrees;
                        } else {
                            mSelectionDegrees[MINUTES] = snapDegrees;
                        }
                        performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK);
                        if (mListener != null) {
                            if (mShowHours) {
                                mListener.onValueSelected(HOURS, getCurrentHour(), false);
                            } else  {
                                mListener.onValueSelected(MINUTES, getCurrentMinute(), false);
                            }
                        }
                        result = true;
                    }
                }
                invalidate();
                return result;

            case MotionEvent.ACTION_UP:
                mAmOrPmPressed = getIsTouchingAmOrPm(eventX, eventY);
                if (mAmOrPmPressed != -1) {
                    if (mAmOrPm != mAmOrPmPressed) {
                        swapAmPm();
                    }
                    mAmOrPmPressed = -1;
                    if (mListener != null) {
                        mListener.onValueSelected(AMPM, getCurrentHour(), true);
                    }
                    result = true;
                } else {
                    degrees = getDegreesFromXY(eventX, eventY);
                    if (degrees != -1) {
                        snapDegrees = (mShowHours ?
                                snapOnly30s(degrees, 0) : snapPrefer30s(degrees)) % 360;
                        if (mShowHours) {
                            mSelectionDegrees[HOURS] = snapDegrees;
                            mSelectionDegrees[HOURS_INNER] = snapDegrees;
                        } else {
                            mSelectionDegrees[MINUTES] = snapDegrees;
                        }
                        if (mListener != null) {
                            if (mShowHours) {
                                mListener.onValueSelected(HOURS, getCurrentHour(), true);
                            } else  {
                                mListener.onValueSelected(MINUTES, getCurrentMinute(), true);
                            }
                        }
                        result = true;
                    }
                }
                if (result) {
                    invalidate();
                }
                return result;

            default:
                break;
        }
        return false;
    }

    /**
     * Necessary for accessibility, to ensure we support "scrolling" forward and backward
     * in the circle.
     */
    @Override
    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
        super.onInitializeAccessibilityNodeInfo(info);
        info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD);
        info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD);
    }

    /**
     * Announce the currently-selected time when launched.
     */
    @Override
    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
        if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
            // Clear the event's current text so that only the current time will be spoken.
            event.getText().clear();
            Time time = new Time();
            time.hour = getCurrentHour();
            time.minute = getCurrentMinute();
            long millis = time.normalize(true);
            int flags = DateUtils.FORMAT_SHOW_TIME;
            if (mIs24HourMode) {
                flags |= DateUtils.FORMAT_24HOUR;
            }
            String timeString = DateUtils.formatDateTime(getContext(), millis, flags);
            event.getText().add(timeString);
            return true;
        }
        return super.dispatchPopulateAccessibilityEvent(event);
    }

    /**
     * When scroll forward/backward events are received, jump the time to the higher/lower
     * discrete, visible value on the circle.
     */
    @SuppressLint("NewApi")
    @Override
    public boolean performAccessibilityAction(int action, Bundle arguments) {
        if (super.performAccessibilityAction(action, arguments)) {
            return true;
        }

        int changeMultiplier = 0;
        if (action == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD) {
            changeMultiplier = 1;
        } else if (action == AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD) {
            changeMultiplier = -1;
        }
        if (changeMultiplier != 0) {
            int value = 0;
            int stepSize = 0;
            if (mShowHours) {
                stepSize = DEGREES_FOR_ONE_HOUR;
                value = getCurrentHour() % 12;
            } else {
                stepSize = DEGREES_FOR_ONE_MINUTE;
                value = getCurrentMinute();
            }

            int degrees = value * stepSize;
            degrees = snapOnly30s(degrees, changeMultiplier);
            value = degrees / stepSize;
            int maxValue = 0;
            int minValue = 0;
            if (mShowHours) {
                if (mIs24HourMode) {
                    maxValue = 23;
                } else {
                    maxValue = 12;
                    minValue = 1;
                }
            } else {
                maxValue = 55;
            }
            if (value > maxValue) {
                // If we scrolled forward past the highest number, wrap around to the lowest.
                value = minValue;
            } else if (value < minValue) {
                // If we scrolled backward past the lowest number, wrap around to the highest.
                value = maxValue;
            }
            if (mShowHours) {
                setCurrentHour(value);
                if (mListener != null) {
                    mListener.onValueSelected(HOURS, value, false);
                }
            } else {
                setCurrentMinute(value);
                if (mListener != null) {
                    mListener.onValueSelected(MINUTES, value, false);
                }
            }
            return true;
        }

        return false;
    }

    public void setInputEnabled(boolean inputEnabled) {
        mInputEnabled = inputEnabled;
        invalidate();
    }

    private static class IntHolder {
        private int mValue;

        public IntHolder(int value) {
            mValue = value;
        }

        public void setValue(int value) {
            mValue = value;
        }

        public int getValue() {
            return mValue;
        }
    }
}
