package android.widget;

import com.android.internal.R;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;

/**
 * @hide
 */
public class ZoomRing extends View {
    
    // TODO: move to ViewConfiguration?
    private static final int DOUBLE_TAP_DISMISS_TIMEOUT = ViewConfiguration.getJumpTapTimeout();
    // TODO: get from theme
    private static final int DISABLED_ALPHA = 160;
    
    private static final String TAG = "ZoomRing";

    // TODO: xml
    private static final int THUMB_DISTANCE = 63; 
    
    /** To avoid floating point calculations, we multiply radians by this value. */
    public static final int RADIAN_INT_MULTIPLIER = 100000000;
    /** PI using our multiplier. */
    public static final int PI_INT_MULTIPLIED = (int) (Math.PI * RADIAN_INT_MULTIPLIER);
    /** PI/2 using our multiplier. */
    private static final int HALF_PI_INT_MULTIPLIED = PI_INT_MULTIPLIED / 2;

    private static final int THUMB_GRAB_SLOP = PI_INT_MULTIPLIED / 4;
    
    /** The cached X of our center. */
    private int mCenterX;
    /** The cached Y of our center. */ 
    private int mCenterY;

    /** The angle of the thumb (in int radians) */
    private int mThumbAngle;
    private boolean mIsThumbAngleValid;
    private int mThumbCenterX;
    private int mThumbCenterY;
    private int mThumbHalfWidth;
    private int mThumbHalfHeight;
    
    private int mCallbackThreshold = Integer.MAX_VALUE;
    
    /** The accumulated amount of drag for the thumb (in int radians). */
    private int mAcculumalatedThumbDrag = 0;
   
    /** The inner radius of the track. */
    private int mBoundInnerRadiusSquared = 0;
    /** The outer radius of the track. */
    private int mBoundOuterRadiusSquared = Integer.MAX_VALUE;
    
    private int mPreviousWidgetDragX;
    private int mPreviousWidgetDragY;
    
    private boolean mDrawThumb = true;
    private Drawable mThumbDrawable;
    
    private static final int MODE_IDLE = 0;
    private static final int MODE_DRAG_THUMB = 1;
    private static final int MODE_MOVE_ZOOM_RING = 2;
    private static final int MODE_TAP_DRAG = 3;
    private int mMode;

    private long mPreviousTapTime;
    
    private Handler mHandler = new Handler();
    
    private Disabler mDisabler = new Disabler();
    
    private OnZoomRingCallback mCallback;
    
    private boolean mResetThumbAutomatically = true;
    private int mThumbDragStartAngle;
    
    public ZoomRing(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        // TODO get drawable from style instead
        Resources res = context.getResources();
        mThumbDrawable = res.getDrawable(R.drawable.zoom_ring_thumb);
        
        // TODO: add padding to drawable
        setBackgroundResource(R.drawable.zoom_ring_track);
        // TODO get from style
        setBounds(30, Integer.MAX_VALUE);
        
        mThumbHalfHeight = mThumbDrawable.getIntrinsicHeight() / 2;
        mThumbHalfWidth = mThumbDrawable.getIntrinsicWidth() / 2;
        
        mCallbackThreshold = PI_INT_MULTIPLIED / 6;
    }

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

    public ZoomRing(Context context) {
        this(context, null);
    }
    
    public void setCallback(OnZoomRingCallback callback) {
        mCallback = callback;
    }

    // TODO: rename
    public void setCallbackThreshold(int callbackThreshold) {
        mCallbackThreshold = callbackThreshold;
    }

    // TODO: from XML too
    public void setBounds(int innerRadius, int outerRadius) {
        mBoundInnerRadiusSquared = innerRadius * innerRadius;
        if (mBoundInnerRadiusSquared < innerRadius) {
            // Prevent overflow
            mBoundInnerRadiusSquared = Integer.MAX_VALUE;
        }

        mBoundOuterRadiusSquared = outerRadius * outerRadius;
        if (mBoundOuterRadiusSquared < outerRadius) {
            // Prevent overflow
            mBoundOuterRadiusSquared = Integer.MAX_VALUE;
        }
    }
    
    public void setThumbAngle(int angle) {
        mThumbAngle = angle;
        mThumbCenterX = (int) (Math.cos(1f * angle / RADIAN_INT_MULTIPLIER) * THUMB_DISTANCE)
                + mCenterX;
        mThumbCenterY = (int) (Math.sin(1f * angle / RADIAN_INT_MULTIPLIER) * THUMB_DISTANCE)
                * -1 + mCenterY;
        invalidate();
    }
    
