/*
 * 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 android.transition.cts;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;

import android.animation.Animator;
import android.content.res.Resources;
import android.graphics.Point;
import android.graphics.Rect;
import android.support.test.filters.MediumTest;
import android.support.test.runner.AndroidJUnit4;
import android.transition.ChangeBounds;
import android.transition.Transition;
import android.transition.TransitionValues;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.LinearInterpolator;

import com.android.compatibility.common.util.PollingCheck;

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

@MediumTest
@RunWith(AndroidJUnit4.class)
public class ChangeBoundsTest extends BaseTransitionTest {
    private static final int SMALL_SQUARE_SIZE_DP = 30;
    private static final int LARGE_SQUARE_SIZE_DP = 50;
    private static final int SMALL_OFFSET_DP = 2;

    ChangeBounds mChangeBounds;
    ValidateBoundsListener mBoundsChangeListener;

    @Override
    @Before
    public void setup() {
        super.setup();
        resetChangeBoundsTransition();
        mBoundsChangeListener = null;
    }

    private void resetChangeBoundsTransition() {
        mListener = mock(Transition.TransitionListener.class);
        mChangeBounds = new MyChangeBounds();
        mChangeBounds.setDuration(400);
        mChangeBounds.addListener(mListener);
        mChangeBounds.setInterpolator(new LinearInterpolator());
        mTransition = mChangeBounds;
    }

    @Test
    public void testBasicChangeBounds() throws Throwable {
        enterScene(R.layout.scene1);

        validateInScene1();

        mBoundsChangeListener = new ValidateBoundsListener(true);

        startTransition(R.layout.scene6);
        // The update listener will validate that it is changing throughout the animation
        waitForEnd(800);

        validateInScene6();
    }

    @Test
    public void testResizeClip() throws Throwable {
        assertEquals(false, mChangeBounds.getResizeClip());
        mChangeBounds.setResizeClip(true);
        assertEquals(true, mChangeBounds.getResizeClip());
        enterScene(R.layout.scene1);

        validateInScene1();

        mBoundsChangeListener = new ValidateBoundsListener(true);

        startTransition(R.layout.scene6);

        // The update listener will validate that it is changing throughout the animation
        waitForEnd(800);

        validateInScene6();
    }

    @Test
    public void testResizeClipSmaller() throws Throwable {
        mChangeBounds.setResizeClip(true);
        enterScene(R.layout.scene6);

        validateInScene6();

        mBoundsChangeListener = new ValidateBoundsListener(false);
        startTransition(R.layout.scene1);

        // The update listener will validate that it is changing throughout the animation
        waitForEnd(800);

        validateInScene1();
    }

    @Test
    public void testInterruptSameDestination() throws Throwable {
        enterScene(R.layout.scene1);

        validateInScene1();

        startTransition(R.layout.scene6);

        waitForMiddleOfTransition();
        resetChangeBoundsTransition();
        startTransition(R.layout.scene6);

        assertFalse(isRestartingAnimation());
        waitForEnd(1000);
        validateInScene6();
    }

    @Test
    public void testInterruptSameDestinationResizeClip() throws Throwable {
        mChangeBounds.setResizeClip(true);
        enterScene(R.layout.scene1);

        validateInScene1();

        startTransition(R.layout.scene6);

        waitForMiddleOfTransition();

        resetChangeBoundsTransition();
        mChangeBounds.setResizeClip(true);
        startTransition(R.layout.scene6);

        assertFalse(isRestartingAnimation());
        assertFalse(isRestartingClip());
        waitForEnd(1000);
        validateInScene6();
    }

    @Test
    public void testInterruptWithReverse() throws Throwable {
        enterScene(R.layout.scene1);

        validateInScene1();

        startTransition(R.layout.scene6);

        waitForMiddleOfTransition();
        // reverse the transition back to scene1
        resetChangeBoundsTransition();
        startTransition(R.layout.scene1);

        assertFalse(isRestartingAnimation());
        waitForEnd(1000);
        validateInScene1();
    }

    @Test
    public void testInterruptWithReverseResizeClip() throws Throwable {
        mChangeBounds.setResizeClip(true);
        enterScene(R.layout.scene1);

        validateInScene1();

        startTransition(R.layout.scene6);
        waitForMiddleOfTransition();

        // reverse the transition back to scene1
        resetChangeBoundsTransition();
        mChangeBounds.setResizeClip(true);
        startTransition(R.layout.scene1);

        assertFalse(isRestartingAnimation());
        assertFalse(isRestartingClip());
        waitForEnd(1000);
        validateInScene1();
    }

    private void waitForMiddleOfTransition() throws Throwable {
        Resources resources = mActivity.getResources();
        float closestDistance = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                SMALL_SQUARE_SIZE_DP / 2, resources.getDisplayMetrics());

        final View red = mActivity.findViewById(R.id.redSquare);
        final View green = mActivity.findViewById(R.id.greenSquare);

        PollingCheck.waitFor(
                () -> red.getTop() > closestDistance && green.getTop() > closestDistance);

        assertTrue(red.getTop() > closestDistance);
        assertTrue(green.getTop() > closestDistance);
    }

    private boolean isRestartingAnimation() {
        View red = mActivity.findViewById(R.id.redSquare);
        View green = mActivity.findViewById(R.id.greenSquare);
        Resources resources = mActivity.getResources();
        float closestDistance = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                SMALL_OFFSET_DP, resources.getDisplayMetrics());
        return red.getTop() < closestDistance || green.getTop() < closestDistance;
    }

    private boolean isRestartingClip() {
        Resources resources = mActivity.getResources();
        float smallDim = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                SMALL_SQUARE_SIZE_DP + SMALL_OFFSET_DP, resources.getDisplayMetrics());
        float largeDim = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                LARGE_SQUARE_SIZE_DP - SMALL_OFFSET_DP, resources.getDisplayMetrics());

        View red = mActivity.findViewById(R.id.redSquare);
        Rect redClip = red.getClipBounds();
        View green = mActivity.findViewById(R.id.greenSquare);
        Rect greenClip = green.getClipBounds();
        return redClip == null || redClip.width() < smallDim || redClip.width() > largeDim ||
                greenClip == null || greenClip.width() < smallDim || greenClip.width() > largeDim;
    }

    private void validateInScene1() {
        validateViewPlacement(R.id.redSquare, R.id.greenSquare, SMALL_SQUARE_SIZE_DP);
    }

    private void validateInScene6() {
        validateViewPlacement(R.id.greenSquare, R.id.redSquare, LARGE_SQUARE_SIZE_DP);
    }

    private void validateViewPlacement(int topViewResource, int bottomViewResource, int dim) {
        Resources resources = mActivity.getResources();
        float expectedDim = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dim,
                resources.getDisplayMetrics());
        View aboveSquare = mActivity.findViewById(topViewResource);
        assertEquals(0, aboveSquare.getLeft());
        assertEquals(0, aboveSquare.getTop());
        assertTrue(aboveSquare.getRight() != 0);
        final int aboveSquareBottom = aboveSquare.getBottom();
        assertTrue(aboveSquareBottom != 0);

        View belowSquare = mActivity.findViewById(bottomViewResource);
        assertEquals(0, belowSquare.getLeft());
        assertWithinAPixel(aboveSquareBottom, belowSquare.getTop());
        assertWithinAPixel(aboveSquareBottom + aboveSquare.getHeight(),
                belowSquare.getBottom());
        assertWithinAPixel(aboveSquare.getRight(), belowSquare.getRight());

        assertWithinAPixel(expectedDim, aboveSquare.getHeight());
        assertWithinAPixel(expectedDim, aboveSquare.getWidth());
        assertWithinAPixel(expectedDim, belowSquare.getHeight());
        assertWithinAPixel(expectedDim, belowSquare.getWidth());

        assertNull(aboveSquare.getClipBounds());
        assertNull(belowSquare.getClipBounds());
    }

    private static boolean isWithinAPixel(float expectedDim, int dim) {
        return (Math.abs(dim - expectedDim) <= 1);
    }

    private static void assertWithinAPixel(float expectedDim, int dim) {
        assertTrue("Expected dimension to be within one pixel of "
                + expectedDim + ", but was " + dim, isWithinAPixel(expectedDim, dim));
    }

    private static void assertNotWithinAPixel(float expectedDim, int dim) {
        assertTrue("Expected dimension to not be within one pixel of "
                + expectedDim + ", but was " + dim, !isWithinAPixel(expectedDim, dim));
    }

    private class MyChangeBounds extends ChangeBounds {
        private static final String PROPNAME_BOUNDS = "android:changeBounds:bounds";
        @Override
        public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
                TransitionValues endValues) {
            Animator animator = super.createAnimator(sceneRoot, startValues, endValues);
            if (animator != null && mBoundsChangeListener != null) {
                animator.addListener(mBoundsChangeListener);
                Rect startBounds = (Rect) startValues.values.get(PROPNAME_BOUNDS);
                Rect endBounds = (Rect) endValues.values.get(PROPNAME_BOUNDS);
            }
            return animator;
        }
    }

    private class ValidateBoundsListener implements ViewTreeObserver.OnDrawListener,
            Animator.AnimatorListener {
        final boolean mGrow;
        final int mMin;
        final int mMax;

        final Point mRedDimensions = new Point(-1, -1);
        final Point mGreenDimensions = new Point(-1, -1);

        View mRedSquare;
        View mGreenSquare;

        boolean mDidChangeSize;

        private ValidateBoundsListener(boolean grow) {
            mGrow = grow;

            Resources resources = mActivity.getResources();
            mMin = (int) (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                    SMALL_SQUARE_SIZE_DP, resources.getDisplayMetrics()));
            mMax = (int) Math.ceil(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
                    LARGE_SQUARE_SIZE_DP, resources.getDisplayMetrics()));
        }

        public void validateView(View view, Point dimensions) {
            final String name = view.getTransitionName();
            final boolean clipped = mChangeBounds.getResizeClip();
            assertEquals(clipped, view.getClipBounds() != null);

            final int width;
            final int height;
            if (clipped) {
                width = view.getClipBounds().width();
                height = view.getClipBounds().height();
            } else {
                width = view.getWidth();
                height = view.getHeight();
            }
            int newWidth = validateDim(name, "width", dimensions.x, width);
            int newHeight = validateDim(name, "height", dimensions.y, height);
            dimensions.set(newWidth, newHeight);
        }

        private int validateDim(String name, String dimen, int lastDim, int newDim) {
            int dim = newDim;
            if (lastDim != -1) {
                // We must give a pixel's buffer because the top-left and
                // bottom-right may move independently, causing a rounding error
                // in size change.
                if (mGrow) {
                    assertTrue(name + " new " + dimen + " " + newDim
                                    + " is less than previous " + lastDim,
                            newDim >= lastDim - 1);
                    dim = Math.max(lastDim, newDim);
                } else {
                    assertTrue(name + " new " + dimen + " " + newDim
                                    + " is more than previous " + lastDim,
                            newDim <= lastDim + 1);
                    dim = Math.min(lastDim, newDim);
                }
                if (newDim != lastDim) {
                    mDidChangeSize = true;
                }
            }
            assertTrue(name + " " + dimen + " " + newDim + " must be <= " + mMax,
                    newDim <= mMax);
            assertTrue(name + " " + dimen + " " + newDim + " must be >= " + mMin,
                    newDim >= mMin);
            return dim;
        }

        @Override
        public void onDraw() {
            if (mRedSquare == null) {
                mRedSquare = mActivity.findViewById(R.id.redSquare);
                mGreenSquare = mActivity.findViewById(R.id.greenSquare);
            }
            validateView(mRedSquare, mRedDimensions);
            validateView(mGreenSquare, mGreenDimensions);
        }

        @Override
        public void onAnimationStart(Animator animation) {
            mActivity.getWindow().getDecorView().getViewTreeObserver().addOnDrawListener(this);
        }

        @Override
        public void onAnimationEnd(Animator animation) {
            mActivity.getWindow().getDecorView().getViewTreeObserver().removeOnDrawListener(this);
            assertTrue(mDidChangeSize);
        }

        @Override
        public void onAnimationCancel(Animator animation) {
        }

        @Override
        public void onAnimationRepeat(Animator animation) {
        }
    }
}

