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

package com.android.music;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;


public class VerticalTextSpinner extends View {

    private static final int SELECTOR_ARROW_HEIGHT = 15;

    private static int TEXT_SPACING;
    private static int TEXT_MARGIN_RIGHT;
    private static int TEXT_SIZE;
    private static int TEXT1_Y;
    private static int TEXT2_Y;
    private static int TEXT3_Y;
    private static int TEXT4_Y;
    private static int TEXT5_Y;
    private static int SCROLL_DISTANCE;

    private static final int SCROLL_MODE_NONE = 0;
    private static final int SCROLL_MODE_UP = 1;
    private static final int SCROLL_MODE_DOWN = 2;

    private static final long DEFAULT_SCROLL_INTERVAL_MS = 400;
    private static final int MIN_ANIMATIONS = 4;

    private final Drawable mBackgroundFocused;
    private final Drawable mSelectorFocused;
    private final Drawable mSelectorNormal;
    private final int mSelectorDefaultY;
    private final int mSelectorMinY;
    private final int mSelectorMaxY;
    private final int mSelectorHeight;
    private final TextPaint mTextPaintDark;
    private final TextPaint mTextPaintLight;

    private int mSelectorY;
    private Drawable mSelector;
    private int mDownY;
    private boolean isDraggingSelector;
    private int mScrollMode;
    private long mScrollInterval;
    private boolean mIsAnimationRunning;
    private boolean mStopAnimation;
    private boolean mWrapAround = true;

    private int mTotalAnimatedDistance;
    private int mNumberOfAnimations;
    private long mDelayBetweenAnimations;
    private int mDistanceOfEachAnimation;

    private String[] mTextList;
    private int mCurrentSelectedPos;
    private OnChangedListener mListener;

    private String mText1;
    private String mText2;
    private String mText3;
    private String mText4;
    private String mText5;

    public interface OnChangedListener {
        void onChanged(
                VerticalTextSpinner spinner, int oldPos, int newPos, String[] items);
    }

    public VerticalTextSpinner(Context context) {
        this(context, null);
    }

    public VerticalTextSpinner(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

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

        float scale = getResources().getDisplayMetrics().density;
        TEXT_SPACING = (int)(18 * scale);
        TEXT_MARGIN_RIGHT = (int)(25 * scale);
        TEXT_SIZE = (int)(22 * scale);
        SCROLL_DISTANCE = TEXT_SIZE + TEXT_SPACING;
        TEXT1_Y = (TEXT_SIZE * (-2 + 2)) + (TEXT_SPACING * (-2 + 1));
        TEXT2_Y = (TEXT_SIZE * (-1 + 2)) + (TEXT_SPACING * (-1 + 1));
        TEXT3_Y = (TEXT_SIZE * (0 + 2)) + (TEXT_SPACING * (0 + 1));
        TEXT4_Y = (TEXT_SIZE * (1 + 2)) + (TEXT_SPACING * (1 + 1));
        TEXT5_Y = (TEXT_SIZE * (2 + 2)) + (TEXT_SPACING * (2 + 1));

        mBackgroundFocused = context.getResources().getDrawable(R.drawable.pickerbox_background);
        mSelectorFocused = context.getResources().getDrawable(R.drawable.pickerbox_selected);
        mSelectorNormal = context.getResources().getDrawable(R.drawable.pickerbox_unselected);

        mSelectorHeight = mSelectorFocused.getIntrinsicHeight();
        mSelectorDefaultY = (mBackgroundFocused.getIntrinsicHeight() - mSelectorHeight) / 2;
        mSelectorMinY = 0;
        mSelectorMaxY = mBackgroundFocused.getIntrinsicHeight() - mSelectorHeight;

        mSelector = mSelectorNormal;
        mSelectorY = mSelectorDefaultY;

        mTextPaintDark = new TextPaint(Paint.ANTI_ALIAS_FLAG);
        mTextPaintDark.setTextSize(TEXT_SIZE);
        mTextPaintDark.setColor(context.getResources()
            .getColor(android.R.color.primary_text_light));

        mTextPaintLight = new TextPaint(Paint.ANTI_ALIAS_FLAG);
        mTextPaintLight.setTextSize(TEXT_SIZE);
        mTextPaintLight.setColor(context.getResources()
            .getColor(android.R.color.secondary_text_dark));

        mScrollMode = SCROLL_MODE_NONE;
        mScrollInterval = DEFAULT_SCROLL_INTERVAL_MS;
        calculateAnimationValues();
    }

    public void setOnChangeListener(OnChangedListener listener) {
        mListener = listener;
    }

    public void setItems(String[] textList) {
        mTextList = textList;
        calculateTextPositions();
    }

    public void setSelectedPos(int selectedPos) {
        mCurrentSelectedPos = selectedPos;
        calculateTextPositions();
        postInvalidate();
    }

    public void setScrollInterval(long interval) {
        mScrollInterval = interval;
        calculateAnimationValues();
    }

