/*
 * 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.systemui.volume;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnDismissListener;
import android.content.DialogInterface.OnShowListener;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.PathInterpolator;

public class VolumeDialogMotion {
    private static final String TAG = Util.logTag(VolumeDialogMotion.class);

    private static final float ANIMATION_SCALE = 1.0f;
    private static final int PRE_DISMISS_DELAY = 50;
    private static final int POST_SHOW_DELAY = 200;

    private final Dialog mDialog;
    private final View mDialogView;
    private final ViewGroup mContents;  // volume rows + zen footer
    private final View mChevron;
    private final Handler mHandler = new Handler();
    private final Callback mCallback;

    private boolean mAnimating;  // show or dismiss animation is running
    private boolean mShowing;  // show animation is running
    private boolean mDismissing;  // dismiss animation is running
    private ValueAnimator mChevronPositionAnimator;
    private ValueAnimator mContentsPositionAnimator;

    public VolumeDialogMotion(Dialog dialog, View dialogView, ViewGroup contents, View chevron,
            Callback callback) {
        mDialog = dialog;
        mDialogView = dialogView;
        mContents = contents;
        mChevron = chevron;
        mCallback = callback;
        mDialog.setOnDismissListener(new OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialog) {
                if (D.BUG) Log.d(TAG, "mDialog.onDismiss");
            }
        });
        mDialog.setOnShowListener(new OnShowListener() {
            @Override
            public void onShow(DialogInterface dialog) {
                if (D.BUG) Log.d(TAG, "mDialog.onShow");
                final int h = mDialogView.getHeight();
                mDialogView.setTranslationY(-h);
                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        startShowAnimation();
                    }
                }, POST_SHOW_DELAY);
            }
        });
    }

    public boolean isAnimating() {
        return mAnimating;
    }

    private void setShowing(boolean showing) {
        if (showing == mShowing) return;
        mShowing = showing;
        if (D.BUG) Log.d(TAG, "mShowing = " + mShowing);
        updateAnimating();
    }

    private void setDismissing(boolean dismissing) {
        if (dismissing == mDismissing) return;
        mDismissing = dismissing;
        if (D.BUG) Log.d(TAG, "mDismissing = " + mDismissing);
        updateAnimating();
    }

    private void updateAnimating() {
        final boolean animating = mShowing || mDismissing;
        if (animating == mAnimating) return;
        mAnimating = animating;
        if (D.BUG) Log.d(TAG, "mAnimating = " + mAnimating);
        if (mCallback != null) {
            mCallback.onAnimatingChanged(mAnimating);
        }
    }

    public void startShow() {
        if (D.BUG) Log.d(TAG, "startShow");
        if (mShowing) return;
        setShowing(true);
        if (mDismissing) {
            mDialogView.animate().cancel();
            setDismissing(false);
            startShowAnimation();
            return;
        }
        if (D.BUG) Log.d(TAG, "mDialog.show()");
        mDialog.show();
    }

    private int chevronDistance() {
        return mChevron.getHeight() / 6;
    }

    private void startShowAnimation() {
        if (D.BUG) Log.d(TAG, "startShowAnimation");
        mDialogView.animate()
                .translationY(0)
                .setDuration(scaledDuration(300))
                .setInterpolator(new LogDecelerateInterpolator())
                .setListener(null)
                .setUpdateListener(new AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        if (mChevronPositionAnimator == null) return;
                        // reposition chevron
                        final float v = (Float) mChevronPositionAnimator.getAnimatedValue();
                        final int posY = (Integer) mChevron.getTag();
                        mChevron.setTranslationY(posY + v + -mDialogView.getTranslationY());
                    }})
                .start();

        mContentsPositionAnimator = ValueAnimator.ofFloat(-chevronDistance(), 0)
                .setDuration(scaledDuration(400));
        mContentsPositionAnimator.addListener(new AnimatorListenerAdapter() {
            private boolean mCancelled;

            @Override
            public void onAnimationEnd(Animator animation) {
                if (mCancelled) return;
                if (D.BUG) Log.d(TAG, "show.onAnimationEnd");
                setShowing(false);
            }
            @Override
            public void onAnimationCancel(Animator animation) {
                if (D.BUG) Log.d(TAG, "show.onAnimationCancel");
                mCancelled = true;
            }
        });
        mContentsPositionAnimator.addUpdateListener(new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float v = (Float) animation.getAnimatedValue();
                mContents.setTranslationY(v + -mDialogView.getTranslationY());
            }
        });
        mContentsPositionAnimator.setInterpolator(new LogDecelerateInterpolator());
        mContentsPositionAnimator.start();

        mContents.setAlpha(0);
        mContents.animate()
                .alpha(1)
                .setDuration(scaledDuration(150))
                .setInterpolator(new PathInterpolator(0f, 0f, .2f, 1f))
                .start();

        mChevronPositionAnimator = ValueAnimator.ofFloat(-chevronDistance(), 0)
                .setDuration(scaledDuration(250));
        mChevronPositionAnimator.setInterpolator(new PathInterpolator(.4f, 0f, .2f, 1f));
        mChevronPositionAnimator.start();

        mChevron.setAlpha(0);
        mChevron.animate()
                .alpha(1)
                .setStartDelay(scaledDuration(50))
                .setDuration(scaledDuration(150))
                .setInterpolator(new PathInterpolator(.4f, 0f, 1f, 1f))
                .start();
    }

    public void startDismiss(final Runnable onComplete) {
        if (D.BUG) Log.d(TAG, "startDismiss");
        if (mDismissing) return;
        setDismissing(true);
        if (mShowing) {
            mDialogView.animate().cancel();
            mContentsPositionAnimator.cancel();
            mContents.animate().cancel();
            mChevronPositionAnimator.cancel();
            mChevron.animate().cancel();
            setShowing(false);
        }
        mDialogView.animate()
                .translationY(-mDialogView.getHeight())
                .setDuration(scaledDuration(250))
                .setInterpolator(new LogAccelerateInterpolator())
                .setUpdateListener(new AnimatorUpdateListener() {
                    @Override
                    public void onAnimationUpdate(ValueAnimator animation) {
                        mContents.setTranslationY(-mDialogView.getTranslationY());
                        int posY = (Integer) mChevron.getTag();
                        mChevron.setTranslationY(posY + -mDialogView.getTranslationY());
                    }
                })
                .setListener(new AnimatorListenerAdapter() {
                    private boolean mCancelled;
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        if (mCancelled) return;
                        if (D.BUG) Log.d(TAG, "dismiss.onAnimationEnd");
                        mHandler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                if (D.BUG) Log.d(TAG, "mDialog.dismiss()");
                                mDialog.dismiss();
                                onComplete.run();
                                setDismissing(false);
                            }
                        }, PRE_DISMISS_DELAY);

                    }
                    @Override
                    public void onAnimationCancel(Animator animation) {
                        if (D.BUG) Log.d(TAG, "dismiss.onAnimationCancel");
                        mCancelled = true;
                    }
                }).start();
    }

    private static int scaledDuration(int base) {
        return (int) (base * ANIMATION_SCALE);
    }

    private static final class LogDecelerateInterpolator implements TimeInterpolator {
        private final float mBase;
        private final float mDrift;
        private final float mTimeScale;
        private final float mOutputScale;

        private LogDecelerateInterpolator() {
            this(400f, 1.4f, 0);
        }

        private LogDecelerateInterpolator(float base, float timeScale, float drift) {
            mBase = base;
            mDrift = drift;
            mTimeScale = 1f / timeScale;

            mOutputScale = 1f / computeLog(1f);
        }

        private float computeLog(float t) {
            return 1f - (float) Math.pow(mBase, -t * mTimeScale) + (mDrift * t);
        }

        @Override
        public float getInterpolation(float t) {
            return computeLog(t) * mOutputScale;
        }
    }

    private static final class LogAccelerateInterpolator implements TimeInterpolator {
        private final int mBase;
        private final int mDrift;
        private final float mLogScale;

        private LogAccelerateInterpolator() {
            this(100, 0);
        }

        private LogAccelerateInterpolator(int base, int drift) {
            mBase = base;
            mDrift = drift;
            mLogScale = 1f / computeLog(1, mBase, mDrift);
        }

        private static float computeLog(float t, int base, int drift) {
            return (float) -Math.pow(base, -t) + 1 + (drift * t);
        }

        @Override
        public float getInterpolation(float t) {
            return 1 - computeLog(1 - t, mBase, mDrift) * mLogScale;
        }
    }

    public interface Callback {
        void onAnimatingChanged(boolean animating);
    }
}
