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

import android.animation.ObjectAnimator;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;

import com.android.launcher3.Launcher;
import com.android.launcher3.R;
import com.android.launcher3.pageindicators.CaretDrawable;

public class AllAppsCaretController {
    // Determines when the caret should flip. Should be accessed via getThreshold()
    private static final float CARET_THRESHOLD = 0.015f;
    private static final float CARET_THRESHOLD_LAND = 0.5f;
    // The velocity at which the caret will peak (i.e. exhibit a 90 degree bend)
    private static final float PEAK_VELOCITY = VerticalPullDetector.RELEASE_VELOCITY_PX_MS * .7f;

    private Launcher mLauncher;

    private ObjectAnimator mCaretAnimator;
    private CaretDrawable mCaretDrawable;
    private float mLastCaretProgress;
    private boolean mThresholdCrossed;

    public AllAppsCaretController(CaretDrawable caret, Launcher launcher) {
        mLauncher = launcher;
        mCaretDrawable = caret;

        final long caretAnimationDuration = launcher.getResources().getInteger(
                R.integer.config_caretAnimationDuration);
        final Interpolator caretInterpolator = AnimationUtils.loadInterpolator(launcher,
                android.R.interpolator.fast_out_slow_in);

        // We will set values later
        mCaretAnimator = ObjectAnimator.ofFloat(mCaretDrawable, "caretProgress", 0);
        mCaretAnimator.setDuration(caretAnimationDuration);
        mCaretAnimator.setInterpolator(caretInterpolator);
    }

    /**
     * Updates the state of the caret based on the progress of the {@link AllAppsContainerView}, as
     * defined by the {@link AllAppsTransitionController}. Uses the container's velocity to adjust
     * angle of caret.
     *
     * @param containerProgress The progress of the container in the range [0..1]
     * @param velocity The velocity of the container
     * @param dragging {@code true} if the container is being dragged
     */
    public void updateCaret(float containerProgress, float velocity, boolean dragging) {
        // If we're in portrait and the shift is not 0 or 1, adjust the caret based on velocity
        if (getThreshold() < containerProgress && containerProgress < 1 - getThreshold() &&
                !mLauncher.useVerticalBarLayout()) {
            mThresholdCrossed = true;

            // How fast are we moving as a percentage of the peak velocity?
            final float pctOfFlingVelocity = Math.max(-1, Math.min(velocity / PEAK_VELOCITY, 1));

            mCaretDrawable.setCaretProgress(pctOfFlingVelocity);

            // Set the last caret progress to this progress to prevent animator cancellation
            mLastCaretProgress = pctOfFlingVelocity;
            // Animate to neutral. This is necessary so the caret doesn't "freeze" when the
            // container stops moving (e.g., during a drag or when the threshold is reached).
            animateCaretToProgress(CaretDrawable.PROGRESS_CARET_NEUTRAL);
        } else if (!dragging) {
            // Otherwise, if we're not dragging, match the caret to the appropriate state
            if (containerProgress <= getThreshold()) { // All Apps is up
                animateCaretToProgress(CaretDrawable.PROGRESS_CARET_POINTING_DOWN);
            } else if (containerProgress >= 1 - getThreshold()) { // All Apps is down
                animateCaretToProgress(CaretDrawable.PROGRESS_CARET_POINTING_UP);
            }
        }
    }

    private void animateCaretToProgress(float progress) {
        // If the new progress is the same as the last progress we animated to, terminate early
        if (Float.compare(mLastCaretProgress, progress) == 0) {
            return;
        }

        if (mCaretAnimator.isRunning()) {
            mCaretAnimator.cancel(); // Stop the animator in its tracks
        }

        // Update the progress and start the animation
        mLastCaretProgress = progress;
        mCaretAnimator.setFloatValues(progress);
        mCaretAnimator.start();
    }

    private float getThreshold() {
        // In landscape, just return the landscape threshold.
        if (mLauncher.useVerticalBarLayout()) {
            return CARET_THRESHOLD_LAND;
        }

        // Before the threshold is crossed, it is reported as zero. This makes the caret immediately
        // responsive when a drag begins. After the threshold is crossed, we return the constant
        // value. This means the caret will start its state-based adjustment sooner. That is, we
        // won't have to wait until the panel is completely settled to begin animation.
        return mThresholdCrossed ? CARET_THRESHOLD : 0f;
    }

    public void onDragStart() {
        mThresholdCrossed = false;
    }
}
