/*
 * Copyright (C) 2015 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.launcher3;

import android.animation.AnimatorSet;
import android.animation.ArgbEvaluator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.ViewConfiguration;

import com.android.launcher3.util.Thunk;

/**
 * The track and scrollbar that shows when you scroll the list.
 */
public class BaseRecyclerViewFastScrollBar {

    public interface FastScrollFocusableView {
        void setFastScrollFocusState(final FastBitmapDrawable.State focusState, boolean animated);
    }

    private final static int MAX_TRACK_ALPHA = 30;
    private final static int SCROLL_BAR_VIS_DURATION = 150;

    @Thunk BaseRecyclerView mRv;
    private BaseRecyclerViewFastScrollPopup mPopup;

    private AnimatorSet mScrollbarAnimator;

    private int mThumbInactiveColor;
    private int mThumbActiveColor;
    @Thunk Point mThumbOffset = new Point(-1, -1);
    @Thunk Paint mThumbPaint;
    private int mThumbMinWidth;
    private int mThumbMaxWidth;
    @Thunk int mThumbWidth;
    @Thunk int mThumbHeight;
    private int mThumbCurvature;
    private Path mThumbPath = new Path();
    private Paint mTrackPaint;
    private int mTrackWidth;
    private float mLastTouchY;
    // The inset is the buffer around which a point will still register as a click on the scrollbar
    private int mTouchInset;
    private boolean mIsDragging;
    private boolean mIsThumbDetached;
    private boolean mCanThumbDetach;
    private boolean mIgnoreDragGesture;

    // This is the offset from the top of the scrollbar when the user first starts touching.  To
    // prevent jumping, this offset is applied as the user scrolls.
    private int mTouchOffset;

    private Rect mInvalidateRect = new Rect();
    private Rect mTmpRect = new Rect();

    public BaseRecyclerViewFastScrollBar(BaseRecyclerView rv, Resources res) {
        mRv = rv;
        mPopup = new BaseRecyclerViewFastScrollPopup(rv, res);
        mTrackPaint = new Paint();
        mTrackPaint.setColor(rv.getFastScrollerTrackColor(Color.BLACK));
        mTrackPaint.setAlpha(MAX_TRACK_ALPHA);
        mThumbActiveColor = mThumbInactiveColor = Utilities.getColorAccent(rv.getContext());
        mThumbPaint = new Paint();
        mThumbPaint.setAntiAlias(true);
        mThumbPaint.setColor(mThumbInactiveColor);
        mThumbPaint.setStyle(Paint.Style.FILL);
        mThumbWidth = mThumbMinWidth = res.getDimensionPixelSize(R.dimen.container_fastscroll_thumb_min_width);
        mThumbMaxWidth = res.getDimensionPixelSize(R.dimen.container_fastscroll_thumb_max_width);
        mThumbHeight = res.getDimensionPixelSize(R.dimen.container_fastscroll_thumb_height);
        mThumbCurvature = mThumbMaxWidth - mThumbMinWidth;
        mTouchInset = res.getDimensionPixelSize(R.dimen.container_fastscroll_thumb_touch_inset);
    }

    public void setDetachThumbOnFastScroll() {
        mCanThumbDetach = true;
    }

    public void reattachThumbToScroll() {
        mIsThumbDetached = false;
    }

    public void setThumbOffset(int x, int y) {
        if (mThumbOffset.x == x && mThumbOffset.y == y) {
            return;
        }
        mInvalidateRect.set(mThumbOffset.x - mThumbCurvature, mThumbOffset.y,
                mThumbOffset.x + mThumbWidth, mThumbOffset.y + mThumbHeight);
        mThumbOffset.set(x, y);
        updateThumbPath();
        mInvalidateRect.union(mThumbOffset.x - mThumbCurvature, mThumbOffset.y,
                mThumbOffset.x + mThumbWidth, mThumbOffset.y + mThumbHeight);
        mRv.invalidate(mInvalidateRect);
    }

    public Point getThumbOffset() {
        return mThumbOffset;
    }

    // Setter/getter for the thumb bar width for animations
    public void setThumbWidth(int width) {
        mInvalidateRect.set(mThumbOffset.x - mThumbCurvature, mThumbOffset.y,
                mThumbOffset.x + mThumbWidth, mThumbOffset.y + mThumbHeight);
        mThumbWidth = width;
        updateThumbPath();
        mInvalidateRect.union(mThumbOffset.x - mThumbCurvature, mThumbOffset.y,
                mThumbOffset.x + mThumbWidth, mThumbOffset.y + mThumbHeight);
        mRv.invalidate(mInvalidateRect);
    }

    public int getThumbWidth() {
        return mThumbWidth;
    }

    // Setter/getter for the track bar width for animations
    public void setTrackWidth(int width) {
        mInvalidateRect.set(mThumbOffset.x - mThumbCurvature, 0, mThumbOffset.x + mThumbWidth,
                mRv.getHeight());
        mTrackWidth = width;
        updateThumbPath();
        mInvalidateRect.union(mThumbOffset.x - mThumbCurvature, 0, mThumbOffset.x + mThumbWidth,
                mRv.getHeight());
        mRv.invalidate(mInvalidateRect);
    }

    public int getTrackWidth() {
        return mTrackWidth;
    }

    public int getThumbHeight() {
        return mThumbHeight;
    }

    public int getThumbMaxWidth() {
        return mThumbMaxWidth;
    }

    public boolean isDraggingThumb() {
        return mIsDragging;
    }

    public boolean isThumbDetached() {
        return mIsThumbDetached;
    }

