/*
 * Copyright (C) 2014 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.systemui.statusbar.phone;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.Context;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;

import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.statusbar.FlingAnimationUtils;
import com.android.systemui.statusbar.KeyguardAffordanceView;

/**
 * A touch handler of the keyguard which is responsible for launching phone and camera affordances.
 */
public class KeyguardAffordanceHelper {

    public static final long HINT_PHASE1_DURATION = 200;
    private static final long HINT_PHASE2_DURATION = 350;
    private static final float BACKGROUND_RADIUS_SCALE_FACTOR = 0.25f;
    private static final int HINT_CIRCLE_OPEN_DURATION = 500;

    private final Context mContext;
    private final Callback mCallback;

    private FlingAnimationUtils mFlingAnimationUtils;
    private VelocityTracker mVelocityTracker;
    private boolean mSwipingInProgress;
    private float mInitialTouchX;
    private float mInitialTouchY;
    private float mTranslation;
    private float mTranslationOnDown;
    private int mTouchSlop;
    private int mMinTranslationAmount;
    private int mMinFlingVelocity;
    private int mHintGrowAmount;
    private KeyguardAffordanceView mLeftIcon;
    private KeyguardAffordanceView mRightIcon;
    private Animator mSwipeAnimator;
    private final FalsingManager mFalsingManager;
    private int mMinBackgroundRadius;
    private boolean mMotionCancelled;
    private int mTouchTargetSize;
    private View mTargetedView;
    private boolean mTouchSlopExeeded;
    private AnimatorListenerAdapter mFlingEndListener = new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            mSwipeAnimator = null;
            mSwipingInProgress = false;
            mTargetedView = null;
        }
    };
    private Runnable mAnimationEndRunnable = new Runnable() {
        @Override
        public void run() {
            mCallback.onAnimationToSideEnded();
        }
    };

    KeyguardAffordanceHelper(Callback callback, Context context, FalsingManager falsingManager) {
        mContext = context;
        mCallback = callback;
        initIcons();
        updateIcon(mLeftIcon, 0.0f, mLeftIcon.getRestingAlpha(), false, false, true, false);
        updateIcon(mRightIcon, 0.0f, mRightIcon.getRestingAlpha(), false, false, true, false);
        mFalsingManager = falsingManager;
        initDimens();
    }

    private void initDimens() {
        final ViewConfiguration configuration = ViewConfiguration.get(mContext);
        mTouchSlop = configuration.getScaledPagingTouchSlop();
        mMinFlingVelocity = configuration.getScaledMinimumFlingVelocity();
        mMinTranslationAmount = mContext.getResources().getDimensionPixelSize(
                R.dimen.keyguard_min_swipe_amount);
        mMinBackgroundRadius = mContext.getResources().getDimensionPixelSize(
                R.dimen.keyguard_affordance_min_background_radius);
        mTouchTargetSize = mContext.getResources().getDimensionPixelSize(
                R.dimen.keyguard_affordance_touch_target_size);
        mHintGrowAmount =
                mContext.getResources().getDimensionPixelSize(R.dimen.hint_grow_amount_sideways);
        mFlingAnimationUtils = new FlingAnimationUtils(mContext.getResources().getDisplayMetrics(),
                0.4f);
    }

    private void initIcons() {
        mLeftIcon = mCallback.getLeftIcon();
        mRightIcon = mCallback.getRightIcon();
        updatePreviews();
    }

    public void updatePreviews() {
        mLeftIcon.setPreviewView(mCallback.getLeftPreview());
        mRightIcon.setPreviewView(mCallback.getRightPreview());
    }

    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getActionMasked();
        if (mMotionCancelled && action != MotionEvent.ACTION_DOWN) {
            return false;
        }
        final float y = event.getY();
        final float x = event.getX();

        boolean isUp = false;
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                View targetView = getIconAtPosition(x, y);
                if (targetView == null || (mTargetedView != null && mTargetedView != targetView)) {
                    mMotionCancelled = true;
                    return false;
                }
                if (mTargetedView != null) {
                    cancelAnimation();
                } else {
                    mTouchSlopExeeded = false;
                }
                startSwiping(targetView);
                mInitialTouchX = x;
                mInitialTouchY = y;
                mTranslationOnDown = mTranslation;
                initVelocityTracker();
                trackMovement(event);
                mMotionCancelled = false;
                break;
            case MotionEvent.ACTION_POINTER_DOWN:
                mMotionCancelled = true;
                endMotion(true /* forceSnapBack */, x, y);
                break;
            case MotionEvent.ACTION_MOVE:
                trackMovement(event);
                float xDist = x - mInitialTouchX;
                float yDist = y - mInitialTouchY;
                float distance = (float) Math.hypot(xDist, yDist);
                if (!mTouchSlopExeeded && distance > mTouchSlop) {
                    mTouchSlopExeeded = true;
                }
                if (mSwipingInProgress) {
                    if (mTargetedView == mRightIcon) {
                        distance = mTranslationOnDown - distance;
                        distance = Math.min(0, distance);
                    } else {
                        distance = mTranslationOnDown + distance;
                        distance = Math.max(0, distance);
                    }
                    setTranslation(distance, false /* isReset */, false /* animateReset */);
                }
                break;

            case MotionEvent.ACTION_UP:
                isUp = true;
            case MotionEvent.ACTION_CANCEL:
                boolean hintOnTheRight = mTargetedView == mRightIcon;
                trackMovement(event);
                endMotion(!isUp, x, y);
                if (!mTouchSlopExeeded && isUp) {
                    mCallback.onIconClicked(hintOnTheRight);
                }
                break;
        }
        return true;
    }

    private void startSwiping(View targetView) {
        mCallback.onSwipingStarted(targetView == mRightIcon);
        mSwipingInProgress = true;
        mTargetedView = targetView;
    }

    private View getIconAtPosition(float x, float y) {
        if (leftSwipePossible() && isOnIcon(mLeftIcon, x, y)) {
            return mLeftIcon;
        }
        if (rightSwipePossible() && isOnIcon(mRightIcon, x, y)) {
            return mRightIcon;
        }
        return null;
    }

    public boolean isOnAffordanceIcon(float x, float y) {
        return isOnIcon(mLeftIcon, x, y) || isOnIcon(mRightIcon, x, y);
    }

    private boolean isOnIcon(View icon, float x, float y) {
        float iconX = icon.getX() + icon.getWidth() / 2.0f;
        float iconY = icon.getY() + icon.getHeight() / 2.0f;
        double distance = Math.hypot(x - iconX, y - iconY);
        return distance <= mTouchTargetSize / 2;
    }

    private void endMotion(boolean forceSnapBack, float lastX, float lastY) {
        if (mSwipingInProgress) {
            flingWithCurrentVelocity(forceSnapBack, lastX, lastY);
        } else {
            mTargetedView = null;
        }
        if (mVelocityTracker != null) {
            mVelocityTracker.recycle();
            mVelocityTracker = null;
        }
    }

    private boolean rightSwipePossible() {
        return mRightIcon.getVisibility() == View.VISIBLE;
    }

    private boolean leftSwipePossible() {
        return mLeftIcon.getVisibility() == View.VISIBLE;
    }

    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return false;
    }

    public void startHintAnimation(boolean right,
            Runnable onFinishedListener) {
        cancelAnimation();
        startHintAnimationPhase1(right, onFinishedListener);
    }

    private void startHintAnimationPhase1(final boolean right, final Runnable onFinishedListener) {
        final KeyguardAffordanceView targetView = right ? mRightIcon : mLeftIcon;
        ValueAnimator animator = getAnimatorToRadius(right, mHintGrowAmount);
        animator.addListener(new AnimatorListenerAdapter() {
            private boolean mCancelled;

            @Override
            public void onAnimationCancel(Animator animation) {
                mCancelled = true;
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                if (mCancelled) {
                    mSwipeAnimator = null;
                    mTargetedView = null;
                    onFinishedListener.run();
                } else {
                    startUnlockHintAnimationPhase2(right, onFinishedListener);
                }
            }
        });
        animator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
        animator.setDuration(HINT_PHASE1_DURATION);
        animator.start();
        mSwipeAnimator = animator;
        mTargetedView = targetView;
    }

    /**
     * Phase 2: Move back.
     */
    private void startUnlockHintAnimationPhase2(boolean right, final Runnable onFinishedListener) {
        ValueAnimator animator = getAnimatorToRadius(right, 0);
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mSwipeAnimator = null;
                mTargetedView = null;
                onFinishedListener.run();
            }
        });
        animator.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
        animator.setDuration(HINT_PHASE2_DURATION);
        animator.setStartDelay(HINT_CIRCLE_OPEN_DURATION);
        animator.start();
        mSwipeAnimator = animator;
    }

    private ValueAnimator getAnimatorToRadius(final boolean right, int radius) {
        final KeyguardAffordanceView targetView = right ? mRightIcon : mLeftIcon;
        ValueAnimator animator = ValueAnimator.ofFloat(targetView.getCircleRadius(), radius);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float newRadius = (float) animation.getAnimatedValue();
                targetView.setCircleRadiusWithoutAnimation(newRadius);
                float translation = getTranslationFromRadius(newRadius);
                mTranslation = right ? -translation : translation;
                updateIconsFromTranslation(targetView);
            }
        });
        return animator;
    }

    private void cancelAnimation() {
        if (mSwipeAnimator != null) {
            mSwipeAnimator.cancel();
        }
    }

    private void flingWithCurrentVelocity(boolean forceSnapBack, float lastX, float lastY) {
        float vel = getCurrentVelocity(lastX, lastY);

        // We snap back if the current translation is not far enough
        boolean snapBack = false;
        if (mCallback.needsAntiFalsing()) {
            snapBack = snapBack || mFalsingManager.isFalseTouch();
        }
        snapBack = snapBack || isBelowFalsingThreshold();

        // or if the velocity is in the opposite direction.
        boolean velIsInWrongDirection = vel * mTranslation < 0;
        snapBack |= Math.abs(vel) > mMinFlingVelocity && velIsInWrongDirection;
        vel = snapBack ^ velIsInWrongDirection ? 0 : vel;
        fling(vel, snapBack || forceSnapBack, mTranslation < 0);
    }

    private boolean isBelowFalsingThreshold() {
        return Math.abs(mTranslation) < Math.abs(mTranslationOnDown) + getMinTranslationAmount();
    }

    private int getMinTranslationAmount() {
        float factor = mCallback.getAffordanceFalsingFactor();
        return (int) (mMinTranslationAmount * factor);
    }

    private void fling(float vel, final boolean snapBack, boolean right) {
        float target = right ? -mCallback.getMaxTranslationDistance()
                : mCallback.getMaxTranslationDistance();
        target = snapBack ? 0 : target;

        ValueAnimator animator = ValueAnimator.ofFloat(mTranslation, target);
        mFlingAnimationUtils.apply(animator, mTranslation, target, vel);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mTranslation = (float) animation.getAnimatedValue();
            }
        });
        animator.addListener(mFlingEndListener);
        if (!snapBack) {
            startFinishingCircleAnimation(vel * 0.375f, mAnimationEndRunnable, right);
            mCallback.onAnimationToSideStarted(right, mTranslation, vel);
        } else {
            reset(true);
        }
        animator.start();
        mSwipeAnimator = animator;
        if (snapBack) {
            mCallback.onSwipingAborted();
        }
    }

    private void startFinishingCircleAnimation(float velocity, Runnable animationEndRunnable,
            boolean right) {
        KeyguardAffordanceView targetView = right ? mRightIcon : mLeftIcon;
        targetView.finishAnimation(velocity, animationEndRunnable);
    }

    private void setTranslation(float translation, boolean isReset, boolean animateReset) {
        translation = rightSwipePossible() ? translation : Math.max(0, translation);
        translation = leftSwipePossible() ? translation : Math.min(0, translation);
        float absTranslation = Math.abs(translation);
        if (translation != mTranslation || isReset) {
            KeyguardAffordanceView targetView = translation > 0 ? mLeftIcon : mRightIcon;
            KeyguardAffordanceView otherView = translation > 0 ? mRightIcon : mLeftIcon;
            float alpha = absTranslation / getMinTranslationAmount();

            // We interpolate the alpha of the other icons to 0
            float fadeOutAlpha = 1.0f - alpha;
            fadeOutAlpha = Math.max(fadeOutAlpha, 0.0f);

            boolean animateIcons = isReset && animateReset;
            boolean forceNoCircleAnimation = isReset && !animateReset;
            float radius = getRadiusFromTranslation(absTranslation);
            boolean slowAnimation = isReset && isBelowFalsingThreshold();
            if (!isReset) {
                updateIcon(targetView, radius, alpha + fadeOutAlpha * targetView.getRestingAlpha(),
                        false, false, false, false);
            } else {
                updateIcon(targetView, 0.0f, fadeOutAlpha * targetView.getRestingAlpha(),
                        animateIcons, slowAnimation, true /* isReset */, forceNoCircleAnimation);
            }
            updateIcon(otherView, 0.0f, fadeOutAlpha * otherView.getRestingAlpha(),
                    animateIcons, slowAnimation, isReset, forceNoCircleAnimation);

            mTranslation = translation;
        }
    }

    private void updateIconsFromTranslation(KeyguardAffordanceView targetView) {
        float absTranslation = Math.abs(mTranslation);
        float alpha = absTranslation / getMinTranslationAmount();

        // We interpolate the alpha of the other icons to 0
        float fadeOutAlpha =  1.0f - alpha;
        fadeOutAlpha = Math.max(0.0f, fadeOutAlpha);

        // We interpolate the alpha of the targetView to 1
        KeyguardAffordanceView otherView = targetView == mRightIcon ? mLeftIcon : mRightIcon;
        updateIconAlpha(targetView, alpha + fadeOutAlpha * targetView.getRestingAlpha(), false);
        updateIconAlpha(otherView, fadeOutAlpha * otherView.getRestingAlpha(), false);
    }

    private float getTranslationFromRadius(float circleSize) {
        float translation = (circleSize - mMinBackgroundRadius)
                / BACKGROUND_RADIUS_SCALE_FACTOR;
        return translation > 0.0f ? translation + mTouchSlop : 0.0f;
    }

    private float getRadiusFromTranslation(float translation) {
        if (translation <= mTouchSlop) {
            return 0.0f;
        }
        return (translation - mTouchSlop)  * BACKGROUND_RADIUS_SCALE_FACTOR + mMinBackgroundRadius;
    }

    public void animateHideLeftRightIcon() {
        cancelAnimation();
        updateIcon(mRightIcon, 0f, 0f, true, false, false, false);
        updateIcon(mLeftIcon, 0f, 0f, true, false, false, false);
    }

    private void updateIcon(KeyguardAffordanceView view, float circleRadius, float alpha,
                            boolean animate, boolean slowRadiusAnimation, boolean force,
                            boolean forceNoCircleAnimation) {
        if (view.getVisibility() != View.VISIBLE && !force) {
            return;
        }
        if (forceNoCircleAnimation) {
            view.setCircleRadiusWithoutAnimation(circleRadius);
        } else {
            view.setCircleRadius(circleRadius, slowRadiusAnimation);
        }
        updateIconAlpha(view, alpha, animate);
    }

    private void updateIconAlpha(KeyguardAffordanceView view, float alpha, boolean animate) {
        float scale = getScale(alpha, view);
        alpha = Math.min(1.0f, alpha);
        view.setImageAlpha(alpha, animate);
        view.setImageScale(scale, animate);
    }

    private float getScale(float alpha, KeyguardAffordanceView icon) {
        float scale = alpha / icon.getRestingAlpha() * 0.2f +
                KeyguardAffordanceView.MIN_ICON_SCALE_AMOUNT;
        return Math.min(scale, KeyguardAffordanceView.MAX_ICON_SCALE_AMOUNT);
    }

    private void trackMovement(MotionEvent event) {
        if (mVelocityTracker != null) {
            mVelocityTracker.addMovement(event);
        }
    }

    private void initVelocityTracker() {
        if (mVelocityTracker != null) {
            mVelocityTracker.recycle();
        }
        mVelocityTracker = VelocityTracker.obtain();
    }

    private float getCurrentVelocity(float lastX, float lastY) {
        if (mVelocityTracker == null) {
            return 0;
        }
        mVelocityTracker.computeCurrentVelocity(1000);
        float aX = mVelocityTracker.getXVelocity();
        float aY = mVelocityTracker.getYVelocity();
        float bX = lastX - mInitialTouchX;
        float bY = lastY - mInitialTouchY;
        float bLen = (float) Math.hypot(bX, bY);
        // Project the velocity onto the distance vector: a * b / |b|
        float projectedVelocity = (aX * bX + aY * bY) / bLen;
        if (mTargetedView == mRightIcon) {
            projectedVelocity = -projectedVelocity;
        }
        return projectedVelocity;
    }

    public void onConfigurationChanged() {
        initDimens();
        initIcons();
    }

    public void onRtlPropertiesChanged() {
        initIcons();
    }

    public void reset(boolean animate) {
        cancelAnimation();
        setTranslation(0.0f, true /* isReset */, animate);
        mMotionCancelled = true;
        if (mSwipingInProgress) {
            mCallback.onSwipingAborted();
            mSwipingInProgress = false;
        }
    }

    public boolean isSwipingInProgress() {
        return mSwipingInProgress;
    }

    public void launchAffordance(boolean animate, boolean left) {
        if (mSwipingInProgress) {
            // We don't want to mess with the state if the user is actually swiping already.
            return;
        }
        KeyguardAffordanceView targetView = left ? mLeftIcon : mRightIcon;
        KeyguardAffordanceView otherView = left ? mRightIcon : mLeftIcon;
        startSwiping(targetView);

        // Do not animate the circle expanding if the affordance isn't visible,
        // otherwise the circle will be meaningless.
        if (targetView.getVisibility() != View.VISIBLE) {
            animate = false;
        }

        if (animate) {
            fling(0, false, !left);
            updateIcon(otherView, 0.0f, 0, true, false, true, false);
        } else {
            mCallback.onAnimationToSideStarted(!left, mTranslation, 0);
            mTranslation = left ? mCallback.getMaxTranslationDistance()
                    : mCallback.getMaxTranslationDistance();
            updateIcon(otherView, 0.0f, 0.0f, false, false, true, false);
            targetView.instantFinishAnimation();
            mFlingEndListener.onAnimationEnd(null);
            mAnimationEndRunnable.run();
        }
    }

    public interface Callback {

        /**
         * Notifies the callback when an animation to a side page was started.
         *
         * @param rightPage Is the page animated to the right page?
         */
        void onAnimationToSideStarted(boolean rightPage, float translation, float vel);

        /**
         * Notifies the callback the animation to a side page has ended.
         */
        void onAnimationToSideEnded();

        float getMaxTranslationDistance();

        void onSwipingStarted(boolean rightIcon);

        void onSwipingAborted();

        void onIconClicked(boolean rightIcon);

        KeyguardAffordanceView getLeftIcon();

        KeyguardAffordanceView getRightIcon();

        View getLeftPreview();

        View getRightPreview();

        /**
         * @return The factor the minimum swipe amount should be multiplied with.
         */
        float getAffordanceFalsingFactor();

        boolean needsAntiFalsing();
    }
}
