/*
 * Copyright (C) 2011 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.gallery3d.ui;


// This is a customized version of Scroller, with a interface similar to
// android.widget.Scroller. It does fling only, not scroll.
//
// The differences between the this Scroller and the system one are:
//
// (1) The velocity does not change because of min/max limit.
// (2) The duration is different.
// (3) The deceleration curve is different.
class FlingScroller {
    @SuppressWarnings("unused")
    private static final String TAG = "FlingController";

    // The fling duration (in milliseconds) when velocity is 1 pixel/second
    private static final float FLING_DURATION_PARAM = 50f;
    private static final int DECELERATED_FACTOR = 4;

    private int mStartX, mStartY;
    private int mMinX, mMinY, mMaxX, mMaxY;
    private double mSinAngle;
    private double mCosAngle;
    private int mDuration;
    private int mDistance;
    private int mFinalX, mFinalY;

    private int mCurrX, mCurrY;
    private double mCurrV;

    public int getFinalX() {
        return mFinalX;
    }

    public int getFinalY() {
        return mFinalY;
    }

    public int getDuration() {
        return mDuration;
    }

    public int getCurrX() {
        return mCurrX;

    }

    public int getCurrY() {
        return mCurrY;
    }

    public int getCurrVelocityX() {
        return (int)Math.round(mCurrV * mCosAngle);
    }

    public int getCurrVelocityY() {
        return (int)Math.round(mCurrV * mSinAngle);
    }

    public void fling(int startX, int startY, int velocityX, int velocityY,
            int minX, int maxX, int minY, int maxY) {
        mStartX = startX;
        mStartY = startY;
        mMinX = minX;
        mMinY = minY;
        mMaxX = maxX;
        mMaxY = maxY;

        double velocity = Math.hypot(velocityX, velocityY);
        mSinAngle = velocityY / velocity;
        mCosAngle = velocityX / velocity;
        //
        // The position formula: x(t) = s + (e - s) * (1 - (1 - t / T) ^ d)
        //     velocity formula: v(t) = d * (e - s) * (1 - t / T) ^ (d - 1) / T
        // Thus,
        //     v0 = d * (e - s) / T => (e - s) = v0 * T / d
        //

        // Ta = T_ref * (Va / V_ref) ^ (1 / (d - 1)); V_ref = 1 pixel/second;
        mDuration = (int)Math.round(FLING_DURATION_PARAM
                * Math.pow(Math.abs(velocity), 1.0 / (DECELERATED_FACTOR - 1)));

        // (e - s) = v0 * T / d
        mDistance = (int)Math.round(
                velocity * mDuration / DECELERATED_FACTOR / 1000);

        mFinalX = getX(1.0f);
        mFinalY = getY(1.0f);
    }

    public void computeScrollOffset(float progress) {
        progress = Math.min(progress, 1);
        float f = 1 - progress;
        f = 1 - (float) Math.pow(f, DECELERATED_FACTOR);
        mCurrX = getX(f);
        mCurrY = getY(f);
        mCurrV = getV(progress);
    }

    private int getX(float f) {
        int r = (int) Math.round(mStartX + f * mDistance * mCosAngle);
        if (mCosAngle > 0 && mStartX <= mMaxX) {
            r = Math.min(r, mMaxX);
        } else if (mCosAngle < 0 && mStartX >= mMinX) {
            r = Math.max(r, mMinX);
        }
        return r;
    }

    private int getY(float f) {
        int r = (int) Math.round(mStartY + f * mDistance * mSinAngle);
        if (mSinAngle > 0 && mStartY <= mMaxY) {
            r = Math.min(r, mMaxY);
        } else if (mSinAngle < 0 && mStartY >= mMinY) {
            r = Math.max(r, mMinY);
        }
        return r;
    }

    private double getV(float progress) {
        // velocity formula: v(t) = d * (e - s) * (1 - t / T) ^ (d - 1) / T
        return DECELERATED_FACTOR * mDistance * 1000 *
                Math.pow(1 - progress, DECELERATED_FACTOR - 1) / mDuration;
    }
}
