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

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;

import java.util.ArrayList;

public class KeyguardWidgetCarousel extends KeyguardWidgetPager {

    private float mAdjacentPagesAngle;
    private static float MAX_SCROLL_PROGRESS = 1.3f;
    private static float CAMERA_DISTANCE = 10000;
    protected AnimatorSet mChildrenTransformsAnimator;
    float[] mTmpTransform = new float[3];

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

    public KeyguardWidgetCarousel(Context context) {
        this(context, null, 0);
    }

    public KeyguardWidgetCarousel(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mAdjacentPagesAngle = context.getResources().getInteger(R.integer.kg_carousel_angle);
    }

    protected float getMaxScrollProgress() {
        return MAX_SCROLL_PROGRESS;
    }

    public float getAlphaForPage(int screenCenter, int index, boolean showSidePages) {
        View child = getChildAt(index);
        if (child == null) return 0f;

        boolean inVisibleRange = index >= getNextPage() - 1 && index <= getNextPage() + 1;
        float scrollProgress = getScrollProgress(screenCenter, child, index);

        if (isOverScrollChild(index, scrollProgress)) {
            return 1.0f;
        } else if ((showSidePages && inVisibleRange) || index == getNextPage()) {
            scrollProgress = getBoundedScrollProgress(screenCenter, child, index);
            float alpha = 1.0f - 1.0f * Math.abs(scrollProgress / MAX_SCROLL_PROGRESS);
            return alpha;
        } else {
            return 0f;
        }
    }

    public float getOutlineAlphaForPage(int screenCenter, int index, boolean showSidePages) {
        boolean inVisibleRange = index >= getNextPage() - 1 && index <= getNextPage() + 1;
        if (inVisibleRange) {
            return super.getOutlineAlphaForPage(screenCenter, index, showSidePages);
        } else {
            return 0f;
        }
    }

    private void updatePageAlphaValues(int screenCenter) {
        if (mChildrenOutlineFadeAnimation != null) {
            mChildrenOutlineFadeAnimation.cancel();
            mChildrenOutlineFadeAnimation = null;
        }
        boolean showSidePages = mShowingInitialHints || isPageMoving();
        if (!isReordering(false)) {
            for (int i = 0; i < getChildCount(); i++) {
                KeyguardWidgetFrame child = getWidgetPageAt(i);
                if (child != null) {
                    float outlineAlpha = getOutlineAlphaForPage(screenCenter, i, showSidePages);
                    float contentAlpha = getAlphaForPage(screenCenter, i,showSidePages);
                    child.setBackgroundAlpha(outlineAlpha);
                    child.setContentAlpha(contentAlpha);
                }
            }
        }
    }

