/*
 * Copyright (C) 2008 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 android.widget;

import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.annotation.StyleRes;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.SystemClock;
import android.text.TextUtils;
import android.text.TextUtils.TruncateAt;
import android.util.IntProperty;
import android.util.MathUtils;
import android.util.Property;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.PointerIcon;
import android.view.View;
import android.view.View.MeasureSpec;
import android.view.ViewConfiguration;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewGroupOverlay;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ImageView.ScaleType;

import com.android.internal.R;

/**
 * Helper class for AbsListView to draw and control the Fast Scroll thumb
 */
class FastScroller {
    /** Duration of fade-out animation. */
    private static final int DURATION_FADE_OUT = 300;

    /** Duration of fade-in animation. */
    private static final int DURATION_FADE_IN = 150;

    /** Duration of transition cross-fade animation. */
    private static final int DURATION_CROSS_FADE = 50;

    /** Duration of transition resize animation. */
    private static final int DURATION_RESIZE = 100;

    /** Inactivity timeout before fading controls. */
    private static final long FADE_TIMEOUT = 1500;

    /** Minimum number of pages to justify showing a fast scroll thumb. */
    private static final int MIN_PAGES = 4;

    /** Scroll thumb and preview not showing. */
    private static final int STATE_NONE = 0;

    /** Scroll thumb visible and moving along with the scrollbar. */
    private static final int STATE_VISIBLE = 1;

    /** Scroll thumb and preview being dragged by user. */
    private static final int STATE_DRAGGING = 2;

    // Positions for preview image and text.
    private static final int OVERLAY_FLOATING = 0;
    private static final int OVERLAY_AT_THUMB = 1;
    private static final int OVERLAY_ABOVE_THUMB = 2;

    // Positions for thumb in relation to track.
    private static final int THUMB_POSITION_MIDPOINT = 0;
    private static final int THUMB_POSITION_INSIDE = 1;

    // Indices for mPreviewResId.
    private static final int PREVIEW_LEFT = 0;
    private static final int PREVIEW_RIGHT = 1;

    /** Delay before considering a tap in the thumb area to be a drag. */
    private static final long TAP_TIMEOUT = ViewConfiguration.getTapTimeout();

    private final Rect mTempBounds = new Rect();
    private final Rect mTempMargins = new Rect();
    @UnsupportedAppUsage
    private final Rect mContainerRect = new Rect();

    private final AbsListView mList;
    private final ViewGroupOverlay mOverlay;
    private final TextView mPrimaryText;
    private final TextView mSecondaryText;
    @UnsupportedAppUsage
    private final ImageView mThumbImage;
    @UnsupportedAppUsage
    private final ImageView mTrackImage;
    private final View mPreviewImage;
    /**
     * Preview image resource IDs for left- and right-aligned layouts. See
     * {@link #PREVIEW_LEFT} and {@link #PREVIEW_RIGHT}.
     */
    private final int[] mPreviewResId = new int[2];

    /** The minimum touch target size in pixels. */
    @UnsupportedAppUsage
    private final int mMinimumTouchTarget;

    /**
     * Padding in pixels around the preview text. Applied as layout margins to
     * the preview text and padding to the preview image.
     */
    private int mPreviewPadding;

    private int mPreviewMinWidth;
    private int mPreviewMinHeight;
    private int mThumbMinWidth;
    private int mThumbMinHeight;

    /** Theme-specified text size. Used only if text appearance is not set. */
    private float mTextSize;

    /** Theme-specified text color. Used only if text appearance is not set. */
    private ColorStateList mTextColor;

    @UnsupportedAppUsage
    private Drawable mThumbDrawable;
    @UnsupportedAppUsage
    private Drawable mTrackDrawable;
    private int mTextAppearance;
    private int mThumbPosition;

    // Used to convert between y-coordinate and thumb position within track.
    private float mThumbOffset;
    private float mThumbRange;

    /** Total width of decorations. */
    private int mWidth;

    /** Set containing decoration transition animations. */
    private AnimatorSet mDecorAnimation;

    /** Set containing preview text transition animations. */
    private AnimatorSet mPreviewAnimation;

    /** Whether the primary text is showing. */
    private boolean mShowingPrimary;

    /** Whether we're waiting for completion of scrollTo(). */
    private boolean mScrollCompleted;

    /** The position of the first visible item in the list. */
    private int mFirstVisibleItem;

    /** The number of headers at the top of the view. */
    @UnsupportedAppUsage
    private int mHeaderCount;

    /** The index of the current section. */
    private int mCurrentSection = -1;

    /** The current scrollbar position. */
    private int mScrollbarPosition = -1;

    /** Whether the list is long enough to need a fast scroller. */
    @UnsupportedAppUsage
    private boolean mLongList;

    private Object[] mSections;

    /** Whether this view is currently performing layout. */
    private boolean mUpdatingLayout;

    /**
     * Current decoration state, one of:
     * <ul>
     * <li>{@link #STATE_NONE}, nothing visible
     * <li>{@link #STATE_VISIBLE}, showing track and thumb
     * <li>{@link #STATE_DRAGGING}, visible and showing preview
     * </ul>
     */
    private int mState;

    /** Whether the preview image is visible. */
    private boolean mShowingPreview;

    private Adapter mListAdapter;
    private SectionIndexer mSectionIndexer;

    /** Whether decorations should be laid out from right to left. */
    private boolean mLayoutFromRight;

    /** Whether the fast scroller is enabled. */
    private boolean mEnabled;

    /** Whether the scrollbar and decorations should always be shown. */
    private boolean mAlwaysShow;

    /**
     * Position for the preview image and text. One of:
     * <ul>
     * <li>{@link #OVERLAY_FLOATING}
     * <li>{@link #OVERLAY_AT_THUMB}
     * <li>{@link #OVERLAY_ABOVE_THUMB}
     * </ul>
     */
    private int mOverlayPosition;

    /** Current scrollbar style, including inset and overlay properties. */
    private int mScrollBarStyle;

    /** Whether to precisely match the thumb position to the list. */
    private boolean mMatchDragPosition;

    private float mInitialTouchY;
    private long mPendingDrag = -1;
    private int mScaledTouchSlop;

    private int mOldItemCount;
    private int mOldChildCount;

    /**
     * Used to delay hiding fast scroll decorations.
     */
    private final Runnable mDeferHide = new Runnable() {
        @Override
        public void run() {
            setState(STATE_NONE);
        }
    };

