package com.android.launcher3.pageindicators;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.graphics.ColorUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.util.Property;
import android.view.View;
import android.view.ViewConfiguration;

import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.dynamicui.ExtractedColors;
import com.android.launcher3.util.TransformingTouchDelegate;

/**
 * A PageIndicator that briefly shows a fraction of a line when moving between pages.
 *
 * The fraction is 1 / number of pages and the position is based on the progress of the page scroll.
 */
public class PageIndicatorLineCaret extends PageIndicator {
    private static final String TAG = "PageIndicatorLine";

    private static final int[] sTempCoords = new int[2];

    private static final int LINE_ANIMATE_DURATION = ViewConfiguration.getScrollBarFadeDuration();
    private static final int LINE_FADE_DELAY = ViewConfiguration.getScrollDefaultDelay();
    public static final int WHITE_ALPHA = (int) (0.70f * 255);
    public static final int BLACK_ALPHA = (int) (0.65f * 255);

    private static final int LINE_ALPHA_ANIMATOR_INDEX = 0;
    private static final int NUM_PAGES_ANIMATOR_INDEX = 1;
    private static final int TOTAL_SCROLL_ANIMATOR_INDEX = 2;

    private ValueAnimator[] mAnimators = new ValueAnimator[3];

    private final Handler mDelayedLineFadeHandler = new Handler(Looper.getMainLooper());

    private boolean mShouldAutoHide = true;

    // The alpha of the line when it is showing.
    private int mActiveAlpha = 0;
    // The alpha that the line is being animated to or already at (either 0 or mActiveAlpha).
    private int mToAlpha;
    // A float value representing the number of pages, to allow for an animation when it changes.
    private float mNumPagesFloat;
    private int mCurrentScroll;
    private int mTotalScroll;
    private Paint mLinePaint;
    private Launcher mLauncher;
    private final int mLineHeight;
    private final TransformingTouchDelegate mTouchDelegate;
    private final int mTouchExtensionHeight;
    private final int mCaretSizePx;
    private final int mCaretWorkspaceOffsetPx;

    private static final Property<PageIndicatorLineCaret, Integer> PAINT_ALPHA
            = new Property<PageIndicatorLineCaret, Integer>(Integer.class, "paint_alpha") {
        @Override
        public Integer get(PageIndicatorLineCaret obj) {
            return obj.mLinePaint.getAlpha();
        }

        @Override
        public void set(PageIndicatorLineCaret obj, Integer alpha) {
            obj.mLinePaint.setAlpha(alpha);
            obj.invalidate();
        }
    };

    private static final Property<PageIndicatorLineCaret, Float> NUM_PAGES
            = new Property<PageIndicatorLineCaret, Float>(Float.class, "num_pages") {
        @Override
        public Float get(PageIndicatorLineCaret obj) {
            return obj.mNumPagesFloat;
        }

        @Override
        public void set(PageIndicatorLineCaret obj, Float numPages) {
            obj.mNumPagesFloat = numPages;
            obj.invalidate();
        }
    };

    private static final Property<PageIndicatorLineCaret, Integer> TOTAL_SCROLL
            = new Property<PageIndicatorLineCaret, Integer>(Integer.class, "total_scroll") {
        @Override
        public Integer get(PageIndicatorLineCaret obj) {
            return obj.mTotalScroll;
        }

        @Override
        public void set(PageIndicatorLineCaret obj, Integer totalScroll) {
            obj.mTotalScroll = totalScroll;
            obj.invalidate();
        }
    };

    private Runnable mHideLineRunnable = new Runnable() {
        @Override
        public void run() {
            animateLineToAlpha(0);
        }
    };

    public PageIndicatorLineCaret(Context context) {
        this(context, null);
    }

