/*
 * 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.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.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 = 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 = 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 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 Paint mPaintCenter = new Paint();
    private final Paint[][] mPaintSelector = new Paint[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;
    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 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);

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

        final Resources res = getResources();

        mAmPmUnselectedColor = a.getColor(R.styleable.TimePicker_amPmUnselectedBackgroundColor,
                res.getColor(
                        R.color.timepicker_default_ampm_unselected_background_color_holo_light));

        mAmPmSelectedColor = a.getColor(R.styleable.TimePicker_amPmSelectedBackgroundColor,
                res.getColor(R.color.timepicker_default_ampm_selected_background_color_holo_light));

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

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

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

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

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

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

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

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

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

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

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

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

        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, Color.WHITE));
        mPaintBackground.setAntiAlias(true);

        final int disabledColor = a.getColor(R.styleable.TimePicker_disabledColor,
                res.getColor(R.color.timepicker_default_disabled_color_holo_light));
        mPaintDisabled.setColor(disabledColor);
        mPaintDisabled.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));

        setOnTouchListener(this);

        // 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;
    }

    public void setCurrentHour(int hour) {
        final int degrees = (hour % 12) * DEGREES_FOR_ONE_HOUR;
        mSelectionDegrees[HOURS] = degrees;
        mSelectionDegrees[HOURS_INNER] = degrees;
        mAmOrPm = ((hour % 24) < 12) ? AM : PM;
        if (mIs24HourMode) {
            mIsOnInnerCircle = (mAmOrPm == AM);
        } else {
            mIsOnInnerCircle = false;
        }
        initData();
        updateLayoutData();
        invalidate();
    }

    // Return hours in 0-23 range
    public int getCurrentHour() {
        int hours =
                mSelectionDegrees[mIsOnInnerCircle ? HOURS_INNER : HOURS] / DEGREES_FOR_ONE_HOUR;
        if (mIs24HourMode) {
            if (mIsOnInnerCircle) {
                hours = hours % 12;
            } else {
                if (hours != 0) {
                    hours += 12;
                }
            }
        } else {
            hours = hours % 12;
            if (hours == 0) {
                if (mAmOrPm == PM) {
                    hours = 12;
                }
            } else {
                if (mAmOrPm == PM) {
                    hours += 12;
                }
            }
        }
        return hours;
    }

    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[] amPmTexts = new DateFormatSymbols().getAmPmStrings();
        mAmPmText[AM] = amPmTexts[0];
        mAmPmText[PM] = amPmTexts[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));

        mPaint[HOURS].setAlpha(mShowHours ? ALPHA_OPAQUE : ALPHA_TRANSPARENT);
        mPaint[MINUTES].setAlpha(mShowHours ? ALPHA_TRANSPARENT : ALPHA_OPAQUE);

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

        mPaintSelector[MINUTES][SELECTOR_CIRCLE].setAlpha(
                mShowHours ? ALPHA_TRANSPARENT : ALPHA_SELECTOR);
        mPaintSelector[MINUTES][SELECTOR_DOT].setAlpha(
                mShowHours ? ALPHA_TRANSPARENT : ALPHA_OPAQUE);
        mPaintSelector[MINUTES][SELECTOR_LINE].setAlpha(
                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) {
        canvas.save();

        calculateGridSizesHours();
        calculateGridSizesMinutes();

        drawCircleBackground(canvas);

        drawTextElements(canvas, mTextSize[HOURS], mTypeface, mOuterTextHours,
                mTextGridWidths[HOURS], mTextGridHeights[HOURS], mPaint[HOURS]);

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

        drawTextElements(canvas, mTextSize[MINUTES], mTypeface, mOuterTextMinutes,
                mTextGridWidths[MINUTES], mTextGridHeights[MINUTES], mPaint[MINUTES]);

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

        if(!mInputEnabled) {
            // Draw outer view rectangle
            mRectF.set(0, 0, getWidth(), getHeight());
            canvas.drawRect(mRectF, mPaintDisabled);
        }

        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(amAlpha);
        canvas.drawCircle(isLayoutRtl ? mRightIndicatorXCenter : mLeftIndicatorXCenter,
                mAmPmYCenter, mAmPmCircleRadius, mPaintAmPmCircle[AM]);

        mPaintAmPmCircle[PM].setColor(pmColor);
        mPaintAmPmCircle[PM].setAlpha(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 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));

        // Draw the selection circle
        canvas.drawCircle(pointX, pointY, mSelectionRadius[index],
                mPaintSelector[index % 2][SELECTOR_CIRCLE]);

        // Draw the dot if needed
        if (mSelectionDegrees[index] % 30 != 0) {
            // We're not on a direct tick
            canvas.drawCircle(pointX, pointY, (mSelectionRadius[index] * 2 / 7),
                    mPaintSelector[index % 2][SELECTOR_DOT]);
        } 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
        canvas.drawLine(mXCenter, mYCenter, pointX, pointY,
                mPaintSelector[index % 2][SELECTOR_LINE]);
    }

    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) {
        paint.setTextSize(textSize);
        paint.setTypeface(typeface);
        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(Object target, int startAlpha, int endAlpha,
                InvalidateUpdateListener updateListener) {
        int duration = 500;
        ObjectAnimator animator = ObjectAnimator.ofInt(target, "alpha", startAlpha, endAlpha);
        animator.setDuration(duration);
        animator.addUpdateListener(updateListener);

        return animator;
    }

    private static ObjectAnimator getFadeInAnimator(Object 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("alpha", 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(mPaint[HOURS],
                    ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
            mHoursToMinutesAnims.add(getFadeOutAnimator(mPaintSelector[HOURS][SELECTOR_CIRCLE],
                    ALPHA_SELECTOR, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
            mHoursToMinutesAnims.add(getFadeOutAnimator(mPaintSelector[HOURS][SELECTOR_DOT],
                    ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
            mHoursToMinutesAnims.add(getFadeOutAnimator(mPaintSelector[HOURS][SELECTOR_LINE],
                    ALPHA_SELECTOR, ALPHA_TRANSPARENT, mInvalidateUpdateListener));

            mHoursToMinutesAnims.add(getRadiusReappearAnimator(this,
                    "animationRadiusMultiplierMinutes", mInvalidateUpdateListener,
                    mTransitionMidRadiusMultiplier, mTransitionEndRadiusMultiplier));
            mHoursToMinutesAnims.add(getFadeInAnimator(mPaint[MINUTES],
                    ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener));
            mHoursToMinutesAnims.add(getFadeInAnimator(mPaintSelector[MINUTES][SELECTOR_CIRCLE],
                    ALPHA_TRANSPARENT, ALPHA_SELECTOR, mInvalidateUpdateListener));
            mHoursToMinutesAnims.add(getFadeInAnimator(mPaintSelector[MINUTES][SELECTOR_DOT],
                    ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener));
            mHoursToMinutesAnims.add(getFadeInAnimator(mPaintSelector[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(mPaint[MINUTES],
                    ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
            mMinuteToHoursAnims.add(getFadeOutAnimator(mPaintSelector[MINUTES][SELECTOR_CIRCLE],
                    ALPHA_SELECTOR, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
            mMinuteToHoursAnims.add(getFadeOutAnimator(mPaintSelector[MINUTES][SELECTOR_DOT],
                    ALPHA_OPAQUE, ALPHA_TRANSPARENT, mInvalidateUpdateListener));
            mMinuteToHoursAnims.add(getFadeOutAnimator(mPaintSelector[MINUTES][SELECTOR_LINE],
                    ALPHA_SELECTOR, ALPHA_TRANSPARENT, mInvalidateUpdateListener));

            mMinuteToHoursAnims.add(getRadiusReappearAnimator(this,
                    "animationRadiusMultiplierHours", mInvalidateUpdateListener,
                    mTransitionMidRadiusMultiplier, mTransitionEndRadiusMultiplier));
            mMinuteToHoursAnims.add(getFadeInAnimator(mPaint[HOURS],
                    ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener));
            mMinuteToHoursAnims.add(getFadeInAnimator(mPaintSelector[HOURS][SELECTOR_CIRCLE],
                    ALPHA_TRANSPARENT, ALPHA_SELECTOR, mInvalidateUpdateListener));
            mMinuteToHoursAnims.add(getFadeInAnimator(mPaintSelector[HOURS][SELECTOR_DOT],
                    ALPHA_TRANSPARENT, ALPHA_OPAQUE, mInvalidateUpdateListener));
            mMinuteToHoursAnims.add(getFadeInAnimator(mPaintSelector[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();
    }
}