    /**
     * Used to effect a transition from primary to secondary text.
     */
    private final AnimatorListener mSwitchPrimaryListener = new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            mShowingPrimary = !mShowingPrimary;
        }
    };

    @UnsupportedAppUsage
    public FastScroller(AbsListView listView, int styleResId) {
        mList = listView;
        mOldItemCount = listView.getCount();
        mOldChildCount = listView.getChildCount();

        final Context context = listView.getContext();
        mScaledTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
        mScrollBarStyle = listView.getScrollBarStyle();

        mScrollCompleted = true;
        mState = STATE_VISIBLE;
        mMatchDragPosition =
                context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB;

        mTrackImage = new ImageView(context);
        mTrackImage.setScaleType(ScaleType.FIT_XY);
        mThumbImage = new ImageView(context);
        mThumbImage.setScaleType(ScaleType.FIT_XY);
        mPreviewImage = new View(context);
        mPreviewImage.setAlpha(0f);

        mPrimaryText = createPreviewTextView(context);
        mSecondaryText = createPreviewTextView(context);

        mMinimumTouchTarget = listView.getResources().getDimensionPixelSize(
                com.android.internal.R.dimen.fast_scroller_minimum_touch_target);

        setStyle(styleResId);

        final ViewGroupOverlay overlay = listView.getOverlay();
        mOverlay = overlay;
        overlay.add(mTrackImage);
        overlay.add(mThumbImage);
        overlay.add(mPreviewImage);
        overlay.add(mPrimaryText);
        overlay.add(mSecondaryText);

        getSectionsFromIndexer();
        updateLongList(mOldChildCount, mOldItemCount);
        setScrollbarPosition(listView.getVerticalScrollbarPosition());
        postAutoHide();
    }

    private void updateAppearance() {
        int width = 0;

        // Add track to overlay if it has an image.
        mTrackImage.setImageDrawable(mTrackDrawable);
        if (mTrackDrawable != null) {
            width = Math.max(width, mTrackDrawable.getIntrinsicWidth());
        }

        // Add thumb to overlay if it has an image.
        mThumbImage.setImageDrawable(mThumbDrawable);
        mThumbImage.setMinimumWidth(mThumbMinWidth);
        mThumbImage.setMinimumHeight(mThumbMinHeight);
        if (mThumbDrawable != null) {
            width = Math.max(width, mThumbDrawable.getIntrinsicWidth());
        }

        // Account for minimum thumb width.
        mWidth = Math.max(width, mThumbMinWidth);

        if (mTextAppearance != 0) {
            mPrimaryText.setTextAppearance(mTextAppearance);
            mSecondaryText.setTextAppearance(mTextAppearance);
        }

        if (mTextColor != null) {
            mPrimaryText.setTextColor(mTextColor);
            mSecondaryText.setTextColor(mTextColor);
        }

        if (mTextSize > 0) {
            mPrimaryText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);
            mSecondaryText.setTextSize(TypedValue.COMPLEX_UNIT_PX, mTextSize);
        }

        final int padding = mPreviewPadding;
        mPrimaryText.setIncludeFontPadding(false);
        mPrimaryText.setPadding(padding, padding, padding, padding);
        mSecondaryText.setIncludeFontPadding(false);
        mSecondaryText.setPadding(padding, padding, padding, padding);

        refreshDrawablePressedState();
    }

    public void setStyle(@StyleRes int resId) {
        final Context context = mList.getContext();
        final TypedArray ta = context.obtainStyledAttributes(null,
                R.styleable.FastScroll, R.attr.fastScrollStyle, resId);
        final int N = ta.getIndexCount();
        for (int i = 0; i < N; i++) {
            final int index = ta.getIndex(i);
            switch (index) {
                case R.styleable.FastScroll_position:
                    mOverlayPosition = ta.getInt(index, OVERLAY_FLOATING);
                    break;
                case R.styleable.FastScroll_backgroundLeft:
                    mPreviewResId[PREVIEW_LEFT] = ta.getResourceId(index, 0);
                    break;
                case R.styleable.FastScroll_backgroundRight:
                    mPreviewResId[PREVIEW_RIGHT] = ta.getResourceId(index, 0);
                    break;
                case R.styleable.FastScroll_thumbDrawable:
                    mThumbDrawable = ta.getDrawable(index);
                    break;
                case R.styleable.FastScroll_trackDrawable:
                    mTrackDrawable = ta.getDrawable(index);
                    break;
                case R.styleable.FastScroll_textAppearance:
                    mTextAppearance = ta.getResourceId(index, 0);
                    break;
                case R.styleable.FastScroll_textColor:
                    mTextColor = ta.getColorStateList(index);
                    break;
                case R.styleable.FastScroll_textSize:
                    mTextSize = ta.getDimensionPixelSize(index, 0);
                    break;
                case R.styleable.FastScroll_minWidth:
                    mPreviewMinWidth = ta.getDimensionPixelSize(index, 0);
                    break;
                case R.styleable.FastScroll_minHeight:
                    mPreviewMinHeight = ta.getDimensionPixelSize(index, 0);
                    break;
                case R.styleable.FastScroll_thumbMinWidth:
                    mThumbMinWidth = ta.getDimensionPixelSize(index, 0);
                    break;
                case R.styleable.FastScroll_thumbMinHeight:
                    mThumbMinHeight = ta.getDimensionPixelSize(index, 0);
                    break;
                case R.styleable.FastScroll_padding:
                    mPreviewPadding = ta.getDimensionPixelSize(index, 0);
                    break;
                case R.styleable.FastScroll_thumbPosition:
                    mThumbPosition = ta.getInt(index, THUMB_POSITION_MIDPOINT);
                    break;
            }
        }
        ta.recycle();

        updateAppearance();
    }

    /**
     * Removes this FastScroller overlay from the host view.
     */
    @UnsupportedAppUsage
    public void remove() {
        mOverlay.remove(mTrackImage);
        mOverlay.remove(mThumbImage);
        mOverlay.remove(mPreviewImage);
        mOverlay.remove(mPrimaryText);
        mOverlay.remove(mSecondaryText);
    }

    /**
     * @param enabled Whether the fast scroll thumb is enabled.
     */
    public void setEnabled(boolean enabled) {
        if (mEnabled != enabled) {
            mEnabled = enabled;

            onStateDependencyChanged(true);
        }
    }

    /**
     * @return Whether the fast scroll thumb is enabled.
     */
    public boolean isEnabled() {
        return mEnabled && (mLongList || mAlwaysShow);
    }

    /**
     * @param alwaysShow Whether the fast scroll thumb should always be shown
     */
    public void setAlwaysShow(boolean alwaysShow) {
        if (mAlwaysShow != alwaysShow) {
            mAlwaysShow = alwaysShow;

            onStateDependencyChanged(false);
        }
    }

    /**
     * @return Whether the fast scroll thumb will always be shown
     * @see #setAlwaysShow(boolean)
     */
    public boolean isAlwaysShowEnabled() {
        return mAlwaysShow;
    }

    /**
     * Called when one of the variables affecting enabled state changes.
     *
     * @param peekIfEnabled whether the thumb should peek, if enabled
     */
    private void onStateDependencyChanged(boolean peekIfEnabled) {
        if (isEnabled()) {
            if (isAlwaysShowEnabled()) {
                setState(STATE_VISIBLE);
            } else if (mState == STATE_VISIBLE) {
                postAutoHide();
            } else if (peekIfEnabled) {
                setState(STATE_VISIBLE);
                postAutoHide();
            }
        } else {
            stop();
        }

        mList.resolvePadding();
    }

    public void setScrollBarStyle(int style) {
        if (mScrollBarStyle != style) {
            mScrollBarStyle = style;

            updateLayout();
        }
    }

    /**
     * Immediately transitions the fast scroller decorations to a hidden state.
     */
    public void stop() {
        setState(STATE_NONE);
    }

    public void setScrollbarPosition(int position) {
        if (position == View.SCROLLBAR_POSITION_DEFAULT) {
            position = mList.isLayoutRtl() ?
                    View.SCROLLBAR_POSITION_LEFT : View.SCROLLBAR_POSITION_RIGHT;
        }

        if (mScrollbarPosition != position) {
            mScrollbarPosition = position;
            mLayoutFromRight = position != View.SCROLLBAR_POSITION_LEFT;

            final int previewResId = mPreviewResId[mLayoutFromRight ? PREVIEW_RIGHT : PREVIEW_LEFT];
            mPreviewImage.setBackgroundResource(previewResId);

            // Propagate padding to text min width/height.
            final int textMinWidth = Math.max(0, mPreviewMinWidth - mPreviewImage.getPaddingLeft()
                    - mPreviewImage.getPaddingRight());
            mPrimaryText.setMinimumWidth(textMinWidth);
            mSecondaryText.setMinimumWidth(textMinWidth);

            final int textMinHeight = Math.max(0, mPreviewMinHeight - mPreviewImage.getPaddingTop()
                    - mPreviewImage.getPaddingBottom());
            mPrimaryText.setMinimumHeight(textMinHeight);
            mSecondaryText.setMinimumHeight(textMinHeight);

            // Requires re-layout.
            updateLayout();
        }
    }

    public int getWidth() {
        return mWidth;
    }

    @UnsupportedAppUsage
    public void onSizeChanged(int w, int h, int oldw, int oldh) {
        updateLayout();
    }

    public void onItemCountChanged(int childCount, int itemCount) {
        if (mOldItemCount != itemCount || mOldChildCount != childCount) {
            mOldItemCount = itemCount;
            mOldChildCount = childCount;

            final boolean hasMoreItems = itemCount - childCount > 0;
            if (hasMoreItems && mState != STATE_DRAGGING) {
                final int firstVisibleItem = mList.getFirstVisiblePosition();
                setThumbPos(getPosFromItemCount(firstVisibleItem, childCount, itemCount));
            }

            updateLongList(childCount, itemCount);
        }
    }

    private void updateLongList(int childCount, int itemCount) {
        final boolean longList = childCount > 0 && itemCount / childCount >= MIN_PAGES;
        if (mLongList != longList) {
            mLongList = longList;

            onStateDependencyChanged(false);
        }
    }

    /**
     * Creates a view into which preview text can be placed.
     */
    private TextView createPreviewTextView(Context context) {
        final LayoutParams params = new LayoutParams(
                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        final TextView textView = new TextView(context);
        textView.setLayoutParams(params);
        textView.setSingleLine(true);
        textView.setEllipsize(TruncateAt.MIDDLE);
        textView.setGravity(Gravity.CENTER);
        textView.setAlpha(0f);

        // Manually propagate inherited layout direction.
        textView.setLayoutDirection(mList.getLayoutDirection());

        return textView;
    }

    /**
     * Measures and layouts the scrollbar and decorations.
     */
    public void updateLayout() {
        // Prevent re-entry when RTL properties change as a side-effect of
        // resolving padding.
        if (mUpdatingLayout) {
            return;
        }

        mUpdatingLayout = true;

        updateContainerRect();

        layoutThumb();
        layoutTrack();

        updateOffsetAndRange();

        final Rect bounds = mTempBounds;
        measurePreview(mPrimaryText, bounds);
        applyLayout(mPrimaryText, bounds);
        measurePreview(mSecondaryText, bounds);
        applyLayout(mSecondaryText, bounds);

        if (mPreviewImage != null) {
            // Apply preview image padding.
            bounds.left -= mPreviewImage.getPaddingLeft();
            bounds.top -= mPreviewImage.getPaddingTop();
            bounds.right += mPreviewImage.getPaddingRight();
            bounds.bottom += mPreviewImage.getPaddingBottom();
            applyLayout(mPreviewImage, bounds);
        }

        mUpdatingLayout = false;
    }

    /**
     * Layouts a view within the specified bounds and pins the pivot point to
     * the appropriate edge.
     *
     * @param view The view to layout.
     * @param bounds Bounds at which to layout the view.
     */
    private void applyLayout(View view, Rect bounds) {
        view.layout(bounds.left, bounds.top, bounds.right, bounds.bottom);
        view.setPivotX(mLayoutFromRight ? bounds.right - bounds.left : 0);
    }

    /**
     * Measures the preview text bounds, taking preview image padding into
     * account. This method should only be called after {@link #layoutThumb()}
     * and {@link #layoutTrack()} have both been called at least once.
     *
     * @param v The preview text view to measure.
     * @param out Rectangle into which measured bounds are placed.
     */
    private void measurePreview(View v, Rect out) {
        // Apply the preview image's padding as layout margins.
        final Rect margins = mTempMargins;
        margins.left = mPreviewImage.getPaddingLeft();
        margins.top = mPreviewImage.getPaddingTop();
        margins.right = mPreviewImage.getPaddingRight();
        margins.bottom = mPreviewImage.getPaddingBottom();

        if (mOverlayPosition == OVERLAY_FLOATING) {
            measureFloating(v, margins, out);
        } else {
            measureViewToSide(v, mThumbImage, margins, out);
        }
    }

    /**
     * Measures the bounds for a view that should be laid out against the edge
     * of an adjacent view. If no adjacent view is provided, lays out against
     * the list edge.
     *
     * @param view The view to measure for layout.
     * @param adjacent (Optional) The adjacent view, may be null to align to the
     *            list edge.
     * @param margins Layout margins to apply to the view.
     * @param out Rectangle into which measured bounds are placed.
     */
    private void measureViewToSide(View view, View adjacent, Rect margins, Rect out) {
        final int marginLeft;
        final int marginTop;
        final int marginRight;
        if (margins == null) {
            marginLeft = 0;
            marginTop = 0;
            marginRight = 0;
        } else {
            marginLeft = margins.left;
            marginTop = margins.top;
            marginRight = margins.right;
        }

        final Rect container = mContainerRect;
        final int containerWidth = container.width();
        final int maxWidth;
        if (adjacent == null) {
            maxWidth = containerWidth;
        } else if (mLayoutFromRight) {
            maxWidth = adjacent.getLeft();
        } else {
            maxWidth = containerWidth - adjacent.getRight();
        }

        final int adjMaxHeight = Math.max(0, container.height());
        final int adjMaxWidth = Math.max(0, maxWidth - marginLeft - marginRight);
        final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(adjMaxWidth, MeasureSpec.AT_MOST);
        final int heightMeasureSpec = MeasureSpec.makeSafeMeasureSpec(
                adjMaxHeight, MeasureSpec.UNSPECIFIED);
        view.measure(widthMeasureSpec, heightMeasureSpec);

        // Align to the left or right.
        final int width = Math.min(adjMaxWidth, view.getMeasuredWidth());
        final int left;
        final int right;
        if (mLayoutFromRight) {
            right = (adjacent == null ? container.right : adjacent.getLeft()) - marginRight;
            left = right - width;
        } else {
            left = (adjacent == null ? container.left : adjacent.getRight()) + marginLeft;
            right = left + width;
        }

        // Don't adjust the vertical position.
        final int top = marginTop;
        final int bottom = top + view.getMeasuredHeight();
        out.set(left, top, right, bottom);
    }

    private void measureFloating(View preview, Rect margins, Rect out) {
        final int marginLeft;
        final int marginTop;
        final int marginRight;
        if (margins == null) {
            marginLeft = 0;
            marginTop = 0;
            marginRight = 0;
        } else {
            marginLeft = margins.left;
            marginTop = margins.top;
            marginRight = margins.right;
        }

        final Rect container = mContainerRect;
        final int containerWidth = container.width();
        final int adjMaxHeight = Math.max(0, container.height());
        final int adjMaxWidth = Math.max(0, containerWidth - marginLeft - marginRight);
        final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(adjMaxWidth, MeasureSpec.AT_MOST);
        final int heightMeasureSpec = MeasureSpec.makeSafeMeasureSpec(
                adjMaxHeight, MeasureSpec.UNSPECIFIED);
        preview.measure(widthMeasureSpec, heightMeasureSpec);

        // Align at the vertical center, 10% from the top.
        final int containerHeight = container.height();
        final int width = preview.getMeasuredWidth();
        final int top = containerHeight / 10 + marginTop + container.top;
        final int bottom = top + preview.getMeasuredHeight();
        final int left = (containerWidth - width) / 2 + container.left;
        final int right = left + width;
        out.set(left, top, right, bottom);
    }

    /**
     * Updates the container rectangle used for layout.
     */
    private void updateContainerRect() {
        final AbsListView list = mList;
        list.resolvePadding();

        final Rect container = mContainerRect;
        container.left = 0;
        container.top = 0;
        container.right = list.getWidth();
        container.bottom = list.getHeight();

        final int scrollbarStyle = mScrollBarStyle;
        if (scrollbarStyle == View.SCROLLBARS_INSIDE_INSET
                || scrollbarStyle == View.SCROLLBARS_INSIDE_OVERLAY) {
            container.left += list.getPaddingLeft();
            container.top += list.getPaddingTop();
            container.right -= list.getPaddingRight();
            container.bottom -= list.getPaddingBottom();

            // In inset mode, we need to adjust for padded scrollbar width.
            if (scrollbarStyle == View.SCROLLBARS_INSIDE_INSET) {
                final int width = getWidth();
                if (mScrollbarPosition == View.SCROLLBAR_POSITION_RIGHT) {
                    container.right += width;
                } else {
                    container.left -= width;
                }
            }
        }
    }

    /**
     * Lays out the thumb according to the current scrollbar position.
     */
    private void layoutThumb() {
        final Rect bounds = mTempBounds;
        measureViewToSide(mThumbImage, null, null, bounds);
        applyLayout(mThumbImage, bounds);
    }

    /**
     * Lays out the track centered on the thumb. Must be called after
     * {@link #layoutThumb}.
     */
    private void layoutTrack() {
        final View track = mTrackImage;
        final View thumb = mThumbImage;
        final Rect container = mContainerRect;
        final int maxWidth = Math.max(0, container.width());
        final int maxHeight = Math.max(0, container.height());
        final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.AT_MOST);
        final int heightMeasureSpec = MeasureSpec.makeSafeMeasureSpec(
                maxHeight, MeasureSpec.UNSPECIFIED);
        track.measure(widthMeasureSpec, heightMeasureSpec);

        final int top;
        final int bottom;
        if (mThumbPosition == THUMB_POSITION_INSIDE) {
            top = container.top;
            bottom = container.bottom;
        } else {
            final int thumbHalfHeight = thumb.getHeight() / 2;
            top = container.top + thumbHalfHeight;
            bottom = container.bottom - thumbHalfHeight;
        }

        final int trackWidth = track.getMeasuredWidth();
        final int left = thumb.getLeft() + (thumb.getWidth() - trackWidth) / 2;
        final int right = left + trackWidth;
        track.layout(left, top, right, bottom);
    }

    /**
     * Updates the offset and range used to convert from absolute y-position to
     * thumb position within the track.
     */
    private void updateOffsetAndRange() {
        final View trackImage = mTrackImage;
        final View thumbImage = mThumbImage;
        final float min;
        final float max;
        if (mThumbPosition == THUMB_POSITION_INSIDE) {
            final float halfThumbHeight = thumbImage.getHeight() / 2f;
            min = trackImage.getTop() + halfThumbHeight;
            max = trackImage.getBottom() - halfThumbHeight;
        } else{
            min = trackImage.getTop();
            max = trackImage.getBottom();
        }

        mThumbOffset = min;
        mThumbRange = max - min;
    }

    @UnsupportedAppUsage
    private void setState(int state) {
        mList.removeCallbacks(mDeferHide);

        if (mAlwaysShow && state == STATE_NONE) {
            state = STATE_VISIBLE;
        }

        if (state == mState) {
            return;
        }

        switch (state) {
            case STATE_NONE:
                transitionToHidden();
                break;
            case STATE_VISIBLE:
                transitionToVisible();
                break;
            case STATE_DRAGGING:
                if (transitionPreviewLayout(mCurrentSection)) {
                    transitionToDragging();
                } else {
                    transitionToVisible();
                }
                break;
        }

        mState = state;

        refreshDrawablePressedState();
    }

    private void refreshDrawablePressedState() {
        final boolean isPressed = mState == STATE_DRAGGING;
        mThumbImage.setPressed(isPressed);
        mTrackImage.setPressed(isPressed);
    }

    /**
     * Shows nothing.
     */
    private void transitionToHidden() {
        if (mDecorAnimation != null) {
            mDecorAnimation.cancel();
        }

        final Animator fadeOut = groupAnimatorOfFloat(View.ALPHA, 0f, mThumbImage, mTrackImage,
                mPreviewImage, mPrimaryText, mSecondaryText).setDuration(DURATION_FADE_OUT);

        // Push the thumb and track outside the list bounds.
        final float offset = mLayoutFromRight ? mThumbImage.getWidth() : -mThumbImage.getWidth();
        final Animator slideOut = groupAnimatorOfFloat(
                View.TRANSLATION_X, offset, mThumbImage, mTrackImage)
                .setDuration(DURATION_FADE_OUT);

        mDecorAnimation = new AnimatorSet();
        mDecorAnimation.playTogether(fadeOut, slideOut);
        mDecorAnimation.start();

        mShowingPreview = false;
    }

    /**
     * Shows the thumb and track.
     */
    private void transitionToVisible() {
        if (mDecorAnimation != null) {
            mDecorAnimation.cancel();
        }

        final Animator fadeIn = groupAnimatorOfFloat(View.ALPHA, 1f, mThumbImage, mTrackImage)
                .setDuration(DURATION_FADE_IN);
        final Animator fadeOut = groupAnimatorOfFloat(
                View.ALPHA, 0f, mPreviewImage, mPrimaryText, mSecondaryText)
                .setDuration(DURATION_FADE_OUT);
        final Animator slideIn = groupAnimatorOfFloat(
                View.TRANSLATION_X, 0f, mThumbImage, mTrackImage).setDuration(DURATION_FADE_IN);

        mDecorAnimation = new AnimatorSet();
        mDecorAnimation.playTogether(fadeIn, fadeOut, slideIn);
        mDecorAnimation.start();

        mShowingPreview = false;
    }

    /**
     * Shows the thumb, preview, and track.
     */
    private void transitionToDragging() {
        if (mDecorAnimation != null) {
            mDecorAnimation.cancel();
        }

        final Animator fadeIn = groupAnimatorOfFloat(
                View.ALPHA, 1f, mThumbImage, mTrackImage, mPreviewImage)
                .setDuration(DURATION_FADE_IN);
        final Animator slideIn = groupAnimatorOfFloat(
                View.TRANSLATION_X, 0f, mThumbImage, mTrackImage).setDuration(DURATION_FADE_IN);

        mDecorAnimation = new AnimatorSet();
        mDecorAnimation.playTogether(fadeIn, slideIn);
        mDecorAnimation.start();

        mShowingPreview = true;
    }

    private void postAutoHide() {
        mList.removeCallbacks(mDeferHide);
        mList.postDelayed(mDeferHide, FADE_TIMEOUT);
    }

    public void onScroll(int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        if (!isEnabled()) {
            setState(STATE_NONE);
            return;
        }

        final boolean hasMoreItems = totalItemCount - visibleItemCount > 0;
        if (hasMoreItems && mState != STATE_DRAGGING) {
            setThumbPos(getPosFromItemCount(firstVisibleItem, visibleItemCount, totalItemCount));
        }

        mScrollCompleted = true;

        if (mFirstVisibleItem != firstVisibleItem) {
            mFirstVisibleItem = firstVisibleItem;

            // Show the thumb, if necessary, and set up auto-fade.
            if (mState != STATE_DRAGGING) {
                setState(STATE_VISIBLE);
                postAutoHide();
            }
        }
    }

    private void getSectionsFromIndexer() {
        mSectionIndexer = null;

        Adapter adapter = mList.getAdapter();
        if (adapter instanceof HeaderViewListAdapter) {
            mHeaderCount = ((HeaderViewListAdapter) adapter).getHeadersCount();
            adapter = ((HeaderViewListAdapter) adapter).getWrappedAdapter();
        }

        if (adapter instanceof ExpandableListConnector) {
            final ExpandableListAdapter expAdapter = ((ExpandableListConnector) adapter)
                    .getAdapter();
            if (expAdapter instanceof SectionIndexer) {
                mSectionIndexer = (SectionIndexer) expAdapter;
                mListAdapter = adapter;
                mSections = mSectionIndexer.getSections();
            }
        } else if (adapter instanceof SectionIndexer) {
            mListAdapter = adapter;
            mSectionIndexer = (SectionIndexer) adapter;
            mSections = mSectionIndexer.getSections();
        } else {
            mListAdapter = adapter;
            mSections = null;
        }
    }

    public void onSectionsChanged() {
        mListAdapter = null;
    }

    /**
     * Scrolls to a specific position within the section
     * @param position
     */
    private void scrollTo(float position) {
        mScrollCompleted = false;

        final int count = mList.getCount();
        final Object[] sections = mSections;
        final int sectionCount = sections == null ? 0 : sections.length;
        int sectionIndex;
        if (sections != null && sectionCount > 1) {
            final int exactSection = MathUtils.constrain(
                    (int) (position * sectionCount), 0, sectionCount - 1);
            int targetSection = exactSection;
            int targetIndex = mSectionIndexer.getPositionForSection(targetSection);
            sectionIndex = targetSection;

            // Given the expected section and index, the following code will
            // try to account for missing sections (no names starting with..)
            // It will compute the scroll space of surrounding empty sections
            // and interpolate the currently visible letter's range across the
            // available space, so that there is always some list movement while
            // the user moves the thumb.
            int nextIndex = count;
            int prevIndex = targetIndex;
            int prevSection = targetSection;
            int nextSection = targetSection + 1;

            // Assume the next section is unique
            if (targetSection < sectionCount - 1) {
                nextIndex = mSectionIndexer.getPositionForSection(targetSection + 1);
            }

            // Find the previous index if we're slicing the previous section
            if (nextIndex == targetIndex) {
                // Non-existent letter
                while (targetSection > 0) {
                    targetSection--;
                    prevIndex = mSectionIndexer.getPositionForSection(targetSection);
                    if (prevIndex != targetIndex) {
                        prevSection = targetSection;
                        sectionIndex = targetSection;
                        break;
                    } else if (targetSection == 0) {
                        // When section reaches 0 here, sectionIndex must follow it.
                        // Assuming mSectionIndexer.getPositionForSection(0) == 0.
                        sectionIndex = 0;
                        break;
                    }
                }
            }

            // Find the next index, in case the assumed next index is not
            // unique. For instance, if there is no P, then request for P's
            // position actually returns Q's. So we need to look ahead to make
            // sure that there is really a Q at Q's position. If not, move
            // further down...
            int nextNextSection = nextSection + 1;
            while (nextNextSection < sectionCount &&
                    mSectionIndexer.getPositionForSection(nextNextSection) == nextIndex) {
                nextNextSection++;
                nextSection++;
            }

            // Compute the beginning and ending scroll range percentage of the
            // currently visible section. This could be equal to or greater than
            // (1 / nSections). If the target position is near the previous
            // position, snap to the previous position.
            final float prevPosition = (float) prevSection / sectionCount;
            final float nextPosition = (float) nextSection / sectionCount;
            final float snapThreshold = (count == 0) ? Float.MAX_VALUE : .125f / count;
            if (prevSection == exactSection && position - prevPosition < snapThreshold) {
                targetIndex = prevIndex;
            } else {
                targetIndex = prevIndex + (int) ((nextIndex - prevIndex) * (position - prevPosition)
                    / (nextPosition - prevPosition));
            }

            // Clamp to valid positions.
            targetIndex = MathUtils.constrain(targetIndex, 0, count - 1);

            if (mList instanceof ExpandableListView) {
                final ExpandableListView expList = (ExpandableListView) mList;
                expList.setSelectionFromTop(expList.getFlatListPosition(
                        ExpandableListView.getPackedPositionForGroup(targetIndex + mHeaderCount)),
                        0);
            } else if (mList instanceof ListView) {
                ((ListView) mList).setSelectionFromTop(targetIndex + mHeaderCount, 0);
            } else {
                mList.setSelection(targetIndex + mHeaderCount);
            }
        } else {
            final int index = MathUtils.constrain((int) (position * count), 0, count - 1);

            if (mList instanceof ExpandableListView) {
                ExpandableListView expList = (ExpandableListView) mList;
                expList.setSelectionFromTop(expList.getFlatListPosition(
                        ExpandableListView.getPackedPositionForGroup(index + mHeaderCount)), 0);
            } else if (mList instanceof ListView) {
                ((ListView)mList).setSelectionFromTop(index + mHeaderCount, 0);
            } else {
                mList.setSelection(index + mHeaderCount);
            }

            sectionIndex = -1;
        }

        if (mCurrentSection != sectionIndex) {
            mCurrentSection = sectionIndex;

            final boolean hasPreview = transitionPreviewLayout(sectionIndex);
            if (!mShowingPreview && hasPreview) {
                transitionToDragging();
            } else if (mShowingPreview && !hasPreview) {
                transitionToVisible();
            }
        }
    }

    /**
     * Transitions the preview text to a new section. Handles animation,
     * measurement, and layout. If the new preview text is empty, returns false.
     *
     * @param sectionIndex The section index to which the preview should
     *            transition.
     * @return False if the new preview text is empty.
     */
    private boolean transitionPreviewLayout(int sectionIndex) {
        final Object[] sections = mSections;
        String text = null;
        if (sections != null && sectionIndex >= 0 && sectionIndex < sections.length) {
            final Object section = sections[sectionIndex];
            if (section != null) {
                text = section.toString();
            }
        }

        final Rect bounds = mTempBounds;
        final View preview = mPreviewImage;
        final TextView showing;
        final TextView target;
        if (mShowingPrimary) {
            showing = mPrimaryText;
            target = mSecondaryText;
        } else {
            showing = mSecondaryText;
            target = mPrimaryText;
        }

        // Set and layout target immediately.
        target.setText(text);
        measurePreview(target, bounds);
        applyLayout(target, bounds);

        if (mPreviewAnimation != null) {
            mPreviewAnimation.cancel();
        }

        // Cross-fade preview text.
        final Animator showTarget = animateAlpha(target, 1f).setDuration(DURATION_CROSS_FADE);
        final Animator hideShowing = animateAlpha(showing, 0f).setDuration(DURATION_CROSS_FADE);
        hideShowing.addListener(mSwitchPrimaryListener);

        // Apply preview image padding and animate bounds, if necessary.
        bounds.left -= preview.getPaddingLeft();
        bounds.top -= preview.getPaddingTop();
        bounds.right += preview.getPaddingRight();
        bounds.bottom += preview.getPaddingBottom();
        final Animator resizePreview = animateBounds(preview, bounds);
        resizePreview.setDuration(DURATION_RESIZE);

        mPreviewAnimation = new AnimatorSet();
        final AnimatorSet.Builder builder = mPreviewAnimation.play(hideShowing).with(showTarget);
        builder.with(resizePreview);

        // The current preview size is unaffected by hidden or showing. It's
        // used to set starting scales for things that need to be scaled down.
        final int previewWidth = preview.getWidth() - preview.getPaddingLeft()
                - preview.getPaddingRight();

        // If target is too large, shrink it immediately to fit and expand to
        // target size. Otherwise, start at target size.
        final int targetWidth = target.getWidth();
        if (targetWidth > previewWidth) {
            target.setScaleX((float) previewWidth / targetWidth);
            final Animator scaleAnim = animateScaleX(target, 1f).setDuration(DURATION_RESIZE);
            builder.with(scaleAnim);
        } else {
            target.setScaleX(1f);
        }

        // If showing is larger than target, shrink to target size.
        final int showingWidth = showing.getWidth();
        if (showingWidth > targetWidth) {
            final float scale = (float) targetWidth / showingWidth;
            final Animator scaleAnim = animateScaleX(showing, scale).setDuration(DURATION_RESIZE);
            builder.with(scaleAnim);
        }

        mPreviewAnimation.start();

        return !TextUtils.isEmpty(text);
    }

    /**
     * Positions the thumb and preview widgets.
     *
     * @param position The position, between 0 and 1, along the track at which
     *            to place the thumb.
     */
    private void setThumbPos(float position) {
        final float thumbMiddle = position * mThumbRange + mThumbOffset;
        mThumbImage.setTranslationY(thumbMiddle - mThumbImage.getHeight() / 2f);

        final View previewImage = mPreviewImage;
        final float previewHalfHeight = previewImage.getHeight() / 2f;
        final float previewPos;
        switch (mOverlayPosition) {
            case OVERLAY_AT_THUMB:
                previewPos = thumbMiddle;
                break;
            case OVERLAY_ABOVE_THUMB:
                previewPos = thumbMiddle - previewHalfHeight;
                break;
            case OVERLAY_FLOATING:
            default:
                previewPos = 0;
                break;
        }

        // Center the preview on the thumb, constrained to the list bounds.
        final Rect container = mContainerRect;
        final int top = container.top;
        final int bottom = container.bottom;
        final float minP = top + previewHalfHeight;
        final float maxP = bottom - previewHalfHeight;
        final float previewMiddle = MathUtils.constrain(previewPos, minP, maxP);
        final float previewTop = previewMiddle - previewHalfHeight;
        previewImage.setTranslationY(previewTop);

        mPrimaryText.setTranslationY(previewTop);
        mSecondaryText.setTranslationY(previewTop);
    }

    private float getPosFromMotionEvent(float y) {
        // If the list is the same height as the thumbnail or shorter,
        // effectively disable scrolling.
        if (mThumbRange <= 0) {
            return 0f;
        }

        return MathUtils.constrain((y - mThumbOffset) / mThumbRange, 0f, 1f);
    }

    /**
     * Calculates the thumb position based on the visible items.
     *
     * @param firstVisibleItem First visible item, >= 0.
     * @param visibleItemCount Number of visible items, >= 0.
     * @param totalItemCount Total number of items, >= 0.
     * @return
     */
    private float getPosFromItemCount(
            int firstVisibleItem, int visibleItemCount, int totalItemCount) {
        final SectionIndexer sectionIndexer = mSectionIndexer;
        if (sectionIndexer == null || mListAdapter == null) {
            getSectionsFromIndexer();
        }

        if (visibleItemCount == 0 || totalItemCount == 0) {
            // No items are visible.
            return 0;
        }

        final boolean hasSections = sectionIndexer != null && mSections != null
                && mSections.length > 0;
        if (!hasSections || !mMatchDragPosition) {
            if (visibleItemCount == totalItemCount) {
                // All items are visible.
                return 0;
            } else {
                return (float) firstVisibleItem / (totalItemCount - visibleItemCount);
            }
        }

        // Ignore headers.
        firstVisibleItem -= mHeaderCount;
        if (firstVisibleItem < 0) {
            return 0;
        }
        totalItemCount -= mHeaderCount;

        // Hidden portion of the first visible row.
        final View child = mList.getChildAt(0);
        final float incrementalPos;
        if (child == null || child.getHeight() == 0) {
            incrementalPos = 0;
        } else {
            incrementalPos = (float) (mList.getPaddingTop() - child.getTop()) / child.getHeight();
        }

        // Number of rows in this section.
        final int section = sectionIndexer.getSectionForPosition(firstVisibleItem);
        final int sectionPos = sectionIndexer.getPositionForSection(section);
        final int sectionCount = mSections.length;
        final int positionsInSection;
        if (section < sectionCount - 1) {
            final int nextSectionPos;
            if (section + 1 < sectionCount) {
                nextSectionPos = sectionIndexer.getPositionForSection(section + 1);
            } else {
                nextSectionPos = totalItemCount - 1;
            }
            positionsInSection = nextSectionPos - sectionPos;
        } else {
            positionsInSection = totalItemCount - sectionPos;
        }

        // Position within this section.
        final float posWithinSection;
        if (positionsInSection == 0) {
            posWithinSection = 0;
        } else {
            posWithinSection = (firstVisibleItem + incrementalPos - sectionPos)
                    / positionsInSection;
        }

        float result = (section + posWithinSection) / sectionCount;

        // Fake out the scroll bar for the last item. Since the section indexer
        // won't ever actually move the list in this end space, make scrolling
        // across the last item account for whatever space is remaining.
        if (firstVisibleItem > 0 && firstVisibleItem + visibleItemCount == totalItemCount) {
            final View lastChild = mList.getChildAt(visibleItemCount - 1);
            final int bottomPadding = mList.getPaddingBottom();
            final int maxSize;
            final int currentVisibleSize;
            if (mList.getClipToPadding()) {
                maxSize = lastChild.getHeight();
                currentVisibleSize = mList.getHeight() - bottomPadding - lastChild.getTop();
            } else {
                maxSize = lastChild.getHeight() + bottomPadding;
                currentVisibleSize = mList.getHeight() - lastChild.getTop();
            }
            if (currentVisibleSize > 0 && maxSize > 0) {
                result += (1 - result) * ((float) currentVisibleSize / maxSize );
            }
        }

        return result;
    }

    /**
     * Cancels an ongoing fling event by injecting a
     * {@link MotionEvent#ACTION_CANCEL} into the host view.
     */
    private void cancelFling() {
        final MotionEvent cancelFling = MotionEvent.obtain(
                0, 0, MotionEvent.ACTION_CANCEL, 0, 0, 0);
        mList.onTouchEvent(cancelFling);
        cancelFling.recycle();
    }

    /**
     * Cancels a pending drag.
     *
     * @see #startPendingDrag()
     */
    private void cancelPendingDrag() {
        mPendingDrag = -1;
    }

    /**
     * Delays dragging until after the framework has determined that the user is
     * scrolling, rather than tapping.
     */
    private void startPendingDrag() {
        mPendingDrag = SystemClock.uptimeMillis() + TAP_TIMEOUT;
    }

    private void beginDrag() {
        mPendingDrag = -1;

        setState(STATE_DRAGGING);

        if (mListAdapter == null && mList != null) {
            getSectionsFromIndexer();
        }

        if (mList != null) {
            mList.requestDisallowInterceptTouchEvent(true);
            mList.reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
        }

        cancelFling();
    }

    @UnsupportedAppUsage
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        if (!isEnabled()) {
            return false;
        }

        switch (ev.getActionMasked()) {
            case MotionEvent.ACTION_DOWN:
                if (isPointInside(ev.getX(), ev.getY())) {
                    // If the parent has requested that its children delay
                    // pressed state (e.g. is a scrolling container) then we
                    // need to allow the parent time to decide whether it wants
                    // to intercept events. If it does, we will receive a CANCEL
                    // event.
                    if (!mList.isInScrollingContainer()) {
                        // This will get dispatched to onTouchEvent(). Start
                        // dragging there.
                        return true;
                    }

                    mInitialTouchY = ev.getY();
                    startPendingDrag();
                }
                break;
            case MotionEvent.ACTION_MOVE:
                if (!isPointInside(ev.getX(), ev.getY())) {
                    cancelPendingDrag();
                } else if (mPendingDrag >= 0 && mPendingDrag <= SystemClock.uptimeMillis()) {
                    beginDrag();

                    final float pos = getPosFromMotionEvent(mInitialTouchY);
                    scrollTo(pos);

                    // This may get dispatched to onTouchEvent(), but it
                    // doesn't really matter since we'll already be in a drag.
                    return onTouchEvent(ev);
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                cancelPendingDrag();
                break;
        }

        return false;
    }

    public boolean onInterceptHoverEvent(MotionEvent ev) {
        if (!isEnabled()) {
            return false;
        }

        final int actionMasked = ev.getActionMasked();
        if ((actionMasked == MotionEvent.ACTION_HOVER_ENTER
                || actionMasked == MotionEvent.ACTION_HOVER_MOVE) && mState == STATE_NONE
                && isPointInside(ev.getX(), ev.getY())) {
            setState(STATE_VISIBLE);
            postAutoHide();
        }

        return false;
    }

    public PointerIcon onResolvePointerIcon(MotionEvent event, int pointerIndex) {
        if (mState == STATE_DRAGGING || isPointInside(event.getX(), event.getY())) {
            return PointerIcon.getSystemIcon(mList.getContext(), PointerIcon.TYPE_ARROW);
        }
        return null;
    }

    @UnsupportedAppUsage
    public boolean onTouchEvent(MotionEvent me) {
        if (!isEnabled()) {
            return false;
        }

        switch (me.getActionMasked()) {
            case MotionEvent.ACTION_DOWN: {
                if (isPointInside(me.getX(), me.getY())) {
                    if (!mList.isInScrollingContainer()) {
                        beginDrag();
                        return true;
                    }
                }
            } break;

            case MotionEvent.ACTION_UP: {
                if (mPendingDrag >= 0) {
                    // Allow a tap to scroll.
                    beginDrag();

                    final float pos = getPosFromMotionEvent(me.getY());
                    setThumbPos(pos);
                    scrollTo(pos);

                    // Will hit the STATE_DRAGGING check below
                }

                if (mState == STATE_DRAGGING) {
                    if (mList != null) {
                        // ViewGroup does the right thing already, but there might
                        // be other classes that don't properly reset on touch-up,
                        // so do this explicitly just in case.
                        mList.requestDisallowInterceptTouchEvent(false);
                        mList.reportScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
                    }

                    setState(STATE_VISIBLE);
                    postAutoHide();

                    return true;
                }
            } break;

            case MotionEvent.ACTION_MOVE: {
                if (mPendingDrag >= 0 && Math.abs(me.getY() - mInitialTouchY) > mScaledTouchSlop) {
                    beginDrag();

                    // Will hit the STATE_DRAGGING check below
                }

                if (mState == STATE_DRAGGING) {
                    // TODO: Ignore jitter.
                    final float pos = getPosFromMotionEvent(me.getY());
                    setThumbPos(pos);

                    // If the previous scrollTo is still pending
                    if (mScrollCompleted) {
                        scrollTo(pos);
                    }

                    return true;
                }
            } break;

            case MotionEvent.ACTION_CANCEL: {
                cancelPendingDrag();
            } break;
        }

        return false;
    }

    /**
     * Returns whether a coordinate is inside the scroller's activation area. If
     * there is a track image, touching anywhere within the thumb-width of the
     * track activates scrolling. Otherwise, the user has to touch inside thumb
     * itself.
     *
     * @param x The x-coordinate.
     * @param y The y-coordinate.
     * @return Whether the coordinate is inside the scroller's activation area.
     */
    private boolean isPointInside(float x, float y) {
        return isPointInsideX(x) && (mTrackDrawable != null || isPointInsideY(y));
    }

    private boolean isPointInsideX(float x) {
        final float offset = mThumbImage.getTranslationX();
        final float left = mThumbImage.getLeft() + offset;
        final float right = mThumbImage.getRight() + offset;

        // Apply the minimum touch target size.
        final float targetSizeDiff = mMinimumTouchTarget - (right - left);
        final float adjust = targetSizeDiff > 0 ? targetSizeDiff : 0;

        if (mLayoutFromRight) {
            return x >= mThumbImage.getLeft() - adjust;
        } else {
            return x <= mThumbImage.getRight() + adjust;
        }
    }

    private boolean isPointInsideY(float y) {
        final float offset = mThumbImage.getTranslationY();
        final float top = mThumbImage.getTop() + offset;
        final float bottom = mThumbImage.getBottom() + offset;

        // Apply the minimum touch target size.
        final float targetSizeDiff = mMinimumTouchTarget - (bottom - top);
        final float adjust = targetSizeDiff > 0 ? targetSizeDiff / 2 : 0;

        return y >= (top - adjust) && y <= (bottom + adjust);
    }

    /**
     * Constructs an animator for the specified property on a group of views.
     * See {@link ObjectAnimator#ofFloat(Object, String, float...)} for
     * implementation details.
     *
     * @param property The property being animated.
     * @param value The value to which that property should animate.
     * @param views The target views to animate.
     * @return An animator for all the specified views.
     */
    private static Animator groupAnimatorOfFloat(
            Property<View, Float> property, float value, View... views) {
        AnimatorSet animSet = new AnimatorSet();
        AnimatorSet.Builder builder = null;

        for (int i = views.length - 1; i >= 0; i--) {
            final Animator anim = ObjectAnimator.ofFloat(views[i], property, value);
            if (builder == null) {
                builder = animSet.play(anim);
            } else {
                builder.with(anim);
            }
        }

        return animSet;
    }

    /**
     * Returns an animator for the view's scaleX value.
     */
    private static Animator animateScaleX(View v, float target) {
        return ObjectAnimator.ofFloat(v, View.SCALE_X, target);
    }

    /**
     * Returns an animator for the view's alpha value.
     */
    private static Animator animateAlpha(View v, float alpha) {
        return ObjectAnimator.ofFloat(v, View.ALPHA, alpha);
    }

    /**
     * A Property wrapper around the <code>left</code> functionality handled by the
     * {@link View#setLeft(int)} and {@link View#getLeft()} methods.
     */
    private static Property<View, Integer> LEFT = new IntProperty<View>("left") {
        @Override
        public void setValue(View object, int value) {
            object.setLeft(value);
        }

        @Override
        public Integer get(View object) {
            return object.getLeft();
        }
    };

    /**
     * A Property wrapper around the <code>top</code> functionality handled by the
     * {@link View#setTop(int)} and {@link View#getTop()} methods.
     */
    private static Property<View, Integer> TOP = new IntProperty<View>("top") {
        @Override
        public void setValue(View object, int value) {
            object.setTop(value);
        }

        @Override
        public Integer get(View object) {
            return object.getTop();
        }
    };

    /**
     * A Property wrapper around the <code>right</code> functionality handled by the
     * {@link View#setRight(int)} and {@link View#getRight()} methods.
     */
    private static Property<View, Integer> RIGHT = new IntProperty<View>("right") {
        @Override
        public void setValue(View object, int value) {
            object.setRight(value);
        }

        @Override
        public Integer get(View object) {
            return object.getRight();
        }
    };

    /**
     * A Property wrapper around the <code>bottom</code> functionality handled by the
     * {@link View#setBottom(int)} and {@link View#getBottom()} methods.
     */
    private static Property<View, Integer> BOTTOM = new IntProperty<View>("bottom") {
        @Override
        public void setValue(View object, int value) {
            object.setBottom(value);
        }

        @Override
        public Integer get(View object) {
            return object.getBottom();
        }
    };

    /**
     * Returns an animator for the view's bounds.
     */
    private static Animator animateBounds(View v, Rect bounds) {
        final PropertyValuesHolder left = PropertyValuesHolder.ofInt(LEFT, bounds.left);
        final PropertyValuesHolder top = PropertyValuesHolder.ofInt(TOP, bounds.top);
        final PropertyValuesHolder right = PropertyValuesHolder.ofInt(RIGHT, bounds.right);
        final PropertyValuesHolder bottom = PropertyValuesHolder.ofInt(BOTTOM, bounds.bottom);
        return ObjectAnimator.ofPropertyValuesHolder(v, left, top, right, bottom);
    }
}