    public PageIndicatorLineCaret(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PageIndicatorLineCaret(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        Resources res = context.getResources();
        mLinePaint = new Paint();
        mLinePaint.setAlpha(0);
        mCaretSizePx = res.getDimensionPixelSize(R.dimen.all_apps_caret_size);
        mCaretWorkspaceOffsetPx = res.getDimensionPixelSize(
                R.dimen.all_apps_caret_workspace_offset);

        mLauncher = (Launcher) context;
        setOnTouchListener(mLauncher.getHapticFeedbackTouchListener());
        setOnClickListener(mLauncher);
        setOnLongClickListener(mLauncher);
        setOnFocusChangeListener(mLauncher.mFocusHandler);
        setCaretDrawable(new CaretDrawable(context));
        mLineHeight = res.getDimensionPixelSize(R.dimen.dynamic_grid_page_indicator_line_height);
        mTouchExtensionHeight = res.getDimensionPixelSize(
                R.dimen.dynamic_grid_page_indicator_extra_touch_height);
        mTouchDelegate = new TransformingTouchDelegate(this);
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        mLauncher.getDragLayer().setTouchDelegate(mTouchDelegate);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        // Top/center align the caret in the page indicator space
        int l = (right - left) / 2 - mCaretSizePx / 2;
        getCaretDrawable().setBounds(l, mCaretWorkspaceOffsetPx, l + mCaretSizePx,
                mCaretWorkspaceOffsetPx + mCaretSizePx);

        // The touch area is expanded below this view by #mTouchExtensionHeight
        // which extends to the top of the hotseat.
        View parent = mLauncher.getDragLayer();
        sTempCoords[0] = sTempCoords[1] = 0;
        Utilities.getDescendantCoordRelativeToAncestor(this, parent, sTempCoords, true);
        mTouchDelegate.setBounds(sTempCoords[0], sTempCoords[1], sTempCoords[0] + this.getWidth(),
                sTempCoords[1] + getHeight() + mTouchExtensionHeight);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        getCaretDrawable().draw(canvas);
        if (mTotalScroll == 0 || mNumPagesFloat == 0) {
            return;
        }

        // Compute and draw line rect.
        float progress = Utilities.boundToRange(((float) mCurrentScroll) / mTotalScroll, 0f, 1f);
        int availableWidth = canvas.getWidth();
        int lineWidth = (int) (availableWidth / mNumPagesFloat);
        int lineLeft = (int) (progress * (availableWidth - lineWidth));
        int lineRight = lineLeft + lineWidth;
        canvas.drawRect(lineLeft, canvas.getHeight() - mLineHeight, lineRight, canvas.getHeight(),
                mLinePaint);
    }

    @Override
    public void setScroll(int currentScroll, int totalScroll) {
        if (getAlpha() == 0) {
            return;
        }
        animateLineToAlpha(mActiveAlpha);

        mCurrentScroll = currentScroll;
        if (mTotalScroll == 0) {
            mTotalScroll = totalScroll;
        } else if (mTotalScroll != totalScroll) {
            animateToTotalScroll(totalScroll);
        } else {
            invalidate();
        }

        if (mShouldAutoHide) {
            hideAfterDelay();
        }
    }

    private void hideAfterDelay() {
        mDelayedLineFadeHandler.removeCallbacksAndMessages(null);
        mDelayedLineFadeHandler.postDelayed(mHideLineRunnable, LINE_FADE_DELAY);
    }

    @Override
    public void setActiveMarker(int activePage) {
    }

    @Override
    protected void onPageCountChanged() {
        if (Float.compare(mNumPages, mNumPagesFloat) != 0) {
            animateToNumPages(mNumPages);
        }
    }

    public void setShouldAutoHide(boolean shouldAutoHide) {
        mShouldAutoHide = shouldAutoHide;
        if (shouldAutoHide && mLinePaint.getAlpha() > 0) {
            hideAfterDelay();
        } else if (!shouldAutoHide) {
            mDelayedLineFadeHandler.removeCallbacksAndMessages(null);
        }
    }

    /**
     * The line's color will be:
     * - mostly opaque white if the hotseat is white (ignoring alpha)
     * - mostly opaque black if the hotseat is black (ignoring alpha)
     */
    public void updateColor(ExtractedColors extractedColors) {
        int originalLineAlpha = mLinePaint.getAlpha();
        int color = extractedColors.getColor(ExtractedColors.HOTSEAT_INDEX, Color.TRANSPARENT);
        if (color != Color.TRANSPARENT) {
            color = ColorUtils.setAlphaComponent(color, 255);
            if (color == Color.BLACK) {
                mActiveAlpha = BLACK_ALPHA;
            } else if (color == Color.WHITE) {
                mActiveAlpha = WHITE_ALPHA;
            } else {
                Log.e(TAG, "Setting workspace page indicators to an unsupported color: #"
                        + Integer.toHexString(color));
            }
            mLinePaint.setColor(color);
            mLinePaint.setAlpha(originalLineAlpha);
        }
    }

    private void animateLineToAlpha(int alpha) {
        if (alpha == mToAlpha) {
            // Ignore the new animation if it is going to the same alpha as the current animation.
            return;
        }
        mToAlpha = alpha;
        setupAndRunAnimation(ObjectAnimator.ofInt(this, PAINT_ALPHA, alpha),
                LINE_ALPHA_ANIMATOR_INDEX);
    }

    private void animateToNumPages(int numPages) {
        setupAndRunAnimation(ObjectAnimator.ofFloat(this, NUM_PAGES, numPages),
                NUM_PAGES_ANIMATOR_INDEX);
    }

    private void animateToTotalScroll(int totalScroll) {
        setupAndRunAnimation(ObjectAnimator.ofInt(this, TOTAL_SCROLL, totalScroll),
                TOTAL_SCROLL_ANIMATOR_INDEX);
    }

    /**
     * Starts the given animator and stores it in the provided index in {@link #mAnimators} until
     * the animation ends.
     *
     * If an animator is already at the index (i.e. it is already playing), it is canceled and
     * replaced with the new animator.
     */
    private void setupAndRunAnimation(ValueAnimator animator, final int animatorIndex) {
        if (mAnimators[animatorIndex] != null) {
            mAnimators[animatorIndex].cancel();
        }
        mAnimators[animatorIndex] = animator;
        mAnimators[animatorIndex].addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                mAnimators[animatorIndex] = null;
            }
        });
        mAnimators[animatorIndex].setDuration(LINE_ANIMATE_DURATION);
        mAnimators[animatorIndex].start();
    }
}