    /**
     * Handles the touch event and determines whether to show the fast scroller (or updates it if
     * it is already showing).
     */
    public void handleTouchEvent(MotionEvent ev, int downX, int downY, int lastY) {
        ViewConfiguration config = ViewConfiguration.get(mRv.getContext());

        int action = ev.getAction();
        int y = (int) ev.getY();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                if (isNearThumb(downX, downY)) {
                    mTouchOffset = downY - mThumbOffset.y;
                }
                break;
            case MotionEvent.ACTION_MOVE:
                // Check if we should start scrolling, but ignore this fastscroll gesture if we have
                // exceeded some fixed movement
                mIgnoreDragGesture |= Math.abs(y - downY) > config.getScaledPagingTouchSlop();
                if (!mIsDragging && !mIgnoreDragGesture && mRv.supportsFastScrolling() &&
                        isNearThumb(downX, lastY) &&
                        Math.abs(y - downY) > config.getScaledTouchSlop()) {
                    mRv.getParent().requestDisallowInterceptTouchEvent(true);
                    mIsDragging = true;
                    if (mCanThumbDetach) {
                        mIsThumbDetached = true;
                    }
                    mTouchOffset += (lastY - downY);
                    mPopup.animateVisibility(true);
                    showActiveScrollbar(true);
                }
                if (mIsDragging) {
                    // Update the fastscroller section name at this touch position
                    int top = mRv.getBackgroundPadding().top;
                    int bottom = mRv.getHeight() - mRv.getBackgroundPadding().bottom - mThumbHeight;
                    float boundedY = (float) Math.max(top, Math.min(bottom, y - mTouchOffset));
                    String sectionName = mRv.scrollToPositionAtProgress((boundedY - top) /
                            (bottom - top));
                    mPopup.setSectionName(sectionName);
                    mPopup.animateVisibility(!sectionName.isEmpty());
                    mRv.invalidate(mPopup.updateFastScrollerBounds(lastY));
                    mLastTouchY = boundedY;
                    setThumbOffset(mRv.getScrollBarX(), (int) mLastTouchY);
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                mTouchOffset = 0;
                mLastTouchY = 0;
                mIgnoreDragGesture = false;
                if (mIsDragging) {
                    mIsDragging = false;
                    mPopup.animateVisibility(false);
                    showActiveScrollbar(false);
                }
                break;
        }
    }

    public void draw(Canvas canvas) {
        if (mThumbOffset.x < 0 || mThumbOffset.y < 0) {
            return;
        }

        // Draw the scroll bar track and thumb
        if (mTrackPaint.getAlpha() > 0) {
            canvas.drawRect(mThumbOffset.x, 0, mThumbOffset.x + mThumbWidth, mRv.getHeight(), mTrackPaint);
        }
        canvas.drawPath(mThumbPath, mThumbPaint);

        // Draw the popup
        mPopup.draw(canvas);
    }

    /**
     * Animates the width and color of the scrollbar.
     */
    private void showActiveScrollbar(boolean isScrolling) {
        if (mScrollbarAnimator != null) {
            mScrollbarAnimator.cancel();
        }

        mScrollbarAnimator = new AnimatorSet();
        ObjectAnimator trackWidthAnim = ObjectAnimator.ofInt(this, "trackWidth",
                isScrolling ? mThumbMaxWidth : mThumbMinWidth);
        ObjectAnimator thumbWidthAnim = ObjectAnimator.ofInt(this, "thumbWidth",
                isScrolling ? mThumbMaxWidth : mThumbMinWidth);
        mScrollbarAnimator.playTogether(trackWidthAnim, thumbWidthAnim);
        if (mThumbActiveColor != mThumbInactiveColor) {
            ValueAnimator colorAnimation = ValueAnimator.ofObject(new ArgbEvaluator(),
                    mThumbPaint.getColor(), isScrolling ? mThumbActiveColor : mThumbInactiveColor);
            colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animator) {
                    mThumbPaint.setColor((Integer) animator.getAnimatedValue());
                    mRv.invalidate(mThumbOffset.x, mThumbOffset.y, mThumbOffset.x + mThumbWidth,
                            mThumbOffset.y + mThumbHeight);
                }
            });
            mScrollbarAnimator.play(colorAnimation);
        }
        mScrollbarAnimator.setDuration(SCROLL_BAR_VIS_DURATION);
        mScrollbarAnimator.start();
    }

    /**
     * Updates the path for the thumb drawable.
     */
    private void updateThumbPath() {
        mThumbCurvature = mThumbMaxWidth - mThumbWidth;
        mThumbPath.reset();
        mThumbPath.moveTo(mThumbOffset.x + mThumbWidth, mThumbOffset.y);                    // tr
        mThumbPath.lineTo(mThumbOffset.x + mThumbWidth, mThumbOffset.y + mThumbHeight);     // br
        mThumbPath.lineTo(mThumbOffset.x, mThumbOffset.y + mThumbHeight);                   // bl
        mThumbPath.cubicTo(mThumbOffset.x, mThumbOffset.y + mThumbHeight,
                mThumbOffset.x - mThumbCurvature, mThumbOffset.y + mThumbHeight / 2,
                mThumbOffset.x, mThumbOffset.y);                                            // bl2tl
        mThumbPath.close();
    }

    /**
     * Returns whether the specified points are near the scroll bar bounds.
     */
    public boolean isNearThumb(int x, int y) {
        mTmpRect.set(mThumbOffset.x, mThumbOffset.y, mThumbOffset.x + mThumbWidth,
                mThumbOffset.y + mThumbHeight);
        mTmpRect.inset(mTouchInset, mTouchInset);
        return mTmpRect.contains(x, y);
    }
}
