/*
 * Copyright (C) 2011 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;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.NonNull;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.RectF;
import android.os.Handler;
import android.util.ArrayMap;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityEvent;

import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.statusbar.FlingAnimationUtils;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;

public class SwipeHelper implements Gefingerpoken {
    static final String TAG = "com.android.systemui.SwipeHelper";
    private static final boolean DEBUG = false;
    private static final boolean DEBUG_INVALIDATE = false;
    private static final boolean SLOW_ANIMATIONS = false; // DEBUG;
    private static final boolean CONSTRAIN_SWIPE = true;
    private static final boolean FADE_OUT_DURING_SWIPE = true;
    private static final boolean DISMISS_IF_SWIPED_FAR_ENOUGH = true;

    public static final int X = 0;
    public static final int Y = 1;

    private static final float SWIPE_ESCAPE_VELOCITY = 500f; // dp/sec
    private static final int DEFAULT_ESCAPE_ANIMATION_DURATION = 200; // ms
    private static final int MAX_ESCAPE_ANIMATION_DURATION = 400; // ms
    private static final int MAX_DISMISS_VELOCITY = 4000; // dp/sec
    private static final int SNAP_ANIM_LEN = SLOW_ANIMATIONS ? 1000 : 150; // ms

    static final float SWIPE_PROGRESS_FADE_END = 0.5f; // fraction of thumbnail width
                                              // beyond which swipe progress->0
    public static final float SWIPED_FAR_ENOUGH_SIZE_FRACTION = 0.6f;
    static final float MAX_SCROLL_SIZE_FRACTION = 0.3f;

    protected final Handler mHandler;

    private float mMinSwipeProgress = 0f;
    private float mMaxSwipeProgress = 1f;

    private final FlingAnimationUtils mFlingAnimationUtils;
    private float mPagingTouchSlop;
    private final Callback mCallback;
    private final int mSwipeDirection;
    private final VelocityTracker mVelocityTracker;
    private final FalsingManager mFalsingManager;

    private float mInitialTouchPos;
    private float mPerpendicularInitialTouchPos;
    private boolean mDragging;
    private boolean mSnappingChild;
    private View mCurrView;
    private boolean mCanCurrViewBeDimissed;
    private float mDensityScale;
    private float mTranslation = 0;

    private boolean mMenuRowIntercepting;
    private boolean mLongPressSent;
    private Runnable mWatchLongPress;
    private final long mLongPressTimeout;

    final private int[] mTmpPos = new int[2];
    private final int mFalsingThreshold;
    private boolean mTouchAboveFalsingThreshold;
    private boolean mDisableHwLayers;
    private final boolean mFadeDependingOnAmountSwiped;

    private final ArrayMap<View, Animator> mDismissPendingMap = new ArrayMap<>();

    public SwipeHelper(
            int swipeDirection, Callback callback, Context context, FalsingManager falsingManager) {
        mCallback = callback;
        mHandler = new Handler();
        mSwipeDirection = swipeDirection;
        mVelocityTracker = VelocityTracker.obtain();
        mPagingTouchSlop = ViewConfiguration.get(context).getScaledPagingTouchSlop();

        // Extra long-press!
        mLongPressTimeout = (long) (ViewConfiguration.getLongPressTimeout() * 1.5f);

        Resources res = context.getResources();
        mDensityScale =  res.getDisplayMetrics().density;
        mFalsingThreshold = res.getDimensionPixelSize(R.dimen.swipe_helper_falsing_threshold);
        mFadeDependingOnAmountSwiped = res.getBoolean(R.bool.config_fadeDependingOnAmountSwiped);
        mFalsingManager = falsingManager;
        mFlingAnimationUtils = new FlingAnimationUtils(res.getDisplayMetrics(),
                getMaxEscapeAnimDuration() / 1000f);
    }

    public void setDensityScale(float densityScale) {
        mDensityScale = densityScale;
    }

    public void setPagingTouchSlop(float pagingTouchSlop) {
        mPagingTouchSlop = pagingTouchSlop;
    }

    public void setDisableHardwareLayers(boolean disableHwLayers) {
        mDisableHwLayers = disableHwLayers;
    }

    private float getPos(MotionEvent ev) {
        return mSwipeDirection == X ? ev.getX() : ev.getY();
    }

    private float getPerpendicularPos(MotionEvent ev) {
        return mSwipeDirection == X ? ev.getY() : ev.getX();
    }

    protected float getTranslation(View v) {
        return mSwipeDirection == X ? v.getTranslationX() : v.getTranslationY();
    }

    private float getVelocity(VelocityTracker vt) {
        return mSwipeDirection == X ? vt.getXVelocity() :
                vt.getYVelocity();
    }

    protected ObjectAnimator createTranslationAnimation(View v, float newPos) {
        ObjectAnimator anim = ObjectAnimator.ofFloat(v,
                mSwipeDirection == X ? View.TRANSLATION_X : View.TRANSLATION_Y, newPos);
        return anim;
    }

    private float getPerpendicularVelocity(VelocityTracker vt) {
        return mSwipeDirection == X ? vt.getYVelocity() :
                vt.getXVelocity();
    }

    protected Animator getViewTranslationAnimator(View v, float target,
            AnimatorUpdateListener listener) {
        ObjectAnimator anim = createTranslationAnimation(v, target);
        if (listener != null) {
            anim.addUpdateListener(listener);
        }
        return anim;
    }

    protected void setTranslation(View v, float translate) {
        if (v == null) {
            return;
        }
        if (mSwipeDirection == X) {
            v.setTranslationX(translate);
        } else {
            v.setTranslationY(translate);
        }
    }

    protected float getSize(View v) {
        return mSwipeDirection == X ? v.getMeasuredWidth() : v.getMeasuredHeight();
    }

    public void setMinSwipeProgress(float minSwipeProgress) {
        mMinSwipeProgress = minSwipeProgress;
    }

    public void setMaxSwipeProgress(float maxSwipeProgress) {
        mMaxSwipeProgress = maxSwipeProgress;
    }

    private float getSwipeProgressForOffset(View view, float translation) {
        float viewSize = getSize(view);
        float result = Math.abs(translation / viewSize);
        return Math.min(Math.max(mMinSwipeProgress, result), mMaxSwipeProgress);
    }

    private float getSwipeAlpha(float progress) {
        if (mFadeDependingOnAmountSwiped) {
            // The more progress has been fade, the lower the alpha value so that the view fades.
            return Math.max(1 - progress, 0);
        }

        return 1f - Math.max(0, Math.min(1, progress / SWIPE_PROGRESS_FADE_END));
    }

    private void updateSwipeProgressFromOffset(View animView, boolean dismissable) {
        updateSwipeProgressFromOffset(animView, dismissable, getTranslation(animView));
    }

    private void updateSwipeProgressFromOffset(View animView, boolean dismissable,
            float translation) {
        float swipeProgress = getSwipeProgressForOffset(animView, translation);
        if (!mCallback.updateSwipeProgress(animView, dismissable, swipeProgress)) {
            if (FADE_OUT_DURING_SWIPE && dismissable) {
                if (!mDisableHwLayers) {
                    if (swipeProgress != 0f && swipeProgress != 1f) {
                        animView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
                    } else {
                        animView.setLayerType(View.LAYER_TYPE_NONE, null);
                    }
                }
                animView.setAlpha(getSwipeAlpha(swipeProgress));
            }
        }
        invalidateGlobalRegion(animView);
    }

    // invalidate the view's own bounds all the way up the view hierarchy
    public static void invalidateGlobalRegion(View view) {
        invalidateGlobalRegion(
            view,
            new RectF(view.getLeft(), view.getTop(), view.getRight(), view.getBottom()));
    }

    // invalidate a rectangle relative to the view's coordinate system all the way up the view
    // hierarchy
    public static void invalidateGlobalRegion(View view, RectF childBounds) {
        //childBounds.offset(view.getTranslationX(), view.getTranslationY());
        if (DEBUG_INVALIDATE)
            Log.v(TAG, "-------------");
        while (view.getParent() != null && view.getParent() instanceof View) {
            view = (View) view.getParent();
            view.getMatrix().mapRect(childBounds);
            view.invalidate((int) Math.floor(childBounds.left),
                            (int) Math.floor(childBounds.top),
                            (int) Math.ceil(childBounds.right),
                            (int) Math.ceil(childBounds.bottom));
            if (DEBUG_INVALIDATE) {
                Log.v(TAG, "INVALIDATE(" + (int) Math.floor(childBounds.left)
                        + "," + (int) Math.floor(childBounds.top)
                        + "," + (int) Math.ceil(childBounds.right)
                        + "," + (int) Math.ceil(childBounds.bottom));
            }
        }
    }

    public void cancelLongPress() {
        if (mWatchLongPress != null) {
            mHandler.removeCallbacks(mWatchLongPress);
            mWatchLongPress = null;
        }
    }

    @Override
    public boolean onInterceptTouchEvent(final MotionEvent ev) {
        if (mCurrView instanceof ExpandableNotificationRow) {
            NotificationMenuRowPlugin nmr = ((ExpandableNotificationRow) mCurrView).getProvider();
            if (nmr != null) {
                mMenuRowIntercepting = nmr.onInterceptTouchEvent(mCurrView, ev);
            }
        }
        final int action = ev.getAction();

        switch (action) {
            case MotionEvent.ACTION_DOWN:
                mTouchAboveFalsingThreshold = false;
                mDragging = false;
                mSnappingChild = false;
                mLongPressSent = false;
                mVelocityTracker.clear();
                mCurrView = mCallback.getChildAtPosition(ev);

                if (mCurrView != null) {
                    onDownUpdate(mCurrView, ev);
                    mCanCurrViewBeDimissed = mCallback.canChildBeDismissed(mCurrView);
                    mVelocityTracker.addMovement(ev);
                    mInitialTouchPos = getPos(ev);
                    mPerpendicularInitialTouchPos = getPerpendicularPos(ev);
                    mTranslation = getTranslation(mCurrView);
                    if (mWatchLongPress == null) {
                        mWatchLongPress = new Runnable() {
                            @Override
                            public void run() {
                                if (mCurrView != null && !mLongPressSent) {
                                    mLongPressSent = true;
                                    mCurrView.getLocationOnScreen(mTmpPos);
                                    final int x = (int) ev.getRawX() - mTmpPos[0];
                                    final int y = (int) ev.getRawY() - mTmpPos[1];
                                    if (mCurrView instanceof ExpandableNotificationRow) {
                                        mCurrView.sendAccessibilityEvent(
                                                AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
                                        ExpandableNotificationRow currRow =
                                                (ExpandableNotificationRow) mCurrView;
                                        currRow.doLongClickCallback(x, y);
                                    }
                                }
                            }
                        };
                    }
                    mHandler.postDelayed(mWatchLongPress, mLongPressTimeout);
                }
                break;

            case MotionEvent.ACTION_MOVE:
                if (mCurrView != null && !mLongPressSent) {
                    mVelocityTracker.addMovement(ev);
                    float pos = getPos(ev);
                    float perpendicularPos = getPerpendicularPos(ev);
                    float delta = pos - mInitialTouchPos;
                    float deltaPerpendicular = perpendicularPos - mPerpendicularInitialTouchPos;
                    if (Math.abs(delta) > mPagingTouchSlop
                            && Math.abs(delta) > Math.abs(deltaPerpendicular)) {
                        if (mCallback.canChildBeDragged(mCurrView)) {
                            mCallback.onBeginDrag(mCurrView);
                            mDragging = true;
                            mInitialTouchPos = getPos(ev);
                            mTranslation = getTranslation(mCurrView);
                        }
                        cancelLongPress();
                    }
                }
                break;

            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                final boolean captured = (mDragging || mLongPressSent || mMenuRowIntercepting);
                mDragging = false;
                mCurrView = null;
                mLongPressSent = false;
                mMenuRowIntercepting = false;
                cancelLongPress();
                if (captured) return true;
                break;
        }
        return mDragging || mLongPressSent || mMenuRowIntercepting;
    }

    /**
     * @param view The view to be dismissed
     * @param velocity The desired pixels/second speed at which the view should move
     * @param useAccelerateInterpolator Should an accelerating Interpolator be used
     */
    public void dismissChild(final View view, float velocity, boolean useAccelerateInterpolator) {
        dismissChild(view, velocity, null /* endAction */, 0 /* delay */,
                useAccelerateInterpolator, 0 /* fixedDuration */, false /* isDismissAll */);
    }

    /**
     * @param view The view to be dismissed
     * @param velocity The desired pixels/second speed at which the view should move
     * @param endAction The action to perform at the end
     * @param delay The delay after which we should start
     * @param useAccelerateInterpolator Should an accelerating Interpolator be used
     * @param fixedDuration If not 0, this exact duration will be taken
     */
    public void dismissChild(final View animView, float velocity, final Runnable endAction,
            long delay, boolean useAccelerateInterpolator, long fixedDuration,
            boolean isDismissAll) {
        final boolean canBeDismissed = mCallback.canChildBeDismissed(animView);
        float newPos;
        boolean isLayoutRtl = animView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;

        // if we use the Menu to dismiss an item in landscape, animate up
        boolean animateUpForMenu = velocity == 0 && (getTranslation(animView) == 0 || isDismissAll)
                && mSwipeDirection == Y;
        // if the language is rtl we prefer swiping to the left
        boolean animateLeftForRtl = velocity == 0 && (getTranslation(animView) == 0 || isDismissAll)
                && isLayoutRtl;
        boolean animateLeft = (Math.abs(velocity) > getEscapeVelocity() && velocity < 0) ||
                (getTranslation(animView) < 0 && !isDismissAll);
        if (animateLeft || animateLeftForRtl || animateUpForMenu) {
            newPos = -getSize(animView);
        } else {
            newPos = getSize(animView);
        }
        long duration;
        if (fixedDuration == 0) {
            duration = MAX_ESCAPE_ANIMATION_DURATION;
            if (velocity != 0) {
                duration = Math.min(duration,
                        (int) (Math.abs(newPos - getTranslation(animView)) * 1000f / Math
                                .abs(velocity))
                );
            } else {
                duration = DEFAULT_ESCAPE_ANIMATION_DURATION;
            }
        } else {
            duration = fixedDuration;
        }

        if (!mDisableHwLayers) {
            animView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
        }
        AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                onTranslationUpdate(animView, (float) animation.getAnimatedValue(), canBeDismissed);
            }
        };

        Animator anim = getViewTranslationAnimator(animView, newPos, updateListener);
        if (anim == null) {
            return;
        }
        if (useAccelerateInterpolator) {
            anim.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
            anim.setDuration(duration);
        } else {
            mFlingAnimationUtils.applyDismissing(anim, getTranslation(animView),
                    newPos, velocity, getSize(animView));
        }
        if (delay > 0) {
            anim.setStartDelay(delay);
        }
        anim.addListener(new AnimatorListenerAdapter() {
            private boolean mCancelled;

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

            @Override
            public void onAnimationEnd(Animator animation) {
                updateSwipeProgressFromOffset(animView, canBeDismissed);
                mDismissPendingMap.remove(animView);
                boolean wasRemoved = false;
                if (animView instanceof ExpandableNotificationRow) {
                    ExpandableNotificationRow row = (ExpandableNotificationRow) animView;
                    wasRemoved = row.isRemoved();
                }
                if (!mCancelled || wasRemoved) {
                    mCallback.onChildDismissed(animView);
                }
                if (endAction != null) {
                    endAction.run();
                }
                if (!mDisableHwLayers) {
                    animView.setLayerType(View.LAYER_TYPE_NONE, null);
                }
            }
        });

        prepareDismissAnimation(animView, anim);
        mDismissPendingMap.put(animView, anim);
        anim.start();
    }

    /**
     * Called to update the dismiss animation.
     */
    protected void prepareDismissAnimation(View view, Animator anim) {
        // Do nothing
    }

    public void snapChild(final View animView, final float targetLeft, float velocity) {
        final boolean canBeDismissed = mCallback.canChildBeDismissed(animView);
        AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                onTranslationUpdate(animView, (float) animation.getAnimatedValue(), canBeDismissed);
            }
        };

        Animator anim = getViewTranslationAnimator(animView, targetLeft, updateListener);
        if (anim == null) {
            return;
        }
        anim.addListener(new AnimatorListenerAdapter() {
            boolean wasCancelled = false;

            @Override
            public void onAnimationCancel(Animator animator) {
                wasCancelled = true;
            }

            @Override
            public void onAnimationEnd(Animator animator) {
                mSnappingChild = false;
                if (!wasCancelled) {
                    updateSwipeProgressFromOffset(animView, canBeDismissed);
                    onChildSnappedBack(animView, targetLeft);
                    mCallback.onChildSnappedBack(animView, targetLeft);
                }
            }
        });
        prepareSnapBackAnimation(animView, anim);
        mSnappingChild = true;
        float maxDistance = Math.abs(targetLeft - getTranslation(animView));
        mFlingAnimationUtils.apply(anim, getTranslation(animView), targetLeft, velocity,
                maxDistance);
        anim.start();
    }

    /**
     * Give the swipe helper itself a chance to do something on snap back so NSSL doesn't have
     * to tell us what to do
     */
    protected void onChildSnappedBack(View animView, float targetLeft) {
    }

    /**
     * Called to update the snap back animation.
     */
    protected void prepareSnapBackAnimation(View view, Animator anim) {
        // Do nothing
    }

    /**
     * Called when there's a down event.
     */
    public void onDownUpdate(View currView, MotionEvent ev) {
        // Do nothing
    }

    /**
     * Called on a move event.
     */
    protected void onMoveUpdate(View view, MotionEvent ev, float totalTranslation, float delta) {
        // Do nothing
    }

    /**
     * Called in {@link AnimatorUpdateListener#onAnimationUpdate(ValueAnimator)} when the current
     * view is being animated to dismiss or snap.
     */
    public void onTranslationUpdate(View animView, float value, boolean canBeDismissed) {
        updateSwipeProgressFromOffset(animView, canBeDismissed, value);
    }

    private void snapChildInstantly(final View view) {
        final boolean canAnimViewBeDismissed = mCallback.canChildBeDismissed(view);
        setTranslation(view, 0);
        updateSwipeProgressFromOffset(view, canAnimViewBeDismissed);
    }

    /**
     * Called when a view is updated to be non-dismissable, if the view was being dismissed before
     * the update this will handle snapping it back into place.
     *
     * @param view the view to snap if necessary.
     * @param animate whether to animate the snap or not.
     * @param targetLeft the target to snap to.
     */
    public void snapChildIfNeeded(final View view, boolean animate, float targetLeft) {
        if ((mDragging && mCurrView == view) || mSnappingChild) {
            return;
        }
        boolean needToSnap = false;
        Animator dismissPendingAnim = mDismissPendingMap.get(view);
        if (dismissPendingAnim != null) {
            needToSnap = true;
            dismissPendingAnim.cancel();
        } else if (getTranslation(view) != 0) {
            needToSnap = true;
        }
        if (needToSnap) {
            if (animate) {
                snapChild(view, targetLeft, 0.0f /* velocity */);
            } else {
                snapChildInstantly(view);
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (mLongPressSent && !mMenuRowIntercepting) {
            return true;
        }

        if (!mDragging && !mMenuRowIntercepting) {
            if (mCallback.getChildAtPosition(ev) != null) {

                // We are dragging directly over a card, make sure that we also catch the gesture
                // even if nobody else wants the touch event.
                onInterceptTouchEvent(ev);
                return true;
            } else {

                // We are not doing anything, make sure the long press callback
                // is not still ticking like a bomb waiting to go off.
                cancelLongPress();
                return false;
            }
        }

        mVelocityTracker.addMovement(ev);
        final int action = ev.getAction();
        switch (action) {
            case MotionEvent.ACTION_OUTSIDE:
            case MotionEvent.ACTION_MOVE:
                if (mCurrView != null) {
                    float delta = getPos(ev) - mInitialTouchPos;
                    float absDelta = Math.abs(delta);
                    if (absDelta >= getFalsingThreshold()) {
                        mTouchAboveFalsingThreshold = true;
                    }
                    // don't let items that can't be dismissed be dragged more than
                    // maxScrollDistance
                    if (CONSTRAIN_SWIPE && !mCallback.canChildBeDismissedInDirection(mCurrView,
                            delta > 0)) {
                        float size = getSize(mCurrView);
                        float maxScrollDistance = MAX_SCROLL_SIZE_FRACTION * size;
                        if (absDelta >= size) {
                            delta = delta > 0 ? maxScrollDistance : -maxScrollDistance;
                        } else {
                            int startPosition = mCallback.getConstrainSwipeStartPosition();
                            if (absDelta > startPosition) {
                                int signedStartPosition =
                                        (int) (startPosition * Math.signum(delta));
                                delta = signedStartPosition
                                        + maxScrollDistance * (float) Math.sin(
                                        ((delta - signedStartPosition) / size) * (Math.PI / 2));
                            }
                        }
                    }

                    setTranslation(mCurrView, mTranslation + delta);
                    updateSwipeProgressFromOffset(mCurrView, mCanCurrViewBeDimissed);
                    onMoveUpdate(mCurrView, ev, mTranslation + delta, delta);
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                if (mCurrView == null) {
                    break;
                }
                mVelocityTracker.computeCurrentVelocity(1000 /* px/sec */, getMaxVelocity());
                float velocity = getVelocity(mVelocityTracker);

                if (!handleUpEvent(ev, mCurrView, velocity, getTranslation(mCurrView))) {
                    if (isDismissGesture(ev)) {
                        // flingadingy
                        dismissChild(mCurrView, velocity,
                                !swipedFastEnough() /* useAccelerateInterpolator */);
                    } else {
                        // snappity
                        mCallback.onDragCancelled(mCurrView);
                        snapChild(mCurrView, 0 /* leftTarget */, velocity);
                    }
                    mCurrView = null;
                }
                mDragging = false;
                break;
        }
        return true;
    }

    private int getFalsingThreshold() {
        float factor = mCallback.getFalsingThresholdFactor();
        return (int) (mFalsingThreshold * factor);
    }

    private float getMaxVelocity() {
        return MAX_DISMISS_VELOCITY * mDensityScale;
    }

    protected float getEscapeVelocity() {
        return getUnscaledEscapeVelocity() * mDensityScale;
    }

    protected float getUnscaledEscapeVelocity() {
        return SWIPE_ESCAPE_VELOCITY;
    }

    protected long getMaxEscapeAnimDuration() {
        return MAX_ESCAPE_ANIMATION_DURATION;
    }

    protected boolean swipedFarEnough() {
        float translation = getTranslation(mCurrView);
        return DISMISS_IF_SWIPED_FAR_ENOUGH
                && Math.abs(translation) > SWIPED_FAR_ENOUGH_SIZE_FRACTION * getSize(mCurrView);
    }

    public boolean isDismissGesture(MotionEvent ev) {
        float translation = getTranslation(mCurrView);
        return ev.getActionMasked() == MotionEvent.ACTION_UP
                && !mFalsingManager.isUnlockingDisabled()
                && !isFalseGesture(ev) && (swipedFastEnough() || swipedFarEnough())
                && mCallback.canChildBeDismissedInDirection(mCurrView, translation > 0);
    }

    public boolean isFalseGesture(MotionEvent ev) {
        boolean falsingDetected = mCallback.isAntiFalsingNeeded();
        if (mFalsingManager.isClassifierEnabled()) {
            falsingDetected = falsingDetected && mFalsingManager.isFalseTouch();
        } else {
            falsingDetected = falsingDetected && !mTouchAboveFalsingThreshold;
        }
        return falsingDetected;
    }

    protected boolean swipedFastEnough() {
        float velocity = getVelocity(mVelocityTracker);
        float translation = getTranslation(mCurrView);
        boolean ret = (Math.abs(velocity) > getEscapeVelocity())
                && (velocity > 0) == (translation > 0);
        return ret;
    }

    protected boolean handleUpEvent(MotionEvent ev, View animView, float velocity,
            float translation) {
        return false;
    }

    public interface Callback {
        View getChildAtPosition(MotionEvent ev);

        boolean canChildBeDismissed(View v);

        /**
         * Returns true if the provided child can be dismissed by a swipe in the given direction.
         *
         * @param isRightOrDown {@code true} if the swipe direction is right or down,
         *                      {@code false} if it is left or up.
         */
        default boolean canChildBeDismissedInDirection(View v, boolean isRightOrDown) {
            return canChildBeDismissed(v);
        }

        boolean isAntiFalsingNeeded();

        void onBeginDrag(View v);

        void onChildDismissed(View v);

        void onDragCancelled(View v);

        /**
         * Called when the child is snapped to a position.
         *
         * @param animView the view that was snapped.
         * @param targetLeft the left position the view was snapped to.
         */
        void onChildSnappedBack(View animView, float targetLeft);

        /**
         * Updates the swipe progress on a child.
         *
         * @return if true, prevents the default alpha fading.
         */
        boolean updateSwipeProgress(View animView, boolean dismissable, float swipeProgress);

        /**
         * @return The factor the falsing threshold should be multiplied with
         */
        float getFalsingThresholdFactor();

        /**
         * @return The position, in pixels, at which a constrained swipe should start being
         * constrained.
         */
        default int getConstrainSwipeStartPosition() {
            return 0;
        }

        /**
         * @return If true, the given view is draggable.
         */
        default boolean canChildBeDragged(@NonNull View animView) { return true; }
    }
}