    public void resetThumbAngle() {
        if (mResetThumbAutomatically) {
            setThumbAngle(HALF_PI_INT_MULTIPLIED);
        }
    }
    
    public void setResetThumbAutomatically(boolean resetThumbAutomatically) {
        mResetThumbAutomatically = resetThumbAutomatically;
    }
    
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec),
                resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec));
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right,
            int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        
        // Cache the center point
        mCenterX = (right - left) / 2;
        mCenterY = (bottom - top) / 2;

        // Done here since we now have center, which is needed to calculate some
        // aux info for thumb angle
        if (mThumbAngle == Integer.MIN_VALUE) {
            resetThumbAngle();
        }
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return handleTouch(event.getAction(), event.getEventTime(),
                (int) event.getX(), (int) event.getY(), (int) event.getRawX(),
                (int) event.getRawY());
    }

    private void resetState() {
        mMode = MODE_IDLE;
        mPreviousWidgetDragX = mPreviousWidgetDragY = Integer.MIN_VALUE;
        mAcculumalatedThumbDrag = 0;
        mIsThumbAngleValid = false;
    }
    
    public void setTapDragMode(boolean tapDragMode, int x, int y) {
        resetState();
        mMode = tapDragMode ? MODE_TAP_DRAG : MODE_IDLE;
        mIsThumbAngleValid = false;
        
        if (tapDragMode && mCallback != null) {
            onThumbDragStarted(getAngle(x - mCenterX, y - mCenterY));
        }
    }
    
    public boolean handleTouch(int action, long time, int x, int y, int rawX, int rawY) {
        switch (action) {
        
            case MotionEvent.ACTION_DOWN:
                if (mPreviousTapTime + DOUBLE_TAP_DISMISS_TIMEOUT >= time) {
                    if (mCallback != null) {
                        mCallback.onZoomRingDismissed();
                    }
                } else {
                    mPreviousTapTime = time;
                }
                resetState();
                return true;
                
            case MotionEvent.ACTION_MOVE:
                // Fall through to code below switch
                break;
                
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                if (mCallback != null) {
                    if (mMode == MODE_MOVE_ZOOM_RING) {
                        mCallback.onZoomRingMovingStopped();
                    } else if (mMode == MODE_DRAG_THUMB || mMode == MODE_TAP_DRAG) {
                        onThumbDragStopped(getAngle(x - mCenterX, y - mCenterY));
                    }
                }
                mDisabler.setEnabling(true);
                return true;
                
            default:
                return false;
        }
        
        // local{X,Y} will be where the center of the widget is (0,0)
        int localX = x - mCenterX;
        int localY = y - mCenterY;
        boolean isTouchingThumb = true;
        boolean isInBounds = true;
        int touchAngle = getAngle(localX, localY);
        
        int radiusSquared = localX * localX + localY * localY;
        if (radiusSquared < mBoundInnerRadiusSquared ||
                radiusSquared > mBoundOuterRadiusSquared) {
            // Out-of-bounds
            isTouchingThumb = false;
            isInBounds = false;
        }
        
        int deltaThumbAndTouch = getDelta(touchAngle, mThumbAngle);
        int absoluteDeltaThumbAndTouch = deltaThumbAndTouch >= 0 ?
                deltaThumbAndTouch : -deltaThumbAndTouch;
        if (isTouchingThumb &&
                absoluteDeltaThumbAndTouch > THUMB_GRAB_SLOP) {
            // Didn't grab close enough to the thumb
            isTouchingThumb = false;
        }
        
        if (mMode == MODE_IDLE) {
            mMode = isTouchingThumb ? MODE_DRAG_THUMB : MODE_MOVE_ZOOM_RING;
            
            if (mCallback != null) {
                if (mMode == MODE_DRAG_THUMB) {
                    onThumbDragStarted(touchAngle);
                } else if (mMode == MODE_MOVE_ZOOM_RING) {
                    mCallback.onZoomRingMovingStarted();
                }
            }
        }
        
        if (mMode == MODE_DRAG_THUMB || mMode == MODE_TAP_DRAG) {
            if (isInBounds) {
                onThumbDragged(touchAngle, mIsThumbAngleValid ? deltaThumbAndTouch : 0);
            } else {
                mIsThumbAngleValid = false;
            }
        } else if (mMode == MODE_MOVE_ZOOM_RING) {
            onZoomRingMoved(rawX, rawY);
        }
        
        return true;
    }
    
    private int getDelta(int angle1, int angle2) {
        int delta = angle1 - angle2;
                
        // Assume this is a result of crossing over the discontinuous 0 -> 2pi
        if (delta > PI_INT_MULTIPLIED || delta < -PI_INT_MULTIPLIED) {
            // Bring both the radians and previous angle onto a continuous range
            if (angle1 < HALF_PI_INT_MULTIPLIED) {
                // Same as deltaRadians = (radians + 2PI) - previousAngle
                delta += PI_INT_MULTIPLIED * 2;
            } else if (angle2 < HALF_PI_INT_MULTIPLIED) {
                // Same as deltaRadians = radians - (previousAngle + 2PI)
                delta -= PI_INT_MULTIPLIED * 2;
            }
        }
       
        return delta;
    }

    private void onThumbDragStarted(int startAngle) {
        mThumbDragStartAngle = startAngle;
        mCallback.onZoomRingThumbDraggingStarted(startAngle);
    }
    
    private void onThumbDragged(int touchAngle, int deltaAngle) {
        mAcculumalatedThumbDrag += deltaAngle;
        if (mAcculumalatedThumbDrag > mCallbackThreshold
                || mAcculumalatedThumbDrag < -mCallbackThreshold) {
            if (mCallback != null) {
                boolean canStillZoom = mCallback.onZoomRingThumbDragged(
                        mAcculumalatedThumbDrag / mCallbackThreshold,
                        mAcculumalatedThumbDrag, mThumbDragStartAngle, touchAngle);
                mDisabler.setEnabling(canStillZoom);
            }
            mAcculumalatedThumbDrag = 0;
        }
    
        setThumbAngle(touchAngle);
        mIsThumbAngleValid = true;
    }
    
    private void onThumbDragStopped(int stopAngle) {
        mCallback.onZoomRingThumbDraggingStopped(stopAngle);
    }
    
    private void onZoomRingMoved(int x, int y) {
        if (mPreviousWidgetDragX != Integer.MIN_VALUE) {
            int deltaX = x - mPreviousWidgetDragX;
            int deltaY = y - mPreviousWidgetDragY;
            
            if (mCallback != null) {
                mCallback.onZoomRingMoved(deltaX, deltaY);
            }
        }
        
        mPreviousWidgetDragX = x;
        mPreviousWidgetDragY = y;
    }
    
    @Override
    public void onWindowFocusChanged(boolean hasWindowFocus) {
        super.onWindowFocusChanged(hasWindowFocus);
        
        if (!hasWindowFocus && mCallback != null) {
            mCallback.onZoomRingDismissed();
        }
    }

    private int getAngle(int localX, int localY) {
        int radians = (int) (Math.atan2(localY, localX) * RADIAN_INT_MULTIPLIER);

        // Convert from [-pi,pi] to {0,2pi]
        if (radians < 0) {
            return -radians;
        } else if (radians > 0) {
            return 2 * PI_INT_MULTIPLIED - radians;
        } else {
            return 0;
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        
        if (mDrawThumb) {
            mThumbDrawable.setBounds(mThumbCenterX - mThumbHalfWidth, mThumbCenterY
                    - mThumbHalfHeight, mThumbCenterX + mThumbHalfWidth, mThumbCenterY
                    + mThumbHalfHeight);
            mThumbDrawable.draw(canvas);
        }
    }

    private class Disabler implements Runnable {
        private static final int DELAY = 15;
        private static final float ENABLE_RATE = 1.05f;
        private static final float DISABLE_RATE = 0.95f;
        
        private int mAlpha = 255;
        private boolean mEnabling;
        
        public int getAlpha() {
            return mAlpha;
        }

        public void setEnabling(boolean enabling) {
            if ((enabling && mAlpha != 255) || (!enabling && mAlpha != DISABLED_ALPHA)) {
                mEnabling = enabling;
                post(this);
            }
        }
        
        public void run() {
            mAlpha *= mEnabling ? ENABLE_RATE : DISABLE_RATE;
            if (mAlpha < DISABLED_ALPHA) {
                mAlpha = DISABLED_ALPHA;
            } else if (mAlpha > 255) {
                mAlpha = 255;
            } else {
                // Still more to go
                postDelayed(this, DELAY);
            }
            
            getBackground().setAlpha(mAlpha);
            invalidate();
        }
    }
    
    public interface OnZoomRingCallback {
        void onZoomRingMovingStarted();
        boolean onZoomRingMoved(int deltaX, int deltaY);
        void onZoomRingMovingStopped();
        
        void onZoomRingThumbDraggingStarted(int startAngle);
        boolean onZoomRingThumbDragged(int numLevels, int dragAmount, int startAngle, int curAngle);
        void onZoomRingThumbDraggingStopped(int endAngle);
        
        void onZoomRingDismissed();
    }

}
