/*
 * 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 ArraySet<Integer> mKeysTransformingToSimilar = new ArraySet<>();
    private ArrayMap<Integer, CustomTransformation> mCustomTransformations = new ArrayMap<>();
    private ValueAnimator mViewTransformationAnimation;

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

    /**
     * Add a view that transforms to a similar sibling, meaning that we should consider any mapping
     * found treated as the same viewType. This is useful for imageViews, where it's hard to compare
     * if the source images are the same when they are bitmap based.
     *
     * @param key The key how this is added
     * @param transformedView the view that is added
     */
    public void addViewTransformingToSimilar(int key, View transformedView) {
        addTransformedView(key, transformedView);
        mKeysTransformingToSimilar.add(key);
    }

    public void reset() {
        mTransformedViews.clear();
        mKeysTransformingToSimilar.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) {
            TransformState transformState = TransformState.createFrom(view, this);
            if (mKeysTransformingToSimilar.contains(fadingView)) {
                transformState.setIsSameAsAnyView(true);
            }
            return transformState;
        }
        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;
        }
    }
}