    public void showInitialPageHints() {
        mShowingInitialHints = true;
        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            boolean inVisibleRange = i >= getNextPage() - 1 && i <= getNextPage() + 1;
            KeyguardWidgetFrame child = getWidgetPageAt(i);
            if (inVisibleRange) {
                child.setBackgroundAlpha(KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER);
                child.setContentAlpha(1f);
            } else {
                child.setBackgroundAlpha(0f);
                child.setContentAlpha(0f);
            }
        }
    }

    @Override
    protected void screenScrolled(int screenCenter) {
        mScreenCenter = screenCenter;
        updatePageAlphaValues(screenCenter);
        if (isReordering(false)) return;
        for (int i = 0; i < getChildCount(); i++) {
            KeyguardWidgetFrame v = getWidgetPageAt(i);
            float scrollProgress = getScrollProgress(screenCenter, v, i);
            float boundedProgress = getBoundedScrollProgress(screenCenter, v, i);
            if (v == mDragView || v == null) continue;
            v.setCameraDistance(CAMERA_DISTANCE);

            if (isOverScrollChild(i, scrollProgress)) {
                v.setRotationY(- OVERSCROLL_MAX_ROTATION * scrollProgress);
                v.setOverScrollAmount(Math.abs(scrollProgress), scrollProgress < 0);
            } else {
                int width = v.getMeasuredWidth();
                float pivotX = (width / 2f) + boundedProgress * (width / 2f);
                float pivotY = v.getMeasuredHeight() / 2;
                float rotationY = - mAdjacentPagesAngle * boundedProgress;
                v.setPivotX(pivotX);
                v.setPivotY(pivotY);
                v.setRotationY(rotationY);
                v.setOverScrollAmount(0f, false);
            }
            float alpha = v.getAlpha();
            // If the view has 0 alpha, we set it to be invisible so as to prevent
            // it from accepting touches
            if (alpha == 0) {
                v.setVisibility(INVISIBLE);
            } else if (v.getVisibility() != VISIBLE) {
                v.setVisibility(VISIBLE);
            }
        }
    }

    void animatePagesToNeutral() {
        if (mChildrenTransformsAnimator != null) {
            mChildrenTransformsAnimator.cancel();
            mChildrenTransformsAnimator = null;
        }

        int count = getChildCount();
        PropertyValuesHolder alpha;
        PropertyValuesHolder outlineAlpha;
        PropertyValuesHolder rotationY;
        ArrayList<Animator> anims = new ArrayList<Animator>();

        for (int i = 0; i < count; i++) {
            KeyguardWidgetFrame child = getWidgetPageAt(i);
            boolean inVisibleRange = (i >= mCurrentPage - 1 && i <= mCurrentPage + 1);
            if (!inVisibleRange) {
                child.setRotationY(0f);
            }
            alpha = PropertyValuesHolder.ofFloat("contentAlpha", 1.0f);
            outlineAlpha = PropertyValuesHolder.ofFloat("backgroundAlpha",
                    KeyguardWidgetFrame.OUTLINE_ALPHA_MULTIPLIER);
            rotationY = PropertyValuesHolder.ofFloat("rotationY", 0f);
            ObjectAnimator a = ObjectAnimator.ofPropertyValuesHolder(child, alpha, outlineAlpha, rotationY);
            child.setVisibility(VISIBLE);
            if (!inVisibleRange) {
                a.setInterpolator(mSlowFadeInterpolator);
            }
            anims.add(a);
        }

        int duration = REORDERING_ZOOM_IN_OUT_DURATION;
        mChildrenTransformsAnimator = new AnimatorSet();
        mChildrenTransformsAnimator.playTogether(anims);

        mChildrenTransformsAnimator.setDuration(duration);
        mChildrenTransformsAnimator.start();
    }

    private void getTransformForPage(int screenCenter, int index, float[] transform) {
        View child = getChildAt(index);
        float boundedProgress = getBoundedScrollProgress(screenCenter, child, index);
        float rotationY = - mAdjacentPagesAngle * boundedProgress;
        int width = child.getMeasuredWidth();
        float pivotX = (width / 2f) + boundedProgress * (width / 2f);
        float pivotY = child.getMeasuredHeight() / 2;

        transform[0] = pivotX;
        transform[1] = pivotY;
        transform[2] = rotationY;
    }

    Interpolator mFastFadeInterpolator = new Interpolator() {
        Interpolator mInternal = new DecelerateInterpolator(1.5f);
        float mFactor = 2.5f;
        @Override
        public float getInterpolation(float input) {
            return mInternal.getInterpolation(Math.min(mFactor * input, 1f));
        }
    };

    Interpolator mSlowFadeInterpolator = new Interpolator() {
        Interpolator mInternal = new AccelerateInterpolator(1.5f);
        float mFactor = 1.3f;
        @Override
        public float getInterpolation(float input) {
            input -= (1 - 1 / mFactor);
            input = mFactor * Math.max(input, 0f);
            return mInternal.getInterpolation(input);
        }
    };

    void animatePagesToCarousel() {
        if (mChildrenTransformsAnimator != null) {
            mChildrenTransformsAnimator.cancel();
            mChildrenTransformsAnimator = null;
        }

        int count = getChildCount();
        PropertyValuesHolder alpha;
        PropertyValuesHolder outlineAlpha;
        PropertyValuesHolder rotationY;
        PropertyValuesHolder pivotX;
        PropertyValuesHolder pivotY;
        ArrayList<Animator> anims = new ArrayList<Animator>();

        for (int i = 0; i < count; i++) {
            KeyguardWidgetFrame child = getWidgetPageAt(i);
            float finalAlpha = getAlphaForPage(mScreenCenter, i, true);
            float finalOutlineAlpha = getOutlineAlphaForPage(mScreenCenter, i, true);
            getTransformForPage(mScreenCenter, i, mTmpTransform);

            boolean inVisibleRange = (i >= mCurrentPage - 1 && i <= mCurrentPage + 1);

            ObjectAnimator a;
            alpha = PropertyValuesHolder.ofFloat("contentAlpha", finalAlpha);
            outlineAlpha = PropertyValuesHolder.ofFloat("backgroundAlpha", finalOutlineAlpha);
            pivotX = PropertyValuesHolder.ofFloat("pivotX", mTmpTransform[0]);
            pivotY = PropertyValuesHolder.ofFloat("pivotY", mTmpTransform[1]);
            rotationY = PropertyValuesHolder.ofFloat("rotationY", mTmpTransform[2]);

            if (inVisibleRange) {
                // for the central pages we animate into a rotated state
                a = ObjectAnimator.ofPropertyValuesHolder(child, alpha, outlineAlpha,
                        pivotX, pivotY, rotationY);
            } else {
                a = ObjectAnimator.ofPropertyValuesHolder(child, alpha, outlineAlpha);
                a.setInterpolator(mFastFadeInterpolator);
            }
            anims.add(a);
        }

        int duration = REORDERING_ZOOM_IN_OUT_DURATION;
        mChildrenTransformsAnimator = new AnimatorSet();
        mChildrenTransformsAnimator.playTogether(anims);

        mChildrenTransformsAnimator.setDuration(duration);
        mChildrenTransformsAnimator.start();
    }

    protected void reorderStarting() {
        mViewStateManager.fadeOutSecurity(REORDERING_ZOOM_IN_OUT_DURATION);
        animatePagesToNeutral();
    }

    protected boolean zoomIn(final Runnable onCompleteRunnable) {
        animatePagesToCarousel();
        return super.zoomIn(onCompleteRunnable);
    }

    @Override
    protected void onEndReordering() {
        super.onEndReordering();
        mViewStateManager.fadeInSecurity(REORDERING_ZOOM_IN_OUT_DURATION);
    }
}
