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

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Interpolator;

import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.statusbar.notification.TransformState;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;

import java.util.Stack;

/**
 * A view that can be transformed to and from.
 */
public class ViewTransformationHelper implements TransformableView,
        TransformState.TransformInfo {

    private static final int TAG_CONTAINS_TRANSFORMED_VIEW = R.id.contains_transformed_view;

    private ArrayMap<Integer, View> mTransformedViews = new ArrayMap<>();
    private ArrayMap<Integer, CustomTransformation> mCustomTransformations = new ArrayMap<>();
    private ValueAnimator mViewTransformationAnimation;

    public void addTransformedView(int key, View transformedView) {
        mTransformedViews.put(key, transformedView);
    }

    public void reset() {
        mTransformedViews.clear();
    }

    public void setCustomTransformation(CustomTransformation transformation, int viewType) {
        mCustomTransformations.put(viewType, transformation);
    }

    @Override
    public TransformState getCurrentState(int fadingView) {
        View view = mTransformedViews.get(fadingView);
        if (view != null && view.getVisibility() != View.GONE) {
            return TransformState.createFrom(view, this);
        }
        return null;
    }

    @Override
    public void transformTo(final TransformableView notification, final Runnable endRunnable) {
        if (mViewTransformationAnimation != null) {
            mViewTransformationAnimation.cancel();
        }
        mViewTransformationAnimation = ValueAnimator.ofFloat(0.0f, 1.0f);
        mViewTransformationAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                transformTo(notification, animation.getAnimatedFraction());
            }
        });
        mViewTransformationAnimation.setInterpolator(Interpolators.LINEAR);
        mViewTransformationAnimation.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
        mViewTransformationAnimation.addListener(new AnimatorListenerAdapter() {
            public boolean mCancelled;

            @Override
            public void onAnimationEnd(Animator animation) {
                if (!mCancelled) {
                    if (endRunnable != null) {
                        endRunnable.run();
                    }
                    setVisible(false);
                    mViewTransformationAnimation = null;
                } else {
                    abortTransformations();
                }
            }

            @Override
            public void onAnimationCancel(Animator animation) {
                mCancelled = true;
            }
        });
        mViewTransformationAnimation.start();
    }

    @Override
    public void transformTo(TransformableView notification, float transformationAmount) {
        for (Integer viewType : mTransformedViews.keySet()) {
            TransformState ownState = getCurrentState(viewType);
            if (ownState != null) {
                CustomTransformation customTransformation = mCustomTransformations.get(viewType);
                if (customTransformation != null && customTransformation.transformTo(
                        ownState, notification, transformationAmount)) {
                    ownState.recycle();
                    continue;
                }
                TransformState otherState = notification.getCurrentState(viewType);
                if (otherState != null) {
                    ownState.transformViewTo(otherState, transformationAmount);
                    otherState.recycle();
                } else {
                    ownState.disappear(transformationAmount, notification);
                }
                ownState.recycle();
            }
        }
    }

    @Override
    public void transformFrom(final TransformableView notification) {
        if (mViewTransformationAnimation != null) {
            mViewTransformationAnimation.cancel();
        }
        mViewTransformationAnimation = ValueAnimator.ofFloat(0.0f, 1.0f);
        mViewTransformationAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                transformFrom(notification, animation.getAnimatedFraction());
            }
        });
        mViewTransformationAnimation.addListener(new AnimatorListenerAdapter() {
            public boolean mCancelled;

            @Override
            public void onAnimationEnd(Animator animation) {
                if (!mCancelled) {
                    setVisible(true);
                } else {
                    abortTransformations();
                }
            }

            @Override
            public void onAnimationCancel(Animator animation) {
                mCancelled = true;
            }
        });
        mViewTransformationAnimation.setInterpolator(Interpolators.LINEAR);
        mViewTransformationAnimation.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
        mViewTransformationAnimation.start();
    }

    @Override
    public void transformFrom(TransformableView notification, float transformationAmount) {
        for (Integer viewType : mTransformedViews.keySet()) {
            TransformState ownState = getCurrentState(viewType);
            if (ownState != null) {
                CustomTransformation customTransformation = mCustomTransformations.get(viewType);
                if (customTransformation != null && customTransformation.transformFrom(
                        ownState, notification, transformationAmount)) {
                    ownState.recycle();
                    continue;
                }
                TransformState otherState = notification.getCurrentState(viewType);
                if (otherState != null) {
                    ownState.transformViewFrom(otherState, transformationAmount);
                    otherState.recycle();
                } else {
                    ownState.appear(transformationAmount, notification);
                }
                ownState.recycle();
            }
        }
    }

    @Override
    public void setVisible(boolean visible) {
        if (mViewTransformationAnimation != null) {
            mViewTransformationAnimation.cancel();
        }
        for (Integer viewType : mTransformedViews.keySet()) {
            TransformState ownState = getCurrentState(viewType);
            if (ownState != null) {
                ownState.setVisible(visible, false /* force */);
                ownState.recycle();
            }
        }
    }

    private void abortTransformations() {
        for (Integer viewType : mTransformedViews.keySet()) {
            TransformState ownState = getCurrentState(viewType);
            if (ownState != null) {
                ownState.abortTransformation();
                ownState.recycle();
            }
        }
    }

    /**
     * Add the remaining transformation views such that all views are being transformed correctly
     * @param viewRoot the root below which all elements need to be transformed
     */
    public void addRemainingTransformTypes(View viewRoot) {
        // lets now tag the right views
        int numValues = mTransformedViews.size();
        for (int i = 0; i < numValues; i++) {
            View view = mTransformedViews.valueAt(i);
            while (view != viewRoot.getParent()) {
                view.setTag(TAG_CONTAINS_TRANSFORMED_VIEW, true);
                view = (View) view.getParent();
            }
        }
        Stack<View> stack = new Stack<>();
        // Add the right views now
        stack.push(viewRoot);
        while (!stack.isEmpty()) {
            View child = stack.pop();
            Boolean containsView = (Boolean) child.getTag(TAG_CONTAINS_TRANSFORMED_VIEW);
            if (containsView == null) {
                // This one is unhandled, let's add it to our list.
                int id = child.getId();
                if (id != View.NO_ID) {
                    // We only fade views with an id
                    addTransformedView(id, child);
                    continue;
                }
            }
            child.setTag(TAG_CONTAINS_TRANSFORMED_VIEW, null);
            if (child instanceof ViewGroup && !mTransformedViews.containsValue(child)){
                ViewGroup group = (ViewGroup) child;
                for (int i = 0; i < group.getChildCount(); i++) {
                    stack.push(group.getChildAt(i));
                }
            }
        }
    }

    public void resetTransformedView(View view) {
        TransformState state = TransformState.createFrom(view, this);
        state.setVisible(true /* visible */, true /* force */);
        state.recycle();
    }

    /**
     * @return a set of all views are being transformed.
     */
    public ArraySet<View> getAllTransformingViews() {
        return new ArraySet<>(mTransformedViews.values());
    }

    @Override
    public boolean isAnimating() {
        return mViewTransformationAnimation != null && mViewTransformationAnimation.isRunning();
    }

    public static abstract class CustomTransformation {
        /**
         * Transform a state to the given view
         * @param ownState the state to transform
         * @param notification the view to transform to
         * @param transformationAmount how much transformation should be done
         * @return whether a custom transformation is performed
         */
        public abstract boolean transformTo(TransformState ownState,
                TransformableView notification,
                float transformationAmount);

        /**
         * Transform to this state from the given view
         * @param ownState the state to transform to
         * @param notification the view to transform from
         * @param transformationAmount how much transformation should be done
         * @return whether a custom transformation is performed
         */
        public abstract boolean transformFrom(TransformState ownState,
                TransformableView notification,
                float transformationAmount);

        /**
         * Perform a custom initialisation before transforming.
         *
         * @param ownState our own state
         * @param otherState the other state
         * @return whether a custom initialization is done
         */
        public boolean initTransformation(TransformState ownState,
                TransformState otherState) {
            return false;
        }

        public boolean customTransformTarget(TransformState ownState,
                TransformState otherState) {
            return false;
        }

        /**
         * Get a custom interpolator for this animation
         * @param interpolationType the type of the interpolation, i.e TranslationX / TranslationY
         * @param isFrom true if this transformation from the other view
         */
        public Interpolator getCustomInterpolator(int interpolationType, boolean isFrom) {
            return null;
        }
    }
}
