/*
 * Copyright (C) 2020 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.car.window;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.IntDef;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewTreeObserver;

import androidx.annotation.CallSuper;

import com.android.systemui.car.CarDeviceProvisionedController;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.wm.shell.animation.FlingAnimationUtils;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
 * The {@link OverlayPanelViewController} provides additional dragging animation capabilities to
 * {@link OverlayViewController}.
 */
public abstract class OverlayPanelViewController extends OverlayViewController {

    /** @hide */
    @IntDef(flag = true, prefix = { "OVERLAY_" }, value = {
            OVERLAY_FROM_TOP_BAR,
            OVERLAY_FROM_BOTTOM_BAR
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface OverlayDirection {}

    /**
     * Indicates that the overlay panel should be opened from the top bar and expanded by dragging
     * towards the bottom bar.
     */
    public static final int OVERLAY_FROM_TOP_BAR = 0;

    /**
     * Indicates that the overlay panel should be opened from the bottom bar and expanded by
     * dragging towards the top bar.
     */
    public static final int OVERLAY_FROM_BOTTOM_BAR = 1;

    private static final boolean DEBUG = false;
    private static final String TAG = "OverlayPanelViewController";

    // used to calculate how fast to open or close the window
    protected static final float DEFAULT_FLING_VELOCITY = 0;
    // max time a fling animation takes
    protected static final float FLING_ANIMATION_MAX_TIME = 0.5f;
    // acceleration rate for the fling animation
    protected static final float FLING_SPEED_UP_FACTOR = 0.6f;

    protected static final int SWIPE_DOWN_MIN_DISTANCE = 25;
    protected static final int SWIPE_MAX_OFF_PATH = 75;
    protected static final int SWIPE_THRESHOLD_VELOCITY = 200;
    private static final int POSITIVE_DIRECTION = 1;
    private static final int NEGATIVE_DIRECTION = -1;

    private final Context mContext;
    private final int mScreenHeightPx;
    private final FlingAnimationUtils mFlingAnimationUtils;
    private final CarDeviceProvisionedController mCarDeviceProvisionedController;
    private final View.OnTouchListener mDragOpenTouchListener;
    private final View.OnTouchListener mDragCloseTouchListener;

    protected int mAnimateDirection = POSITIVE_DIRECTION;

    private int mSettleClosePercentage;
    private int mPercentageFromEndingEdge;
    private int mPercentageCursorPositionOnScreen;

    private boolean mPanelVisible;
    private boolean mPanelExpanded;

    private float mOpeningVelocity = DEFAULT_FLING_VELOCITY;
    private float mClosingVelocity = DEFAULT_FLING_VELOCITY;

    private boolean mIsAnimating;
    private boolean mIsTracking;

    public OverlayPanelViewController(
            Context context,
            @Main Resources resources,
            int stubId,
            OverlayViewGlobalStateController overlayViewGlobalStateController,
            FlingAnimationUtils.Builder flingAnimationUtilsBuilder,
            CarDeviceProvisionedController carDeviceProvisionedController
    ) {
        super(stubId, overlayViewGlobalStateController);

        mContext = context;
        mScreenHeightPx = Resources.getSystem().getDisplayMetrics().heightPixels;
        mFlingAnimationUtils = flingAnimationUtilsBuilder
                .setMaxLengthSeconds(FLING_ANIMATION_MAX_TIME)
                .setSpeedUpFactor(FLING_SPEED_UP_FACTOR)
                .build();
        mCarDeviceProvisionedController = carDeviceProvisionedController;

        // Attached to a navigation bar to open the overlay panel
        GestureDetector openGestureDetector = new GestureDetector(context,
                new OpenGestureListener() {
                    @Override
                    protected void open() {
                        animateExpandPanel();
                    }
                });

        // Attached to the other navigation bars to close the overlay panel
        GestureDetector closeGestureDetector = new GestureDetector(context,
                new SystemBarCloseGestureListener() {
                    @Override
                    protected void close() {
                        if (isPanelExpanded()) {
                            animateCollapsePanel();
                        }
                    }
                });

        mDragOpenTouchListener = (v, event) -> {
            if (!mCarDeviceProvisionedController.isCurrentUserFullySetup()) {
                return true;
            }
            if (!isInflated()) {
                getOverlayViewGlobalStateController().inflateView(this);
            }

            boolean consumed = openGestureDetector.onTouchEvent(event);
            if (consumed) {
                return true;
            }
            maybeCompleteAnimation(event);
            return true;
        };

        mDragCloseTouchListener = (v, event) -> {
            if (!isInflated()) {
                return true;
            }
            boolean consumed = closeGestureDetector.onTouchEvent(event);
            if (consumed) {
                return true;
            }
            maybeCompleteAnimation(event);
            return true;
        };
    }

    @Override
    protected void onFinishInflate() {
        setUpHandleBar();
    }

    /** Sets the overlay panel animation direction along the x or y axis. */
    public void setOverlayDirection(@OverlayDirection int direction) {
        if (direction == OVERLAY_FROM_TOP_BAR) {
            mAnimateDirection = POSITIVE_DIRECTION;
        } else if (direction == OVERLAY_FROM_BOTTOM_BAR) {
            mAnimateDirection = NEGATIVE_DIRECTION;
        } else {
            throw new IllegalArgumentException("Direction not supported");
        }
    }

    /** Toggles the visibility of the panel. */
    public void toggle() {
        if (!isInflated()) {
            getOverlayViewGlobalStateController().inflateView(this);
        }
        if (isPanelExpanded()) {
            animateCollapsePanel();
        } else {
            animateExpandPanel();
        }
    }

    /** Checks if a {@link MotionEvent} is an action to open the panel.
     * @param e {@link MotionEvent} to check.
     * @return true only if opening action.
     */
    protected boolean isOpeningAction(MotionEvent e) {
        if (mAnimateDirection == POSITIVE_DIRECTION) {
            return e.getActionMasked() == MotionEvent.ACTION_DOWN;
        }

        if (mAnimateDirection == NEGATIVE_DIRECTION) {
            return e.getActionMasked() == MotionEvent.ACTION_UP;
        }

        return false;
    }

    /** Checks if a {@link MotionEvent} is an action to close the panel.
     * @param e {@link MotionEvent} to check.
     * @return true only if closing action.
     */
    protected boolean isClosingAction(MotionEvent e) {
        if (mAnimateDirection == POSITIVE_DIRECTION) {
            return e.getActionMasked() == MotionEvent.ACTION_UP;
        }

        if (mAnimateDirection == NEGATIVE_DIRECTION) {
            return e.getActionMasked() == MotionEvent.ACTION_DOWN;
        }

        return false;
    }

    /* ***************************************************************************************** *
     * Panel Animation
     * ***************************************************************************************** */

    /** Animates the closing of the panel. */
    protected void animateCollapsePanel() {
        if (!shouldAnimateCollapsePanel()) {
            return;
        }

        if (!isPanelExpanded() || !isPanelVisible()) {
            return;
        }

        onAnimateCollapsePanel();
        animatePanel(mClosingVelocity, /* isClosing= */ true);
    }

    /** Determines whether {@link #animateCollapsePanel()} should collapse the panel. */
    protected abstract boolean shouldAnimateCollapsePanel();

    /** Called when the panel is beginning to collapse. */
    protected abstract void onAnimateCollapsePanel();

    /** Animates the expansion of the panel. */
    protected void animateExpandPanel() {
        if (!shouldAnimateExpandPanel()) {
            return;
        }

        if (!mCarDeviceProvisionedController.isCurrentUserFullySetup()) {
            return;
        }

        onAnimateExpandPanel();
        setPanelVisible(true);
        animatePanel(mOpeningVelocity, /* isClosing= */ false);

        setPanelExpanded(true);
    }

    /** Determines whether {@link #animateExpandPanel()}} should expand the panel. */
    protected abstract boolean shouldAnimateExpandPanel();

    /** Called when the panel is beginning to expand. */
    protected abstract void onAnimateExpandPanel();

    /** Returns the percentage at which we've determined whether to open or close the panel. */
    protected abstract int getSettleClosePercentage();

    /**
     * Depending on certain conditions, determines whether to fully expand or collapse the panel.
     */
    protected void maybeCompleteAnimation(MotionEvent event) {
        if (isPanelVisible()) {
            if (mSettleClosePercentage == 0) {
                mSettleClosePercentage = getSettleClosePercentage();
            }

            boolean closePanel = mAnimateDirection == POSITIVE_DIRECTION
                    ? mSettleClosePercentage > mPercentageCursorPositionOnScreen
                    : mSettleClosePercentage < mPercentageCursorPositionOnScreen;
            animatePanel(DEFAULT_FLING_VELOCITY, closePanel);
        }
    }

    /**
     * Animates the panel from one position to other. This is used to either open or
     * close the panel completely with a velocity. If the animation is to close the
     * panel this method also makes the view invisible after animation ends.
     */
    protected void animatePanel(float velocity, boolean isClosing) {
        float to = getEndPosition(isClosing);

        Rect rect = getLayout().getClipBounds();
        if (rect != null) {
            float from = getCurrentStartPosition(rect);
            if (from != to) {
                animate(from, to, velocity, isClosing);
            } else if (isClosing) {
                resetPanelVisibility();
            }

            // If we swipe down the notification panel all the way to the bottom of the screen
            // (i.e. from == to), then we have finished animating the panel.
            return;
        }

        // We will only be here if the shade is being opened programmatically or via button when
        // height of the layout was not calculated.
        ViewTreeObserver panelTreeObserver = getLayout().getViewTreeObserver();
        panelTreeObserver.addOnGlobalLayoutListener(
                new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        ViewTreeObserver obs = getLayout().getViewTreeObserver();
                        obs.removeOnGlobalLayoutListener(this);
                        animate(
                                getDefaultStartPosition(),
                                getEndPosition(/* isClosing= */ false),
                                velocity,
                                isClosing
                        );
                    }
                });
    }

