/*
 * Copyright (C) 2018 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.AnimatorSet;
import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Handler;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.util.Log;
import android.util.Slog;
import android.view.Display;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import android.view.WindowManagerGlobal;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.support.annotation.DimenRes;
import com.android.systemui.Dependency;
import com.android.systemui.OverviewProxyService;
import com.android.systemui.R;
import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper;
import com.android.systemui.shared.recents.IOverviewProxy;
import com.android.systemui.shared.recents.utilities.Utilities;

import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_BOTTOM;
import static com.android.systemui.OverviewProxyService.DEBUG_OVERVIEW_PROXY;
import static com.android.systemui.OverviewProxyService.TAG_OPS;

/**
 * Class to detect gestures on the navigation bar and implement quick scrub and switch.
 */
public class QuickScrubController extends GestureDetector.SimpleOnGestureListener implements
        GestureHelper {

    private static final String TAG = "QuickScrubController";
    private static final int QUICK_SWITCH_FLING_VELOCITY = 0;
    private static final int ANIM_DURATION_MS = 200;
    private static final long LONG_PRESS_DELAY_MS = 150;

    /**
     * For quick step, set a damping value to allow the button to stick closer its origin position
     * when dragging before quick scrub is active.
     */
    private static final int SWITCH_STICKINESS = 4;

    private NavigationBarView mNavigationBarView;
    private GestureDetector mGestureDetector;

    private boolean mDraggingActive;
    private boolean mQuickScrubActive;
    private float mDownOffset;
    private float mTranslation;
    private int mTouchDownX;
    private int mTouchDownY;
    private boolean mDragPositive;
    private boolean mIsVertical;
    private boolean mIsRTL;
    private float mTrackAlpha;
    private int mLightTrackColor;
    private int mDarkTrackColor;
    private float mDarkIntensity;

    private final Handler mHandler = new Handler();
    private final Interpolator mQuickScrubEndInterpolator = new DecelerateInterpolator();
    private final Rect mTrackRect = new Rect();
    private final Rect mHomeButtonRect = new Rect();
    private final Paint mTrackPaint = new Paint();
    private final int mScrollTouchSlop;
    private final OverviewProxyService mOverviewEventSender;
    private final Display mDisplay;
    private final int mTrackThickness;
    private final int mTrackPadding;
    private final ValueAnimator mTrackAnimator;
    private final ValueAnimator mButtonAnimator;
    private final AnimatorSet mQuickScrubEndAnimator;
    private final Context mContext;
    private final ArgbEvaluator mTrackColorEvaluator = new ArgbEvaluator();

    private final AnimatorUpdateListener mTrackAnimatorListener = valueAnimator -> {
        mTrackAlpha = (float) valueAnimator.getAnimatedValue();
        mNavigationBarView.invalidate();
    };

    private final AnimatorUpdateListener mButtonTranslationListener = animator -> {
        int pos = (int) animator.getAnimatedValue();
        if (!mQuickScrubActive) {
            pos = mDragPositive ? Math.min((int) mTranslation, pos) : Math.max((int) mTranslation, pos);
        }
        final View homeView = mNavigationBarView.getHomeButton().getCurrentView();
        if (mIsVertical) {
            homeView.setTranslationY(pos);
        } else {
            homeView.setTranslationX(pos);
        }
    };

    private AnimatorListenerAdapter mQuickScrubEndListener = new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            mNavigationBarView.getHomeButton().setClickable(true);
            mQuickScrubActive = false;
            mTranslation = 0;
        }
    };

    private Runnable mLongPressRunnable = this::startQuickScrub;

    private final GestureDetector.SimpleOnGestureListener mGestureListener =
        new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velX, float velY) {
                if (!isQuickScrubEnabled() || mQuickScrubActive) {
                    return false;
                }
                float velocityX = mIsRTL ? -velX : velX;
                float absVelY = Math.abs(velY);
                final boolean isValidFling = velocityX > QUICK_SWITCH_FLING_VELOCITY &&
                        mIsVertical ? (absVelY > velocityX) : (velocityX > absVelY);
                if (isValidFling) {
                    mDraggingActive = false;
                    mButtonAnimator.setIntValues((int) mTranslation, 0);
                    mButtonAnimator.start();
                    mHandler.removeCallbacks(mLongPressRunnable);
                    try {
                        final IOverviewProxy overviewProxy = mOverviewEventSender.getProxy();
                        overviewProxy.onQuickSwitch();
                        if (DEBUG_OVERVIEW_PROXY) {
                            Log.d(TAG_OPS, "Quick Switch");
                        }
                    } catch (RemoteException e) {
                        Log.e(TAG, "Failed to send start of quick switch.", e);
                    }
                }
                return true;
            }
        };

    public QuickScrubController(Context context) {
        mContext = context;
        mScrollTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        mDisplay = ((WindowManager) context.getSystemService(
                Context.WINDOW_SERVICE)).getDefaultDisplay();
        mOverviewEventSender = Dependency.get(OverviewProxyService.class);
        mGestureDetector = new GestureDetector(mContext, mGestureListener);
        mTrackThickness = getDimensionPixelSize(mContext, R.dimen.nav_quick_scrub_track_thickness);
        mTrackPadding = getDimensionPixelSize(mContext, R.dimen.nav_quick_scrub_track_edge_padding);
        mTrackPaint.setAlpha(0);

        mTrackAnimator = ObjectAnimator.ofFloat();
        mTrackAnimator.addUpdateListener(mTrackAnimatorListener);
        mButtonAnimator = ObjectAnimator.ofInt();
        mButtonAnimator.addUpdateListener(mButtonTranslationListener);
        mQuickScrubEndAnimator = new AnimatorSet();
        mQuickScrubEndAnimator.playTogether(mTrackAnimator, mButtonAnimator);
        mQuickScrubEndAnimator.setDuration(ANIM_DURATION_MS);
        mQuickScrubEndAnimator.addListener(mQuickScrubEndListener);
        mQuickScrubEndAnimator.setInterpolator(mQuickScrubEndInterpolator);
    }

    public void setComponents(NavigationBarView navigationBarView) {
        mNavigationBarView = navigationBarView;
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        final IOverviewProxy overviewProxy = mOverviewEventSender.getProxy();
        final ButtonDispatcher homeButton = mNavigationBarView.getHomeButton();
        if (overviewProxy == null) {
            homeButton.setDelayTouchFeedback(false);
            return false;
        }
        mGestureDetector.onTouchEvent(event);
        int action = event.getAction();
        switch (action & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_DOWN: {
                int x = (int) event.getX();
                int y = (int) event.getY();
                if (isQuickScrubEnabled() && mHomeButtonRect.contains(x, y)) {
                    mTouchDownX = x;
                    mTouchDownY = y;
                    homeButton.setDelayTouchFeedback(true);
                    mHandler.postDelayed(mLongPressRunnable, LONG_PRESS_DELAY_MS);
                } else {
                    homeButton.setDelayTouchFeedback(false);
                    mTouchDownX = mTouchDownY = -1;
                }
                break;
            }
            case MotionEvent.ACTION_MOVE: {
                if (mTouchDownX != -1) {
                    int x = (int) event.getX();
                    int y = (int) event.getY();
                    int xDiff = Math.abs(x - mTouchDownX);
                    int yDiff = Math.abs(y - mTouchDownY);
                    boolean exceededTouchSlopX = xDiff > mScrollTouchSlop && xDiff > yDiff;
                    boolean exceededTouchSlopY = yDiff > mScrollTouchSlop && yDiff > xDiff;
                    boolean exceededTouchSlop, exceededPerpendicularTouchSlop;
                    int pos, touchDown, offset, trackSize;

                    if (mIsVertical) {
                        exceededTouchSlop = exceededTouchSlopY;
                        exceededPerpendicularTouchSlop = exceededTouchSlopX;
                        pos = y;
                        touchDown = mTouchDownY;
                        offset = pos - mTrackRect.top;
                        trackSize = mTrackRect.height();
                    } else {
                        exceededTouchSlop = exceededTouchSlopX;
                        exceededPerpendicularTouchSlop = exceededTouchSlopY;
                        pos = x;
                        touchDown = mTouchDownX;
                        offset = pos - mTrackRect.left;
                        trackSize = mTrackRect.width();
                    }
                    // Do not start scrubbing when dragging in the perpendicular direction
                    if (!mDraggingActive && exceededPerpendicularTouchSlop) {
                        mHandler.removeCallbacksAndMessages(null);
                        return false;
                    }
                    if (!mDragPositive) {
                        offset -= mIsVertical ? mTrackRect.height() : mTrackRect.width();
                    }

                    // Control the button movement
                    if (!mDraggingActive && exceededTouchSlop) {
                        boolean allowDrag = !mDragPositive
                                ? offset < 0 && pos < touchDown : offset >= 0 && pos > touchDown;
                        if (allowDrag) {
                            mDownOffset = offset;
                            homeButton.setClickable(false);
                            mDraggingActive = true;
                        }
                    }
                    if (mDraggingActive && (mDragPositive && offset >= 0
                            || !mDragPositive && offset <= 0)) {
                        float scrubFraction =
                                Utilities.clamp(Math.abs(offset) * 1f / trackSize, 0, 1);
                        mTranslation = !mDragPositive
                            ? Utilities.clamp(offset - mDownOffset, -trackSize, 0)
                            : Utilities.clamp(offset - mDownOffset, 0, trackSize);
                        if (mQuickScrubActive) {
                            try {
                                overviewProxy.onQuickScrubProgress(scrubFraction);
                                if (DEBUG_OVERVIEW_PROXY) {
                                    Log.d(TAG_OPS, "Quick Scrub Progress:" + scrubFraction);
                                }
                            } catch (RemoteException e) {
                                Log.e(TAG, "Failed to send progress of quick scrub.", e);
                            }
                        } else {
                            mTranslation /= SWITCH_STICKINESS;
                        }
                        if (mIsVertical) {
                            homeButton.getCurrentView().setTranslationY(mTranslation);
                        } else {
                            homeButton.getCurrentView().setTranslationX(mTranslation);
                        }
                    }
                }
                break;
            }
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP:
                endQuickScrub();
                break;
        }
        return mDraggingActive || mQuickScrubActive;
    }

    @Override
    public void onDraw(Canvas canvas) {
        int color = (int) mTrackColorEvaluator.evaluate(mDarkIntensity, mLightTrackColor,
                mDarkTrackColor);
        mTrackPaint.setColor(color);
        mTrackPaint.setAlpha((int) (mTrackPaint.getAlpha() * mTrackAlpha));
        canvas.drawRect(mTrackRect, mTrackPaint);
    }

    @Override
    public void onLayout(boolean changed, int left, int top, int right, int bottom) {
        final int width = right - left;
        final int height = bottom - top;
        final int x1, x2, y1, y2;
        if (mIsVertical) {
            x1 = (width - mTrackThickness) / 2;
            x2 = x1 + mTrackThickness;
            y1 = mDragPositive ? height / 2 : mTrackPadding;
            y2 = y1 + height / 2 - mTrackPadding;
        } else {
            y1 = (height - mTrackThickness) / 2;
            y2 = y1 + mTrackThickness;
            x1 = mDragPositive ? width / 2 : mTrackPadding;
            x2 = x1 + width / 2 - mTrackPadding;
        }
        mTrackRect.set(x1, y1, x2, y2);

        // Get the touch rect of the home button location
        View homeView = mNavigationBarView.getHomeButton().getCurrentView();
        if (homeView != null) {
            int[] globalHomePos = homeView.getLocationOnScreen();
            int[] globalNavBarPos = mNavigationBarView.getLocationOnScreen();
            int homeX = globalHomePos[0] - globalNavBarPos[0];
            int homeY = globalHomePos[1] - globalNavBarPos[1];
            mHomeButtonRect.set(homeX, homeY, homeX + homeView.getMeasuredWidth(),
                    homeY + homeView.getMeasuredHeight());
        }
    }

    @Override
    public void onDarkIntensityChange(float intensity) {
        mDarkIntensity = intensity;
        mNavigationBarView.invalidate();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            endQuickScrub();
        }
        return false;
    }

    @Override
    public void setBarState(boolean isVertical, boolean isRTL) {
        mIsVertical = isVertical;
        mIsRTL = isRTL;
        try {
            int navbarPos = WindowManagerGlobal.getWindowManagerService().getNavBarPosition();
            mDragPositive = navbarPos == NAV_BAR_LEFT || navbarPos == NAV_BAR_BOTTOM;
            if (isRTL) {
                mDragPositive = !mDragPositive;
            }
        } catch (RemoteException e) {
            Slog.e(TAG, "Failed to get nav bar position.", e);
        }
    }

    boolean isQuickScrubEnabled() {
        return SystemProperties.getBoolean("persist.quickstep.scrub.enabled", false);
    }

    private void startQuickScrub() {
        if (!mQuickScrubActive) {
            mQuickScrubActive = true;
            mLightTrackColor = mContext.getColor(R.color.quick_step_track_background_light);
            mDarkTrackColor = mContext.getColor(R.color.quick_step_track_background_dark);
            mTrackAnimator.setFloatValues(0, 1);
            mTrackAnimator.start();
            try {
                mOverviewEventSender.getProxy().onQuickScrubStart();
                if (DEBUG_OVERVIEW_PROXY) {
                    Log.d(TAG_OPS, "Quick Scrub Start");
                }
            } catch (RemoteException e) {
                Log.e(TAG, "Failed to send start of quick scrub.", e);
            }
        }
    }

    private void endQuickScrub() {
        mHandler.removeCallbacks(mLongPressRunnable);
        if (mDraggingActive || mQuickScrubActive) {
            mButtonAnimator.setIntValues((int) mTranslation, 0);
            mTrackAnimator.setFloatValues(mTrackAlpha, 0);
            mQuickScrubEndAnimator.start();
            try {
                mOverviewEventSender.getProxy().onQuickScrubEnd();
                if (DEBUG_OVERVIEW_PROXY) {
                    Log.d(TAG_OPS, "Quick Scrub End");
                }
            } catch (RemoteException e) {
                Log.e(TAG, "Failed to send end of quick scrub.", e);
            }
        }
        mDraggingActive = false;
    }

    private int getDimensionPixelSize(Context context, @DimenRes int resId) {
        return context.getResources().getDimensionPixelSize(resId);
    }
}
