/*
 * Copyright (C) 2018 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.server.wm;

import static com.android.server.wm.AnimationAdapter.STATUS_BAR_TRANSITION_DURATION;
import static com.android.server.wm.AnimationSpecProto.WINDOW;
import static com.android.server.wm.WindowAnimationSpecProto.ANIMATION;

import android.graphics.Matrix;
import android.graphics.Rect;
import android.os.SystemClock;
import android.util.proto.ProtoOutputStream;
import android.view.DisplayInfo;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.ClipRectAnimation;
import android.view.animation.ScaleAnimation;
import android.view.animation.Transformation;
import android.view.animation.TranslateAnimation;

import com.android.server.wm.LocalAnimationAdapter.AnimationSpec;

import java.io.PrintWriter;

/**
 * Animation spec for changing window animations.
 */
public class WindowChangeAnimationSpec implements AnimationSpec {

    private final ThreadLocal<TmpValues> mThreadLocalTmps = ThreadLocal.withInitial(TmpValues::new);
    private final boolean mIsAppAnimation;
    private final Rect mStartBounds;
    private final Rect mEndBounds;
    private final Rect mTmpRect = new Rect();

    private Animation mAnimation;
    private final boolean mIsThumbnail;

    static final int ANIMATION_DURATION = AppTransition.DEFAULT_APP_TRANSITION_DURATION;

    public WindowChangeAnimationSpec(Rect startBounds, Rect endBounds, DisplayInfo displayInfo,
            float durationScale, boolean isAppAnimation, boolean isThumbnail) {
        mStartBounds = new Rect(startBounds);
        mEndBounds = new Rect(endBounds);
        mIsAppAnimation = isAppAnimation;
        mIsThumbnail = isThumbnail;
        createBoundsInterpolator((int) (ANIMATION_DURATION * durationScale), displayInfo);
    }

    @Override
    public boolean getShowWallpaper() {
        return false;
    }

    @Override
    public int getBackgroundColor() {
        return 0;
    }

    @Override
    public long getDuration() {
        return mAnimation.getDuration();
    }

    /**
     * This animator behaves slightly differently depending on whether the window is growing
     * or shrinking:
     * If growing, it will do a clip-reveal after quicker fade-out/scale of the smaller (old)
     * snapshot.
     * If shrinking, it will do an opposite clip-reveal on the old snapshot followed by a quicker
     * fade-out of the bigger (old) snapshot while simultaneously shrinking the new window into
     * place.
     * @param duration
     * @param displayInfo
     */
    private void createBoundsInterpolator(long duration, DisplayInfo displayInfo) {
        boolean growing = mEndBounds.width() - mStartBounds.width()
                + mEndBounds.height() - mStartBounds.height() >= 0;
        float scalePart = 0.7f;
        long scalePeriod = (long) (duration * scalePart);
        float startScaleX = scalePart * ((float) mStartBounds.width()) / mEndBounds.width()
                + (1.f - scalePart);
        float startScaleY = scalePart * ((float) mStartBounds.height()) / mEndBounds.height()
                + (1.f - scalePart);
        if (mIsThumbnail) {
            AnimationSet animSet = new AnimationSet(true);
            Animation anim = new AlphaAnimation(1.f, 0.f);
            anim.setDuration(scalePeriod);
            if (!growing) {
                anim.setStartOffset(duration - scalePeriod);
            }
            animSet.addAnimation(anim);
            float endScaleX = 1.f / startScaleX;
            float endScaleY = 1.f / startScaleY;
            anim = new ScaleAnimation(endScaleX, endScaleX, endScaleY, endScaleY);
            anim.setDuration(duration);
            animSet.addAnimation(anim);
            mAnimation = animSet;
            mAnimation.initialize(mStartBounds.width(), mStartBounds.height(),
                    mEndBounds.width(), mEndBounds.height());
        } else {
            AnimationSet animSet = new AnimationSet(true);
            final Animation scaleAnim = new ScaleAnimation(startScaleX, 1, startScaleY, 1);
            scaleAnim.setDuration(scalePeriod);
            if (!growing) {
                scaleAnim.setStartOffset(duration - scalePeriod);
            }
            animSet.addAnimation(scaleAnim);
            final Animation translateAnim = new TranslateAnimation(mStartBounds.left,
                    mEndBounds.left, mStartBounds.top, mEndBounds.top);
            translateAnim.setDuration(duration);
            animSet.addAnimation(translateAnim);
            Rect startClip = new Rect(mStartBounds);
            Rect endClip = new Rect(mEndBounds);
            startClip.offsetTo(0, 0);
            endClip.offsetTo(0, 0);
            final Animation clipAnim = new ClipRectAnimation(startClip, endClip);
            clipAnim.setDuration(duration);
            animSet.addAnimation(clipAnim);
            mAnimation = animSet;
            mAnimation.initialize(mStartBounds.width(), mStartBounds.height(),
                    displayInfo.appWidth, displayInfo.appHeight);
        }
    }

    @Override
    public void apply(Transaction t, SurfaceControl leash, long currentPlayTime) {
        final TmpValues tmp = mThreadLocalTmps.get();
        if (mIsThumbnail) {
            mAnimation.getTransformation(currentPlayTime, tmp.mTransformation);
            t.setMatrix(leash, tmp.mTransformation.getMatrix(), tmp.mFloats);
            t.setAlpha(leash, tmp.mTransformation.getAlpha());
        } else {
            mAnimation.getTransformation(currentPlayTime, tmp.mTransformation);
            final Matrix matrix = tmp.mTransformation.getMatrix();
            t.setMatrix(leash, matrix, tmp.mFloats);

            // The following applies an inverse scale to the clip-rect so that it crops "after" the
            // scale instead of before.
            tmp.mVecs[1] = tmp.mVecs[2] = 0;
            tmp.mVecs[0] = tmp.mVecs[3] = 1;
            matrix.mapVectors(tmp.mVecs);
            tmp.mVecs[0] = 1.f / tmp.mVecs[0];
            tmp.mVecs[3] = 1.f / tmp.mVecs[3];
            final Rect clipRect = tmp.mTransformation.getClipRect();
            mTmpRect.left = (int) (clipRect.left * tmp.mVecs[0] + 0.5f);
            mTmpRect.right = (int) (clipRect.right * tmp.mVecs[0] + 0.5f);
            mTmpRect.top = (int) (clipRect.top * tmp.mVecs[3] + 0.5f);
            mTmpRect.bottom = (int) (clipRect.bottom * tmp.mVecs[3] + 0.5f);
            t.setWindowCrop(leash, mTmpRect);
        }
    }

    @Override
    public long calculateStatusBarTransitionStartTime() {
        long uptime = SystemClock.uptimeMillis();
        return Math.max(uptime, uptime + ((long) (((float) mAnimation.getDuration()) * 0.99f))
                - STATUS_BAR_TRANSITION_DURATION);
    }

    @Override
    public boolean canSkipFirstFrame() {
        return false;
    }

    @Override
    public boolean needsEarlyWakeup() {
        return mIsAppAnimation;
    }

    @Override
    public void dump(PrintWriter pw, String prefix) {
        pw.print(prefix); pw.println(mAnimation.getDuration());
    }

    @Override
    public void writeToProtoInner(ProtoOutputStream proto) {
        final long token = proto.start(WINDOW);
        proto.write(ANIMATION, mAnimation.toString());
        proto.end(token);
    }

    private static class TmpValues {
        final Transformation mTransformation = new Transformation();
        final float[] mFloats = new float[9];
        final float[] mVecs = new float[4];
    }
}