    /* Returns the start position if the user has not started swiping. */
    private int getDefaultStartPosition() {
        return mAnimateDirection > 0 ? 0 : getLayout().getHeight();
    }

    /** Returns the start position if we are in the middle of swiping. */
    private int getCurrentStartPosition(Rect clipBounds) {
        return mAnimateDirection > 0 ? clipBounds.bottom : clipBounds.top;
    }

    private int getEndPosition(boolean isClosing) {
        return (mAnimateDirection > 0 && !isClosing) || (mAnimateDirection == -1 && isClosing)
                ? getLayout().getHeight()
                : 0;
    }

    private void animate(float from, float to, float velocity, boolean isClosing) {
        if (mIsAnimating) {
            return;
        }
        mIsAnimating = true;
        mIsTracking = true;
        ValueAnimator animator = ValueAnimator.ofFloat(from, to);
        animator.addUpdateListener(
                animation -> {
                    float animatedValue = (Float) animation.getAnimatedValue();
                    setViewClipBounds((int) animatedValue);
                });
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                mIsAnimating = false;
                mIsTracking = false;
                mOpeningVelocity = DEFAULT_FLING_VELOCITY;
                mClosingVelocity = DEFAULT_FLING_VELOCITY;
                if (isClosing) {
                    resetPanelVisibility();
                } else {
                    onExpandAnimationEnd();
                    setPanelExpanded(true);
                }
            }
        });
        getFlingAnimationUtils().apply(animator, from, to, Math.abs(velocity));
        animator.start();
    }

    private void resetPanelVisibility() {
        setPanelVisible(false);
        getLayout().setClipBounds(null);
        onCollapseAnimationEnd();
        setPanelExpanded(false);
    }

    /**
     * Called in {@link Animator.AnimatorListener#onAnimationEnd(Animator)} when the panel is
     * closing.
     */
    protected abstract void onCollapseAnimationEnd();

    /**
     * Called in {@link Animator.AnimatorListener#onAnimationEnd(Animator)} when the panel is
     * opening.
     */
    protected abstract void onExpandAnimationEnd();

    /* ***************************************************************************************** *
     * Panel Visibility
     * ***************************************************************************************** */

    /** Set the panel view to be visible. */
    protected final void setPanelVisible(boolean visible) {
        mPanelVisible = visible;
        onPanelVisible(visible);
    }

    /** Returns {@code true} if panel is visible. */
    public final boolean isPanelVisible() {
        return mPanelVisible;
    }

    /** Business logic run when panel visibility is set. */
    @CallSuper
    protected void onPanelVisible(boolean visible) {
        if (DEBUG) {
            Log.e(TAG, "onPanelVisible: " + visible);
        }

        if (visible && !getOverlayViewGlobalStateController().isWindowVisible()) {
            getOverlayViewGlobalStateController().showView(/* panelViewController= */ this);
        }
        if (!visible && getOverlayViewGlobalStateController().isWindowVisible()) {
            getOverlayViewGlobalStateController().hideView(/* panelViewController= */ this);
        }
        getLayout().setVisibility(visible ? View.VISIBLE : View.INVISIBLE);

        // TODO(b/202890142): Unify OverlayPanelViewController with super class show and hide
        for (OverlayViewStateListener l : mViewStateListeners) {
            l.onVisibilityChanged(visible);
        }
    }

    /* ***************************************************************************************** *
     * Panel Expansion
     * ***************************************************************************************** */

    /**
     * Set the panel state to expanded. This will expand or collapse the overlay window if
     * necessary.
     */
    protected final void setPanelExpanded(boolean expand) {
        mPanelExpanded = expand;
        onPanelExpanded(expand);
    }

    /** Returns {@code true} if panel is expanded. */
    public final boolean isPanelExpanded() {
        return mPanelExpanded;
    }

    @CallSuper
    protected void onPanelExpanded(boolean expand) {
        if (DEBUG) {
            Log.e(TAG, "onPanelExpanded: " + expand);
        }
    }

    /* ***************************************************************************************** *
     * Misc
     * ***************************************************************************************** */

    /**
     * Given the position of the pointer dragging the panel, return the percentage of its closeness
     * to the ending edge.
     */
    protected void calculatePercentageFromEndingEdge(float y) {
        if (getLayout().getHeight() > 0) {
            float height = getVisiblePanelHeight(y);
            mPercentageFromEndingEdge = (int) Math.abs(height / getLayout().getHeight() * 100);
        }
    }

    /**
     * Given the position of the pointer dragging the panel, update its vertical position in terms
     * of the percentage of the total height of the screen.
     */
    protected void calculatePercentageCursorPositionOnScreen(float y) {
        mPercentageCursorPositionOnScreen = Math.round(Math.abs(y / mScreenHeightPx * 100));
    }

    private float getVisiblePanelHeight(float y) {
        return mAnimateDirection > 0 ? y : getLayout().getHeight() - y;
    }

    /** Sets the boundaries of the overlay panel that can be seen based on pointer position. */
    protected void setViewClipBounds(int y) {
        // Bound the pointer position to be within the overlay panel.
        y = Math.max(0, Math.min(y, getLayout().getHeight()));
        Rect clipBounds = new Rect();
        int top, bottom;
        if (mAnimateDirection > 0) {
            top = 0;
            bottom = y;
        } else {
            top = y;
            bottom = getLayout().getHeight();
        }
        clipBounds.set(0, top, getLayout().getWidth(), bottom);
        getLayout().setClipBounds(clipBounds);
        onScroll(y);
    }

    /**
     * Called while scrolling, this passes the position of the clip boundary that is currently
     * changing.
     */
    protected void onScroll(int y) {
        if (getHandleBarViewId() == null) return;
        View handleBar = getLayout().findViewById(getHandleBarViewId());
        if (handleBar == null) return;

        handleBar.setTranslationY(y);
    }

    /* ***************************************************************************************** *
     * Getters
     * ***************************************************************************************** */

    /** Returns the open touch listener. */
    public final View.OnTouchListener getDragOpenTouchListener() {
        return mDragOpenTouchListener;
    }

    /** Returns the close touch listener. */
    public final View.OnTouchListener getDragCloseTouchListener() {
        return mDragCloseTouchListener;
    }

    /** Gets the fling animation utils used for animating this panel. */
    protected final FlingAnimationUtils getFlingAnimationUtils() {
        return mFlingAnimationUtils;
    }

    /** Returns {@code true} if the panel is currently tracking. */
    protected final boolean isTracking() {
        return mIsTracking;
    }

    /** Sets whether the panel is currently tracking or not. */
    protected final void setIsTracking(boolean isTracking) {
        mIsTracking = isTracking;
    }

    /** Returns {@code true} if the panel is currently animating. */
    protected final boolean isAnimating() {
        return mIsAnimating;
    }

    /** Returns the percentage of the panel that is open from the bottom. */
    protected final int getPercentageFromEndingEdge() {
        return mPercentageFromEndingEdge;
    }

    /* ***************************************************************************************** *
     * Gesture Listeners
     * ***************************************************************************************** */

    /** Called when the user is beginning to scroll down the panel. */
    protected abstract void onOpenScrollStart();

    /**
     * Only responsible for open hooks. Since once the panel opens it covers all elements
     * there is no need to merge with close.
     */
    protected abstract class OpenGestureListener extends
            GestureDetector.SimpleOnGestureListener {

        @Override
        public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX,
                float distanceY) {

            if (!isPanelVisible()) {
                onOpenScrollStart();
            }
            setPanelVisible(true);

            // clips the view for the panel when the user scrolls to open.
            setViewClipBounds((int) event2.getRawY());

            // Initially the scroll starts with height being zero. This checks protects from divide
            // by zero error.
            calculatePercentageFromEndingEdge(event2.getRawY());
            calculatePercentageCursorPositionOnScreen(event2.getRawY());

            mIsTracking = true;
            return true;
        }


        @Override
        public boolean onFling(MotionEvent event1, MotionEvent event2,
                float velocityX, float velocityY) {
            if (mAnimateDirection * velocityY > SWIPE_THRESHOLD_VELOCITY) {
                mOpeningVelocity = velocityY;
                open();
                return true;
            }
            animatePanel(DEFAULT_FLING_VELOCITY, true);

            return false;
        }

        protected abstract void open();
    }

    /** Determines whether the scroll event should allow closing of the panel. */
    protected abstract boolean shouldAllowClosingScroll();

    protected abstract class CloseGestureListener extends
            GestureDetector.SimpleOnGestureListener {

        @Override
        public boolean onSingleTapUp(MotionEvent motionEvent) {
            if (isPanelExpanded()) {
                animatePanel(DEFAULT_FLING_VELOCITY, true);
            }
            return true;
        }

        @Override
        public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX,
                float distanceY) {
            if (!shouldAllowClosingScroll()) {
                return false;
            }
            float y = getYPositionOfPanelEndingEdge(event1, event2);
            if (getLayout().getHeight() > 0) {
                mPercentageFromEndingEdge = (int) Math.abs(
                        y / getLayout().getHeight() * 100);
                mPercentageCursorPositionOnScreen = (int) Math.abs(y / mScreenHeightPx * 100);
                boolean isInClosingDirection = mAnimateDirection * distanceY > 0;

                // This check is to figure out if onScroll was called while swiping the card at
                // bottom of the panel. At that time we should not allow panel to
                // close. We are also checking for the upwards swipe gesture here because it is
                // possible if a user is closing the panel and while swiping starts
                // to open again but does not fling. At that time we should allow the
                // panel to close fully or else it would stuck in between.
                if (Math.abs(getLayout().getHeight() - y)
                        > SWIPE_DOWN_MIN_DISTANCE && isInClosingDirection) {
                    setViewClipBounds((int) y);
                    mIsTracking = true;
                } else if (!isInClosingDirection) {
                    setViewClipBounds((int) y);
                }
            }
            // if we return true the items in RV won't be scrollable.
            return false;
        }

        /**
         * To prevent the jump in the clip bounds while closing the panel we should calculate the y
         * position using the diff of event1 and event2. This will help the panel clip smoothly as
         * the event2 value changes while event1 value will be fixed.
         * @param event1 MotionEvent that contains the position of where the event2 started.
         * @param event2 MotionEvent that contains the position of where the user has scrolled to
         *               on the screen.
         */
        private float getYPositionOfPanelEndingEdge(MotionEvent event1, MotionEvent event2) {
            float diff = mAnimateDirection * (event1.getRawY() - event2.getRawY());
            float y = mAnimateDirection > 0 ? getLayout().getHeight() - diff : diff;
            y = Math.max(0, Math.min(y, getLayout().getHeight()));
            return y;
        }

        @Override
        public boolean onFling(MotionEvent event1, MotionEvent event2,
                float velocityX, float velocityY) {
            // should not fling if the touch does not start when view is at the end of the list.
            if (!shouldAllowClosingScroll()) {
                return false;
            }
            if (Math.abs(event1.getX() - event2.getX()) > SWIPE_MAX_OFF_PATH
                    || Math.abs(velocityY) < SWIPE_THRESHOLD_VELOCITY) {
                // swipe was not vertical or was not fast enough
                return false;
            }
            boolean isInClosingDirection = mAnimateDirection * velocityY < 0;
            if (isInClosingDirection) {
                close();
                return true;
            } else {
                // we should close the shade
                animatePanel(velocityY, false);
            }
            return false;
        }

        protected abstract void close();
    }

    protected abstract class SystemBarCloseGestureListener extends CloseGestureListener {
        @Override
        public boolean onSingleTapUp(MotionEvent e) {
            mClosingVelocity = DEFAULT_FLING_VELOCITY;
            if (isPanelExpanded()) {
                close();
            }
            return super.onSingleTapUp(e);
        }

        @Override
        public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX,
                float distanceY) {
            calculatePercentageFromEndingEdge(event2.getRawY());
            calculatePercentageCursorPositionOnScreen(event2.getRawY());
            setViewClipBounds((int) event2.getRawY());
            return true;
        }
    }

    /**
     * Optionally returns the ID of the handle bar view which enables dragging the panel to close
     * it. Return null if no handle bar is to be set up.
     */
    protected Integer getHandleBarViewId() {
        return null;
    };

    protected void setUpHandleBar() {
        Integer handleBarViewId = getHandleBarViewId();
        if (handleBarViewId == null) return;
        View handleBar = getLayout().findViewById(handleBarViewId);
        if (handleBar == null) return;
        GestureDetector handleBarCloseGestureDetector =
                new GestureDetector(mContext, new HandleBarCloseGestureListener());
        handleBar.setOnTouchListener((v, event) -> {
            int action = event.getAction();
            switch (action & MotionEvent.ACTION_MASK) {
                case MotionEvent.ACTION_UP:
                    maybeCompleteAnimation(event);
                    // Intentionally not breaking here, since handleBarClosureGestureDetector's
                    // onTouchEvent should still be called with MotionEvent.ACTION_UP.
                default:
                    handleBarCloseGestureDetector.onTouchEvent(event);
                    return true;
            }
        });
    }

    /**
     * A GestureListener to be installed on the handle bar.
     */
    private class HandleBarCloseGestureListener extends GestureDetector.SimpleOnGestureListener {

        @Override
        public boolean onScroll(MotionEvent event1, MotionEvent event2, float distanceX,
                float distanceY) {
            calculatePercentageFromEndingEdge(event2.getRawY());
            calculatePercentageCursorPositionOnScreen(event2.getRawY());
            // To prevent the jump in the clip bounds while closing the notification panel using
            // the handle bar, we should calculate the height using the diff of event1 and event2.
            // This will help the notification shade to clip smoothly as the event2 value changes
            // as event1 value will be fixed.
            float diff = mAnimateDirection * (event1.getRawY() - event2.getRawY());
            float y = mAnimateDirection > 0
                    ? getLayout().getHeight() - diff
                    : diff;
            // Ensure the position is within the overlay panel.
            y = Math.max(0, Math.min(y, getLayout().getHeight()));
            setViewClipBounds((int) y);
            return true;
        }
    }
}
