/*
 * 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.contacts.editor;

import android.animation.Animator;
import android.animation.Animator.AnimatorListener;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.LinearLayout;
import android.widget.ScrollView;

import com.android.contacts.util.SchedulingUtils;
import com.google.common.collect.Lists;

import java.util.List;

/**
 * Configures animations for typical use-cases
 */
public class EditorAnimator {
    private static EditorAnimator sInstance = new EditorAnimator();

    public static  EditorAnimator getInstance() {
        return sInstance;
    }

    /** Private constructor for singleton */
    private EditorAnimator() { }

    private AnimatorRunner mRunner = new AnimatorRunner();

    public void removeEditorView(final View victim) {
        mRunner.endOldAnimation();
        final int offset = victim.getHeight();

        final List<View> viewsToMove = getViewsBelowOf(victim);
        final List<Animator> animators = Lists.newArrayList();

        // Fade out
        final ObjectAnimator fadeOutAnimator =
                ObjectAnimator.ofFloat(victim, View.ALPHA, 1.0f, 0.0f);
        fadeOutAnimator.setDuration(200);
        animators.add(fadeOutAnimator);

        // Translations
        translateViews(animators, viewsToMove, 0.0f, -offset, 100, 200);

        mRunner.run(animators, new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                // Clean up: Remove all the translations
                for (int i = 0; i < viewsToMove.size(); i++) {
                    final View view = viewsToMove.get(i);
                    view.setTranslationY(0.0f);
                }
                // Remove our target view (if parent is null, we were run several times by quick
                // fingers. Just ignore)
                final ViewGroup victimParent = (ViewGroup) victim.getParent();
                if (victimParent != null) {
                    victimParent.removeView(victim);
                }
            }
        });
    }

    /**
     * Slides the view into its new height, while simultaneously fading it into view.
     *
     * @param target The target view to perform the animation on.
     * @param previousHeight The previous height of the view before its height was changed.
     * Needed because the view does not store any state information about its previous height.
     */
    public void slideAndFadeIn(final ViewGroup target, final int previousHeight) {
        mRunner.endOldAnimation();
        target.setVisibility(View.VISIBLE);
        target.setAlpha(0.0f);
        SchedulingUtils.doAfterLayout(target, new Runnable() {
            @Override
            public void run() {
                final int offset = target.getHeight() - previousHeight;
                final List<Animator> animators = Lists.newArrayList();

                // Translations
                final List<View> viewsToMove = getViewsBelowOf(target);

                translateViews(animators, viewsToMove, -offset, 0.0f, 0, 200);

                // Fade in
                final ObjectAnimator fadeInAnimator = ObjectAnimator.ofFloat(
                        target, View.ALPHA, 0.0f, 1.0f);
                fadeInAnimator.setDuration(200);
                fadeInAnimator.setStartDelay(200);
                animators.add(fadeInAnimator);

                mRunner.run(animators);
            }
        });
    }

    public void showFieldFooter(final View view) {
        mRunner.endOldAnimation();
        if (view.getVisibility() == View.VISIBLE) return;
        // Make the new controls visible and do one layout pass (so that we can measure)
        view.setVisibility(View.VISIBLE);
        view.setAlpha(0.0f);
        SchedulingUtils.doAfterLayout(view, new Runnable() {
            @Override
            public void run() {
                // How many pixels extra do we need?
                final int offset = view.getHeight();

                final List<Animator> animators = Lists.newArrayList();

                // Translations
                final List<View> viewsToMove = getViewsBelowOf(view);
                translateViews(animators, viewsToMove, -offset, 0.0f, 0, 200);

                // Fade in
                final ObjectAnimator fadeInAnimator = ObjectAnimator.ofFloat(
                        view, View.ALPHA, 0.0f, 1.0f);
                fadeInAnimator.setDuration(200);
                fadeInAnimator.setStartDelay(200);
                animators.add(fadeInAnimator);

                mRunner.run(animators);
            }
        });
    }

    /**
     * Smoothly scroll {@param targetView}'s parent ScrollView to the top of {@param targetView}.
     */
    public void scrollViewToTop(final View targetView) {
        final ScrollView scrollView = getParentScrollView(targetView);
        SchedulingUtils.doAfterLayout(scrollView, new Runnable() {
            @Override
            public void run() {
                ScrollView scrollView = getParentScrollView(targetView);
                scrollView.smoothScrollTo(0, offsetFromTopOfViewGroup(targetView, scrollView)
                        + scrollView.getScrollY());
            }
        });
        // Clear the focused element so it doesn't interfere with scrolling.
        View view = scrollView.findFocus();
        if (view != null) {
            view.clearFocus();
        }
    }

    public static void placeFocusAtTopOfScreenAfterReLayout(final View view) {
        // In order for the focus to be placed at the top of the Window, we need
        // to wait for layout. Otherwise we don't know where the top of the screen is.
        SchedulingUtils.doAfterLayout(view, new Runnable() {
            @Override
            public void run() {
                EditorAnimator.getParentScrollView(view).clearFocus();
            }
        });
    }

    private int offsetFromTopOfViewGroup(View view, ViewGroup viewGroup) {
        int viewLocation[] = new int[2];
        int viewGroupLocation[] = new int[2];
        viewGroup.getLocationOnScreen(viewGroupLocation);
        view.getLocationOnScreen(viewLocation);
        return viewLocation[1] - viewGroupLocation[1];
    }

    private static ScrollView getParentScrollView(View view) {
        while (true) {
            ViewParent parent = view.getParent();
            if (parent instanceof ScrollView)
                return (ScrollView) parent;
            if (!(parent instanceof View))
                throw new IllegalArgumentException(
                        "The editor should be contained inside a ScrollView.");
            view = (View) parent;
        }
    }

    /**
     * Creates a translation-animation for the given views
     */
    private static void translateViews(List<Animator> animators, List<View> views, float fromY,
            float toY, int startDelay, int duration) {
        for (int i = 0; i < views.size(); i++) {
            final View child = views.get(i);
            final ObjectAnimator translateAnimator =
                    ObjectAnimator.ofFloat(child, View.TRANSLATION_Y, fromY, toY);
            translateAnimator.setStartDelay(startDelay);
            translateAnimator.setDuration(duration);
            animators.add(translateAnimator);
        }
    }

    /**
     * Traverses up the view hierarchy and returns all views physically below this item.
     *
     * @return List of views that are below the given view. Empty list if parent of view is null.
     */
    private static List<View> getViewsBelowOf(View view) {
        final ViewGroup victimParent = (ViewGroup) view.getParent();
        final List<View> result = Lists.newArrayList();
        if (victimParent != null) {
            final int index = victimParent.indexOfChild(view);
            getViewsBelowOfRecursive(result, victimParent, index + 1, view);
        }
        return result;
    }

    private static void getViewsBelowOfRecursive(List<View> result, ViewGroup container,
            int index, View target) {
        for (int i = index; i < container.getChildCount(); i++) {
            View view = container.getChildAt(i);
            // consider the child view below the target view only if it is physically
            // below the view on-screen, using half the height of the target view as the
            // baseline
            if (view.getY() > (target.getY() + target.getHeight() / 2)) {
                result.add(view);
            }
        }

        final ViewParent parent = container.getParent();
        if (parent instanceof LinearLayout) {
            final LinearLayout parentLayout = (LinearLayout) parent;
            int containerIndex = parentLayout.indexOfChild(container);
            getViewsBelowOfRecursive(result, parentLayout, containerIndex + 1, target);
        }
    }

    /**
     * Keeps a reference to the last animator, so that we can end that early if the user
     * quickly pushes buttons. Removes the reference once the animation has finished
     */
    /* package */ static class AnimatorRunner extends AnimatorListenerAdapter {
        private Animator mLastAnimator;

        @Override
        public void onAnimationEnd(Animator animation) {
            mLastAnimator = null;
        }

        public void run(List<Animator> animators) {
            run(animators, null);
        }

        public void run(List<Animator> animators, AnimatorListener listener) {
            final AnimatorSet set = new AnimatorSet();
            set.playTogether(animators);
            if (listener != null) set.addListener(listener);
            set.addListener(this);
            mLastAnimator = set;
            set.start();
        }

        public void endOldAnimation() {
            if (mLastAnimator != null) {
                mLastAnimator.end();
            }
        }
    }
}
