/*
 * 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 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);
                startShowAnimation();
            }
        });
    }

    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 int chevronPosY() {
        final Object tag = mChevron == null ? null : mChevron.getTag();
        return tag == null ? 0 : (Integer) tag;
    }

    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 = chevronPosY();
                        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();
            if (mContentsPositionAnimator != null) {
                mContentsPositionAnimator.cancel();
            }
            mContents.animate().cancel();
            if (mChevronPositionAnimator != null) {
                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());
                        final int posY = chevronPosY();
                        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);
    }
}
