/*
 * Copyright (C) 2008 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 android.view.animation.cts;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;

import android.content.res.XmlResourceParser;
import android.support.test.filters.LargeTest;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.util.AttributeSet;
import android.util.Xml;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LayoutAnimationController;
import android.view.animation.LayoutAnimationController.AnimationParameters;
import android.view.animation.ScaleAnimation;
import android.view.animation.Transformation;
import android.view.cts.R;
import android.widget.AbsListView;
import android.widget.ListView;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

@LargeTest
@RunWith(AndroidJUnit4.class)
public class LayoutAnimationControllerTest {
    /** Duration defined in layout_anim_controller_animation.xml is 1000 */
    private static final int DURATION = 1000;
    private static final float DELTA = 0.1f;
    private static final int INDEX_OF_CHILD1 = 0;
    private static final int INDEX_OF_CHILD2 = 1;
    private static final int INDEX_OF_CHILD3 = 2;
    /** Default delay of LayoutAnimationController */
    private static final float DEFAULT_DELAY = 0.5f;
    /** Default max duration of these three children */
    private static final long DEFAULT_MAX_DURATION = 2000;

    private LayoutAnimCtsActivity mActivity;
    private Animation mDefaultAnimation;
    private ListView mListView;
    private LayoutAnimationController mController;

    @Rule
    public ActivityTestRule<LayoutAnimCtsActivity> mActivityRule =
            new ActivityTestRule<>(LayoutAnimCtsActivity.class);

    @Before
    public void setup() {
        mActivity = mActivityRule.getActivity();
        mListView = mActivity.getListView();
        mDefaultAnimation = AnimationUtils.loadAnimation(mActivity,
                R.anim.layout_anim_controller_animation);
        mController = new LayoutAnimationController(mDefaultAnimation, DEFAULT_DELAY);
    }

    @Test
    public void testAccessOrder() throws Throwable {
        mController.setOrder(LayoutAnimationController.ORDER_NORMAL);
        assertEquals(LayoutAnimationController.ORDER_NORMAL, mController.getOrder());

        AnimationTestUtils.assertRunController(mActivityRule, mListView, mController,
                DEFAULT_MAX_DURATION);

        Animation childAnimation1 = mListView.getChildAt(INDEX_OF_CHILD1).getAnimation();
        Animation childAnimation2 = mListView.getChildAt(INDEX_OF_CHILD2).getAnimation();
        Animation childAnimation3 = mListView.getChildAt(INDEX_OF_CHILD3).getAnimation();

        // Test normal order
        long startTime = childAnimation1.getStartTime();
        assertEquals(0, childAnimation1.getStartOffset());
        assertEquals(500, childAnimation2.getStartOffset());
        assertEquals(1000, childAnimation3.getStartOffset());

        Transformation transformation1 = new Transformation();
        Transformation transformation2 = new Transformation();
        Transformation transformation3 = new Transformation();

        // child1 has started animation, child2 and child3 haven't started
        childAnimation1.getTransformation(startTime + 500, transformation1);
        childAnimation2.getTransformation(startTime + 500, transformation2);
        childAnimation3.getTransformation(startTime + 500, transformation3);
        assertIsRunningAnimation(transformation1.getAlpha());
        assertEquals(0.0f, transformation2.getAlpha(), DELTA);
        assertEquals(0.0f, transformation3.getAlpha(), DELTA);

        // child2 has started animation, child1 has finished and child3 hasn't started
        childAnimation1.getTransformation(startTime + 1000, transformation1);
        childAnimation2.getTransformation(startTime + 1000, transformation2);
        childAnimation3.getTransformation(startTime + 1000, transformation3);
        assertEquals(1.0f, transformation1.getAlpha(), DELTA);
        assertIsRunningAnimation(transformation2.getAlpha());
        assertEquals(0.0f, transformation3.getAlpha(), DELTA);

        // child3 has started animation, child1, child2 have finished
        childAnimation1.getTransformation(startTime + 1500, transformation1);
        childAnimation2.getTransformation(startTime + 1500, transformation2);
        childAnimation3.getTransformation(startTime + 1500, transformation3);
        assertEquals(1.0f, transformation1.getAlpha(), DELTA);
        assertEquals(1.0f, transformation2.getAlpha(), DELTA);
        assertIsRunningAnimation(transformation3.getAlpha());

        // Test reverse order
        mController.setOrder(LayoutAnimationController.ORDER_REVERSE);
        assertEquals(LayoutAnimationController.ORDER_REVERSE, mController.getOrder());
        AnimationTestUtils.assertRunController(mActivityRule, mListView, mController,
                DEFAULT_MAX_DURATION);

        transformation1 = new Transformation();
        transformation2 = new Transformation();
        transformation3 = new Transformation();
        childAnimation1 = mListView.getChildAt(INDEX_OF_CHILD1).getAnimation();
        childAnimation2 = mListView.getChildAt(INDEX_OF_CHILD2).getAnimation();
        childAnimation3 = mListView.getChildAt(INDEX_OF_CHILD3).getAnimation();
        startTime = childAnimation1.getStartTime();
        assertEquals(1000, childAnimation1.getStartOffset());
        assertEquals(500, childAnimation2.getStartOffset());
        assertEquals(0, childAnimation3.getStartOffset());

        // child3 has started animation, child1 and child2 haven't started
        childAnimation1.getTransformation(startTime + 500, transformation1);
        childAnimation2.getTransformation(startTime + 500, transformation2);
        childAnimation3.getTransformation(startTime + 500, transformation3);
        assertEquals(0.0f, transformation1.getAlpha(), DELTA);
        assertEquals(0.0f, transformation2.getAlpha(), DELTA);
        assertIsRunningAnimation(transformation3.getAlpha());

        // child2 has started animation, child3 has finished and child1 hasn't started
        childAnimation1.getTransformation(startTime + 1000, transformation1);
        childAnimation2.getTransformation(startTime + 1000, transformation2);
        childAnimation3.getTransformation(startTime + 1000, transformation3);
        assertEquals(0.0f, transformation1.getAlpha(), DELTA);
        assertIsRunningAnimation(transformation2.getAlpha());
        assertEquals(1.0f, transformation3.getAlpha(), DELTA);

        // child1 has started animation, child2 and child3 has finished
        childAnimation1.getTransformation(startTime + 1500, transformation1);
        childAnimation2.getTransformation(startTime + 1500, transformation2);
        childAnimation3.getTransformation(startTime + 1500, transformation3);
        assertIsRunningAnimation(transformation1.getAlpha());
        assertEquals(1.0f, transformation2.getAlpha(), DELTA);
        assertEquals(1.0f, transformation3.getAlpha(), DELTA);
    }

    @Test
    public void testAccessDelay() throws Throwable {
        mController.setOrder(LayoutAnimationController.ORDER_NORMAL);
        float delay = 1.5f;
        mController.setDelay(delay);
        assertEquals(delay, mController.getDelay(), 0.0f);
        long maxDuration = (long) (delay * INDEX_OF_CHILD3 * DURATION + DURATION);
        AnimationTestUtils.assertRunController(mActivityRule, mListView, mController,
                maxDuration);

        Animation childAnimation1 = mListView.getChildAt(INDEX_OF_CHILD1).getAnimation();
        Animation childAnimation2 = mListView.getChildAt(INDEX_OF_CHILD2).getAnimation();
        Animation childAnimation3 = mListView.getChildAt(INDEX_OF_CHILD3).getAnimation();

        long startTime = childAnimation1.getStartTime();
        long offsetTime1 = childAnimation1.getStartOffset();
        long offsetTime2 = childAnimation2.getStartOffset();
        long offsetTime3 = childAnimation3.getStartOffset();
        // child animation delay = child index * delay * animation duration
        assertEquals(0, offsetTime1);
        assertEquals(1500, offsetTime2);
        assertEquals(3000, offsetTime3);

        Transformation transformation1 = new Transformation();
        Transformation transformation2 = new Transformation();
        Transformation transformation3 = new Transformation();

        // child1 has started animation, child2 and child3 haven't started
        childAnimation1.getTransformation(startTime + 500, transformation1);
        childAnimation2.getTransformation(startTime + 500, transformation2);
        childAnimation3.getTransformation(startTime + 500, transformation3);
        assertIsRunningAnimation(transformation1.getAlpha());
        assertEquals(0.0f, transformation2.getAlpha(), DELTA);
        assertEquals(0.0f, transformation3.getAlpha(), DELTA);

        // child1 has finished, child2 and child3 haven't started
        childAnimation1.getTransformation(startTime + 1200, transformation1);
        childAnimation2.getTransformation(startTime + 1200, transformation2);
        childAnimation3.getTransformation(startTime + 1200, transformation3);
        assertEquals(1.0f, transformation1.getAlpha(), DELTA);
        assertEquals(0.0f, transformation2.getAlpha(), DELTA);
        assertEquals(0.0f, transformation3.getAlpha(), DELTA);

        // child1 has finished, child2 has started animation, child3 hasn't started.
        childAnimation1.getTransformation(startTime + 2000, transformation1);
        childAnimation2.getTransformation(startTime + 2000, transformation2);
        childAnimation3.getTransformation(startTime + 2000, transformation3);
        assertEquals(1.0f, transformation1.getAlpha(), DELTA);
        assertIsRunningAnimation(transformation2.getAlpha());
        assertEquals(0.0f, transformation3.getAlpha(), DELTA);

        // child1 and child2 have finished, child3 hasn't started
        childAnimation1.getTransformation(startTime + 2700, transformation1);
        childAnimation2.getTransformation(startTime + 2700, transformation2);
        childAnimation3.getTransformation(startTime + 2700, transformation3);
        assertEquals(1.0f, transformation1.getAlpha(), DELTA);
        assertEquals(1.0f, transformation2.getAlpha(), DELTA);
        assertEquals(0.0f, transformation3.getAlpha(), DELTA);

        // child1 and child2 have finished, child3 has started animation
        childAnimation1.getTransformation(startTime + 3500, transformation1);
        childAnimation2.getTransformation(startTime + 3500, transformation2);
        childAnimation3.getTransformation(startTime + 3500, transformation3);
        assertIsRunningAnimation(transformation3.getAlpha());
    }

    private void assertIsRunningAnimation(float alpha) {
        assertTrue(alpha > 0.0f);
        assertTrue(alpha < 1.0f);
    }

    @Test
    public void testAccessAnimation() throws Throwable {
        Animation animation = AnimationUtils.loadAnimation(mActivity, R.anim.decelerate_alpha);
        animation.setFillAfter(true);
        // duration defined in decelerate_alpha.xml is 2000
        long duration = 2000;
        mController.setAnimation(animation);
        assertSame(animation, mController.getAnimation());
        long maxDuration = (long) (DEFAULT_DELAY * INDEX_OF_CHILD3 * duration + duration);
        AnimationTestUtils.assertRunController(mActivityRule, mListView, mController,
                maxDuration);

        Animation childAnimation1 = mListView.getChildAt(INDEX_OF_CHILD1).getAnimation();
        Animation childAnimation2 = mListView.getChildAt(INDEX_OF_CHILD2).getAnimation();
        Animation childAnimation3 = mListView.getChildAt(INDEX_OF_CHILD3).getAnimation();
        assertAnimation(childAnimation1, false, duration);
        assertAnimation(childAnimation2, false, duration);
        assertAnimation(childAnimation3, false, duration);

        mController.setAnimation(mActivity, R.anim.layout_anim_controller_animation);
        Animation actualAnimation = mController.getAnimation();
        assertEquals(DURATION, actualAnimation.getDuration());
        assertTrue(actualAnimation.getInterpolator() instanceof AccelerateInterpolator);
        AnimationTestUtils.assertRunController(mActivityRule, mListView, mController,
                DEFAULT_MAX_DURATION);

        childAnimation1 = mListView.getChildAt(INDEX_OF_CHILD1).getAnimation();
        childAnimation2 = mListView.getChildAt(INDEX_OF_CHILD2).getAnimation();
        childAnimation3 = mListView.getChildAt(INDEX_OF_CHILD3).getAnimation();
        assertAnimation(childAnimation1, true, DURATION);
        assertAnimation(childAnimation2, true, DURATION);
        assertAnimation(childAnimation3, true, DURATION);
    }

    /**
     * This method is used for asserting alpha of accelerate and decelerate animations to
     * make sure their accelerate/decelerate functionalities really work.
     * @param animation
     * @param isAccelerate
     * @param duration
     */
    private void assertAnimation(Animation animation, boolean isAccelerate, long duration) {
        Transformation transformation = new Transformation();
        long baseTime = animation.getStartTime() + animation.getStartOffset();
        animation.getTransformation(baseTime, transformation);
        long step = duration / 4;
        float alpha1 = transformation.getAlpha();
        animation.getTransformation(baseTime + step * 1, transformation);
        float alpha2 = transformation.getAlpha();
        animation.getTransformation(baseTime + step * 2, transformation);
        float alpha3 = transformation.getAlpha();
        animation.getTransformation(baseTime + step * 3, transformation);
        float alpha4 = transformation.getAlpha();
        animation.getTransformation(baseTime + step * 4, transformation);
        float alpha5 = transformation.getAlpha();

        // check decelerating delta alpha
        float delta1 = alpha2 - alpha1;
        float delta2 = alpha3 - alpha2;
        float delta3 = alpha4 - alpha3;
        float delta4 = alpha5 - alpha4;
        if (isAccelerate) {
            assertTrue(delta1 < delta2);
            assertTrue(delta2 < delta3);
            assertTrue(delta3 < delta4);
        } else {
            assertTrue(delta1 > delta2);
            assertTrue(delta2 > delta3);
            assertTrue(delta3 > delta4);
        }
    }

    @Test
    public void testAccessInterpolator() throws Throwable {
        DecelerateInterpolator interpolator = new DecelerateInterpolator(1.0f);
        mController.setInterpolator(interpolator);
        assertSame(interpolator, mController.getInterpolator());
        AnimationTestUtils.assertRunController(mActivityRule, mListView, mController,
                DEFAULT_MAX_DURATION);

        Animation childAnimation1 = mListView.getChildAt(INDEX_OF_CHILD1).getAnimation();
        Animation childAnimation2 = mListView.getChildAt(INDEX_OF_CHILD2).getAnimation();
        Animation childAnimation3 = mListView.getChildAt(INDEX_OF_CHILD3).getAnimation();

        long delta1 = childAnimation2.getStartOffset() - childAnimation1.getStartOffset();
        long delta2 = childAnimation3.getStartOffset() - childAnimation2.getStartOffset();
        assertTrue(delta2 < delta1);

        mController.setInterpolator(mActivity, android.R.anim.accelerate_interpolator);
        assertTrue(mController.getInterpolator() instanceof AccelerateInterpolator);
        AnimationTestUtils.assertRunController(mActivityRule, mListView, mController,
                DEFAULT_MAX_DURATION);

        childAnimation1 = mListView.getChildAt(INDEX_OF_CHILD1).getAnimation();
        childAnimation2 = mListView.getChildAt(INDEX_OF_CHILD2).getAnimation();
        childAnimation3 = mListView.getChildAt(INDEX_OF_CHILD3).getAnimation();

        delta1 = childAnimation2.getStartOffset() - childAnimation1.getStartOffset();
        delta2 = childAnimation3.getStartOffset() - childAnimation2.getStartOffset();
        assertTrue(delta2 > delta1);
    }

    @Test
    public void testConstructor() {
        XmlResourceParser parser = mActivity.getResources().getAnimation(
                R.anim.accelerate_decelerate_alpha);
        AttributeSet attrs = Xml.asAttributeSet(parser);
        new LayoutAnimationController(mActivity, attrs);
        new LayoutAnimationController(mDefaultAnimation, DEFAULT_DELAY);
        LayoutAnimationController controller = new LayoutAnimationController(mDefaultAnimation);
        assertEquals(DEFAULT_DELAY, controller.getDelay(), 0.0f);
    }

    @Test
    public void testGetDelayForView() throws Throwable {
        Animation animation = AnimationUtils.loadAnimation(mActivity, R.anim.decelerate_alpha);
        animation.setFillAfter(true);
        MyLayoutAnimationController controller = new MyLayoutAnimationController(animation);

        // child1's animationParams
        final AbsListView.LayoutParams layoutParams1 = setAnimationParameters(0);
        // child2's animationParams
        final AbsListView.LayoutParams layoutParams2 = setAnimationParameters(1);
        // child3's animationParams
        final AbsListView.LayoutParams layoutParams3 = setAnimationParameters(2);

        final View child1 = mListView.getChildAt(INDEX_OF_CHILD1);
        final View child2 = mListView.getChildAt(INDEX_OF_CHILD2);
        final View child3 = mListView.getChildAt(INDEX_OF_CHILD3);
        mActivityRule.runOnUiThread(() -> {
            child1.setLayoutParams(layoutParams1);
            child2.setLayoutParams(layoutParams2);
            child3.setLayoutParams(layoutParams3);
        });

        AnimationTestUtils.assertRunController(mActivityRule, mListView, controller,
                DEFAULT_MAX_DURATION);

        assertEquals(0, controller.getDelayForView(child1));
        assertEquals(1000, controller.getDelayForView(child2));
        assertEquals(2000, controller.getDelayForView(child3));
    }

    private AbsListView.LayoutParams setAnimationParameters(int index) {
        AnimationParameters animationParams = new AnimationParameters();
        animationParams.index = index;
        animationParams.count = 3;
        final AbsListView.LayoutParams layoutParams = new AbsListView.LayoutParams(
                LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
        layoutParams.layoutAnimationParameters = animationParams;
        return layoutParams;
    }

    @Test
    public void testGetTransformedIndex() {
        Animation animation = AnimationUtils.loadAnimation(mActivity, R.anim.decelerate_alpha);
        animation.setFillAfter(true);
        MyLayoutAnimationController controller = new MyLayoutAnimationController(animation);
        AnimationParameters animationParams = new AnimationParameters();
        animationParams.count = 3;

        // Test getTransformedIndex in ORDER_NORMAL condition, child1_index == 0, child2_index == 1,
        // child3_index == 2
        animationParams.index = 0;
        assertEquals(0, controller.getTransformedIndex(animationParams));
        animationParams.index = 1;
        assertEquals(1, controller.getTransformedIndex(animationParams));
        animationParams.index = 2;
        assertEquals(2, controller.getTransformedIndex(animationParams));
        // Test getTransformedIndex in ORDER_REVERSE condition, child1_index == 2,
        // child2_index == 1, child3_index == 0
        controller.setOrder(LayoutAnimationController.ORDER_REVERSE);
        animationParams.index = 0;
        assertEquals(2, controller.getTransformedIndex(animationParams));
        animationParams.index = 1;
        assertEquals(1, controller.getTransformedIndex(animationParams));
        animationParams.index = 2;
        assertEquals(0, controller.getTransformedIndex(animationParams));
    }

    @Test
    public void testStart() {
        Animation animation = new ScaleAnimation(0.0f, 10.0f, 0.0f, 20.0f);
        animation.setStartTime(500);
        LayoutAnimationController controller = new LayoutAnimationController(animation);

        assertTrue(Animation.START_ON_FIRST_FRAME != controller.getAnimation().getStartTime());

        controller.start();
        assertEquals(Animation.START_ON_FIRST_FRAME, controller.getAnimation().getStartTime());
    }

    @Test
    public void testIsDone() throws Throwable {
        AnimationTestUtils.assertRunController(mActivityRule, mListView, mController,
                DEFAULT_MAX_DURATION);
        assertTrue(mController.isDone());
    }

    @Test
    public void testGetAnimationForView() throws Throwable {
        Animation animation = AnimationUtils.loadAnimation(mActivity, R.anim.decelerate_alpha);
        animation.setFillAfter(true);
        mController.setAnimation(animation);
        AnimationTestUtils.assertRunController(mActivityRule, mListView, mController,
                DEFAULT_MAX_DURATION);
        Animation childAnimation1 = mListView.getChildAt(INDEX_OF_CHILD1).getAnimation();
        Animation childAnimation2 = mListView.getChildAt(INDEX_OF_CHILD2).getAnimation();
        Animation childAnimation3 = mListView.getChildAt(INDEX_OF_CHILD3).getAnimation();
        // duration defined in decelerate_alpha.xml is 2000
        long duration = 2000;
        assertAnimation(childAnimation1, false, duration);
        assertAnimation(childAnimation2, false, duration);
        assertAnimation(childAnimation3, false, duration);
        assertEquals(0, childAnimation1.getStartOffset());
        assertEquals(1000, childAnimation2.getStartOffset());
        assertEquals(2000, childAnimation3.getStartOffset());
    }

    @Test
    public void testWillOverlap() {
        LayoutAnimationController controller = new LayoutAnimationController(mDefaultAnimation);

        controller.setDelay(0.5f);
        assertTrue(controller.willOverlap());

        controller.setDelay(1.0f);
        assertFalse(controller.willOverlap());

        controller.setDelay(1.5f);
        assertFalse(controller.willOverlap());
    }

    private class MyLayoutAnimationController extends LayoutAnimationController {
        public MyLayoutAnimationController(Animation animation) {
            super(animation);
        }

        protected int getTransformedIndex(AnimationParameters params) {
            return super.getTransformedIndex(params);
        }

        protected long getDelayForView(View view) {
            return super.getDelayForView(view);
        }
    }
}