    public void setWrapAround(boolean wrap) {
        mWrapAround = wrap;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        /* This is a bit confusing, when we get the key event
         * DPAD_DOWN we actually roll the spinner up. When the
         * key event is DPAD_UP we roll the spinner down.
         */
        if ((keyCode == KeyEvent.KEYCODE_DPAD_UP) && canScrollDown()) {
            mScrollMode = SCROLL_MODE_DOWN;
            scroll();
            mStopAnimation = true;
            return true;
        } else if ((keyCode == KeyEvent.KEYCODE_DPAD_DOWN) && canScrollUp()) {
            mScrollMode = SCROLL_MODE_UP;
            scroll();
            mStopAnimation = true;
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    private boolean canScrollDown() {
        return (mCurrentSelectedPos > 0) || mWrapAround;
    }

    private boolean canScrollUp() {
        return ((mCurrentSelectedPos < (mTextList.length - 1)) || mWrapAround);
    }

    @Override
    protected void onFocusChanged(boolean gainFocus, int direction,
            Rect previouslyFocusedRect) {
        if (gainFocus) {
            setBackgroundDrawable(mBackgroundFocused);
            mSelector = mSelectorFocused;
        } else {
            setBackgroundDrawable(null);
            mSelector = mSelectorNormal;
            mSelectorY = mSelectorDefaultY;
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        final int action = event.getAction();
        final int y = (int) event.getY();

        switch (action) {
        case MotionEvent.ACTION_DOWN:
            requestFocus();
            mDownY = y;
            isDraggingSelector = (y >= mSelectorY) &&
                    (y <= (mSelectorY + mSelector.getIntrinsicHeight()));
            break;

        case MotionEvent.ACTION_MOVE:
            if (isDraggingSelector) {
                int top = mSelectorDefaultY + (y - mDownY);
                if (top <= mSelectorMinY && canScrollDown()) {
                    mSelectorY = mSelectorMinY;
                    mStopAnimation = false;
                    if (mScrollMode != SCROLL_MODE_DOWN) {
                        mScrollMode = SCROLL_MODE_DOWN;
                        scroll();
                    }
                } else if (top >= mSelectorMaxY && canScrollUp()) {
                    mSelectorY = mSelectorMaxY;
                    mStopAnimation = false;
                    if (mScrollMode != SCROLL_MODE_UP) {
                        mScrollMode = SCROLL_MODE_UP;
                        scroll();
                    }
                } else {
                    mSelectorY = top;
                    mStopAnimation = true;
                }
            }
            break;

        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_CANCEL:
        default:
            mSelectorY = mSelectorDefaultY;
            mStopAnimation = true;
            invalidate();
            break;
        }
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {

        /* The bounds of the selector */
        final int selectorLeft = 0;
        final int selectorTop = mSelectorY;
        final int selectorRight = getWidth();
        final int selectorBottom = mSelectorY + mSelectorHeight;

        /* Draw the selector */
        mSelector.setBounds(selectorLeft, selectorTop, selectorRight, selectorBottom);
        mSelector.draw(canvas);

        if (mTextList == null) {

            /* We're not setup with values so don't draw anything else */
            return;
        }

        final TextPaint textPaintDark = mTextPaintDark;
        if (hasFocus()) {

            /* The bounds of the top area where the text should be light */
            final int topLeft = 0;
            final int topTop = 0;
            final int topRight = selectorRight;
            final int topBottom = selectorTop + SELECTOR_ARROW_HEIGHT;

            /* Assign a bunch of local finals for performance */
            final String text1 = mText1;
            final String text2 = mText2;
            final String text3 = mText3;
            final String text4 = mText4;
            final String text5 = mText5;
            final TextPaint textPaintLight = mTextPaintLight;

            /*
             * Draw the 1st, 2nd and 3rd item in light only, clip it so it only
             * draws in the area above the selector
             */
            canvas.save();
            canvas.clipRect(topLeft, topTop, topRight, topBottom);
            drawText(canvas, text1, TEXT1_Y
                    + mTotalAnimatedDistance, textPaintLight);
            drawText(canvas, text2, TEXT2_Y
                    + mTotalAnimatedDistance, textPaintLight);
            drawText(canvas, text3,
                    TEXT3_Y + mTotalAnimatedDistance, textPaintLight);
            canvas.restore();

            /*
             * Draw the 2nd, 3rd and 4th clipped to the selector bounds in dark
             * paint
             */
            canvas.save();
            canvas.clipRect(selectorLeft, selectorTop + SELECTOR_ARROW_HEIGHT,
                    selectorRight, selectorBottom - SELECTOR_ARROW_HEIGHT);
            drawText(canvas, text2, TEXT2_Y
                    + mTotalAnimatedDistance, textPaintDark);
            drawText(canvas, text3,
                    TEXT3_Y + mTotalAnimatedDistance, textPaintDark);
            drawText(canvas, text4,
                    TEXT4_Y + mTotalAnimatedDistance, textPaintDark);
            canvas.restore();

            /* The bounds of the bottom area where the text should be light */
            final int bottomLeft = 0;
            final int bottomTop = selectorBottom - SELECTOR_ARROW_HEIGHT;
            final int bottomRight = selectorRight;
            final int bottomBottom = getMeasuredHeight();

            /*
             * Draw the 3rd, 4th and 5th in white text, clip it so it only draws
             * in the area below the selector.
             */
            canvas.save();
            canvas.clipRect(bottomLeft, bottomTop, bottomRight, bottomBottom);
            drawText(canvas, text3,
                    TEXT3_Y + mTotalAnimatedDistance, textPaintLight);
            drawText(canvas, text4,
                    TEXT4_Y + mTotalAnimatedDistance, textPaintLight);
            drawText(canvas, text5,
                    TEXT5_Y + mTotalAnimatedDistance, textPaintLight);
            canvas.restore();

        } else {
            drawText(canvas, mText3, TEXT3_Y, textPaintDark);
        }
        if (mIsAnimationRunning) {
            if ((Math.abs(mTotalAnimatedDistance) + mDistanceOfEachAnimation) > SCROLL_DISTANCE) {
                mTotalAnimatedDistance = 0;
                if (mScrollMode == SCROLL_MODE_UP) {
                    int oldPos = mCurrentSelectedPos;
                    int newPos = getNewIndex(1);
                    if (newPos >= 0) {
                        mCurrentSelectedPos = newPos;
                        if (mListener != null) {
                            mListener.onChanged(this, oldPos, mCurrentSelectedPos, mTextList);
                        }
                    }
                    if (newPos < 0 || ((newPos >= mTextList.length - 1) && !mWrapAround)) {
                        mStopAnimation = true;
                    }
                    calculateTextPositions();
                } else if (mScrollMode == SCROLL_MODE_DOWN) {
                    int oldPos = mCurrentSelectedPos;
                    int newPos = getNewIndex(-1);
                    if (newPos >= 0) {
                        mCurrentSelectedPos = newPos;
                        if (mListener != null) {
                            mListener.onChanged(this, oldPos, mCurrentSelectedPos, mTextList);
                        }
                    }
                    if (newPos < 0 || (newPos == 0 && !mWrapAround)) {
                        mStopAnimation = true;
                    }
                    calculateTextPositions();
                }
                if (mStopAnimation) {
                    final int previousScrollMode = mScrollMode;

                    /* No longer scrolling, we wait till the current animation
                     * completes then we stop.
                     */
                    mIsAnimationRunning = false;
                    mStopAnimation = false;
                    mScrollMode = SCROLL_MODE_NONE;

                    /* If the current selected item is an empty string
                     * scroll past it.
                     */
                    if ("".equals(mTextList[mCurrentSelectedPos])) {
                       mScrollMode = previousScrollMode;
                       scroll();
                       mStopAnimation = true;
                    }
                }
            } else {
                if (mScrollMode == SCROLL_MODE_UP) {
                    mTotalAnimatedDistance -= mDistanceOfEachAnimation;
                } else if (mScrollMode == SCROLL_MODE_DOWN) {
                    mTotalAnimatedDistance += mDistanceOfEachAnimation;
                }
            }
            if (mDelayBetweenAnimations > 0) {
                postInvalidateDelayed(mDelayBetweenAnimations);
            } else {
                invalidate();
            }
        }
    }

    /**
     * Called every time the text items or current position
     * changes. We calculate store we don't have to calculate
     * onDraw.
     */
    private void calculateTextPositions() {
        mText1 = getTextToDraw(-2);
        mText2 = getTextToDraw(-1);
        mText3 = getTextToDraw(0);
        mText4 = getTextToDraw(1);
        mText5 = getTextToDraw(2);
    }

    private String getTextToDraw(int offset) {
        int index = getNewIndex(offset);
        if (index < 0) {
            return "";
        }
        return mTextList[index];
    }

    private int getNewIndex(int offset) {
        int index = mCurrentSelectedPos + offset;
        if (index < 0) {
            if (mWrapAround) {
                index += mTextList.length;
            } else {
                return -1;
            }
        } else if (index >= mTextList.length) {
            if (mWrapAround) {
                index -= mTextList.length;
            } else {
                return -1;
            }
        }
        return index;
    }

    private void scroll() {
        if (mIsAnimationRunning) {
            return;
        }
        mTotalAnimatedDistance = 0;
        mIsAnimationRunning = true;
        invalidate();
    }

    private void calculateAnimationValues() {
        mNumberOfAnimations = (int) mScrollInterval / SCROLL_DISTANCE;
        if (mNumberOfAnimations < MIN_ANIMATIONS) {
            mNumberOfAnimations = MIN_ANIMATIONS;
            mDistanceOfEachAnimation = SCROLL_DISTANCE / mNumberOfAnimations;
            mDelayBetweenAnimations = 0;
        } else {
            mDistanceOfEachAnimation = SCROLL_DISTANCE / mNumberOfAnimations;
            mDelayBetweenAnimations = mScrollInterval / mNumberOfAnimations;
        }
    }

    private void drawText(Canvas canvas, String text, int y, TextPaint paint) {
        int width = (int) paint.measureText(text);
        int x = getMeasuredWidth() - width - TEXT_MARGIN_RIGHT;
        canvas.drawText(text, x, y, paint);
    }

    public int getCurrentSelectedPos() {
        return mCurrentSelectedPos;
    }
}
