/*
 * Copyright (C) 2017 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.WindowStateAnimator.STACK_CLIP_AFTER_ANIM;
import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_NONE;

import android.graphics.Point;
import android.graphics.Rect;
import android.os.SystemClock;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
import android.view.animation.Interpolator;
import android.view.animation.Transformation;
import android.view.animation.TranslateAnimation;

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

/**
 * Animation spec for regular window animations.
 */
public class WindowAnimationSpec implements AnimationSpec {

    private Animation mAnimation;
    private final Point mPosition = new Point();
    private final ThreadLocal<TmpValues> mThreadLocalTmps = ThreadLocal.withInitial(TmpValues::new);
    private final boolean mCanSkipFirstFrame;
    private final Rect mStackBounds = new Rect();
    private int mStackClipMode;
    private final Rect mTmpRect = new Rect();

    public WindowAnimationSpec(Animation animation, Point position, boolean canSkipFirstFrame)  {
        this(animation, position, null /* stackBounds */, canSkipFirstFrame, STACK_CLIP_NONE);
    }

    public WindowAnimationSpec(Animation animation, Point position, Rect stackBounds,
            boolean canSkipFirstFrame, int stackClipMode) {
        mAnimation = animation;
        if (position != null) {
            mPosition.set(position.x, position.y);
        }
        mCanSkipFirstFrame = canSkipFirstFrame;
        mStackClipMode = stackClipMode;
        if (stackBounds != null) {
            mStackBounds.set(stackBounds);
        }
    }

    @Override
    public boolean getDetachWallpaper() {
        return mAnimation.getDetachWallpaper();
    }

    @Override
    public int getBackgroundColor() {
        return mAnimation.getBackgroundColor();
    }

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

    @Override
    public void apply(Transaction t, SurfaceControl leash, long currentPlayTime) {
        final TmpValues tmp = mThreadLocalTmps.get();
        tmp.transformation.clear();
        mAnimation.getTransformation(currentPlayTime, tmp.transformation);
        tmp.transformation.getMatrix().postTranslate(mPosition.x, mPosition.y);
        t.setMatrix(leash, tmp.transformation.getMatrix(), tmp.floats);
        t.setAlpha(leash, tmp.transformation.getAlpha());
        if (mStackClipMode == STACK_CLIP_NONE) {
            t.setWindowCrop(leash, tmp.transformation.getClipRect());
        } else if (mStackClipMode == STACK_CLIP_AFTER_ANIM) {
            t.setFinalCrop(leash, mStackBounds);
            t.setWindowCrop(leash, tmp.transformation.getClipRect());
        } else {
            mTmpRect.set(mStackBounds);
            mTmpRect.intersect(tmp.transformation.getClipRect());
            t.setWindowCrop(leash, mTmpRect);
        }
    }

    @Override
    public long calculateStatusBarTransitionStartTime() {
        TranslateAnimation openTranslateAnimation = findTranslateAnimation(mAnimation);
        if (openTranslateAnimation != null) {

            // Some interpolators are extremely quickly mostly finished, but not completely. For
            // our purposes, we need to find the fraction for which ther interpolator is mostly
            // there, and use that value for the calculation.
            float t = findAlmostThereFraction(openTranslateAnimation.getInterpolator());
            return SystemClock.uptimeMillis()
                    + openTranslateAnimation.getStartOffset()
                    + (long)(openTranslateAnimation.getDuration() * t)
                    - STATUS_BAR_TRANSITION_DURATION;
        } else {
            return SystemClock.uptimeMillis();
        }
    }

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

    /**
     * Tries to find a {@link TranslateAnimation} inside the {@code animation}.
     *
     * @return the found animation, {@code null} otherwise
     */
    private static TranslateAnimation findTranslateAnimation(Animation animation) {
        if (animation instanceof TranslateAnimation) {
            return (TranslateAnimation) animation;
        } else if (animation instanceof AnimationSet) {
            AnimationSet set = (AnimationSet) animation;
            for (int i = 0; i < set.getAnimations().size(); i++) {
                Animation a = set.getAnimations().get(i);
                if (a instanceof TranslateAnimation) {
                    return (TranslateAnimation) a;
                }
            }
        }
        return null;
    }

    /**
     * Binary searches for a {@code t} such that there exists a {@code -0.01 < eps < 0.01} for which
     * {@code interpolator(t + eps) > 0.99}.
     */
    private static float findAlmostThereFraction(Interpolator interpolator) {
        float val = 0.5f;
        float adj = 0.25f;
        while (adj >= 0.01f) {
            if (interpolator.getInterpolation(val) < 0.99f) {
                val += adj;
            } else {
                val -= adj;
            }
            adj /= 2;
        }
        return val;
    }

    private static class TmpValues {
        final Transformation transformation = new Transformation();
        final float[] floats = new float[9];
    }
}
