/*
 * 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.systemui.statusbar.notification;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.app.ActivityManager;
import android.app.ActivityOptions;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.os.RemoteException;
import android.util.MathUtils;
import android.view.IRemoteAnimationFinishedCallback;
import android.view.IRemoteAnimationRunner;
import android.view.RemoteAnimationAdapter;
import android.view.RemoteAnimationTarget;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.ViewRootImpl;

import com.android.systemui.Interpolators;
import com.android.systemui.statusbar.ExpandableNotificationRow;
import com.android.systemui.statusbar.NotificationListContainer;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
import com.android.systemui.statusbar.phone.NotificationPanelView;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarWindowView;

import java.util.function.Consumer;

/**
 * A class that allows activities to be launched in a seamless way where the notification
 * transforms nicely into the starting window.
 */
public class ActivityLaunchAnimator {

    private static final int ANIMATION_DURATION = 400;
    public static final long ANIMATION_DURATION_FADE_CONTENT = 67;
    public static final long ANIMATION_DURATION_FADE_APP = 200;
    public static final long ANIMATION_DELAY_ICON_FADE_IN = ANIMATION_DURATION -
            CollapsedStatusBarFragment.FADE_IN_DURATION - CollapsedStatusBarFragment.FADE_IN_DELAY
            - 16;
    private static final long LAUNCH_TIMEOUT = 500;
    private final NotificationPanelView mNotificationPanel;
    private final NotificationListContainer mNotificationContainer;
    private final StatusBarWindowView mStatusBarWindow;
    private StatusBar mStatusBar;
    private final Runnable mTimeoutRunnable = () -> {
        setAnimationPending(false);
        mStatusBar.collapsePanel(true /* animate */);
    };
    private boolean mAnimationPending;

    public ActivityLaunchAnimator(StatusBarWindowView statusBarWindow,
            StatusBar statusBar,
            NotificationPanelView notificationPanel,
            NotificationListContainer container) {
        mNotificationPanel = notificationPanel;
        mNotificationContainer = container;
        mStatusBarWindow = statusBarWindow;
        mStatusBar = statusBar;
    }

    public RemoteAnimationAdapter getLaunchAnimation(
            ExpandableNotificationRow sourceNotification) {
        AnimationRunner animationRunner = new AnimationRunner(sourceNotification);
        return new RemoteAnimationAdapter(animationRunner, ANIMATION_DURATION,
                0 /* statusBarTransitionDelay */);
    }

    public boolean isAnimationPending() {
        return mAnimationPending;
    }

    public void setLaunchResult(int launchResult) {
        setAnimationPending((launchResult == ActivityManager.START_TASK_TO_FRONT
                || launchResult == ActivityManager.START_SUCCESS)
                        && mStatusBar.getBarState() == StatusBarState.SHADE);
    }

    private void setAnimationPending(boolean pending) {
        mAnimationPending = pending;
        mStatusBarWindow.setExpandAnimationPending(pending);
        if (pending) {
            mStatusBarWindow.postDelayed(mTimeoutRunnable, LAUNCH_TIMEOUT);
        } else {
            mStatusBarWindow.removeCallbacks(mTimeoutRunnable);
        }
    }

    class AnimationRunner extends IRemoteAnimationRunner.Stub {

        private final ExpandableNotificationRow mSourceNotification;
        private final ExpandAnimationParameters mParams;
        private final Rect mWindowCrop = new Rect();
        private boolean mLeashShown;
        private boolean mInstantCollapsePanel = true;

        public AnimationRunner(ExpandableNotificationRow sourceNofitication) {
            mSourceNotification = sourceNofitication;
            mParams = new ExpandAnimationParameters();
        }

        @Override
        public void onAnimationStart(RemoteAnimationTarget[] remoteAnimationTargets,
                IRemoteAnimationFinishedCallback iRemoteAnimationFinishedCallback)
                    throws RemoteException {
            mSourceNotification.post(() -> {
                for (RemoteAnimationTarget app : remoteAnimationTargets) {
                    if (app.mode == RemoteAnimationTarget.MODE_OPENING) {
                        setExpandAnimationRunning(true);
                        mInstantCollapsePanel = app.position.y == 0
                                && app.sourceContainerBounds.height()
                                        >= mNotificationPanel.getHeight();
                        if (!mInstantCollapsePanel) {
                            mNotificationPanel.collapseWithDuration(ANIMATION_DURATION);
                        }
                        ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
                        mParams.startPosition = mSourceNotification.getLocationOnScreen();
                        mParams.startTranslationZ = mSourceNotification.getTranslationZ();
                        int targetWidth = app.sourceContainerBounds.width();
                        int notificationHeight = mSourceNotification.getActualHeight();
                        int notificationWidth = mSourceNotification.getWidth();
                        anim.setDuration(ANIMATION_DURATION);
                        anim.setInterpolator(Interpolators.LINEAR);
                        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                            @Override
                            public void onAnimationUpdate(ValueAnimator animation) {
                                mParams.linearProgress = animation.getAnimatedFraction();
                                float progress
                                        = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(
                                                mParams.linearProgress);
                                int newWidth = (int) MathUtils.lerp(notificationWidth,
                                        targetWidth, progress);
                                mParams.left = (int) ((targetWidth - newWidth) / 2.0f);
                                mParams.right = mParams.left + newWidth;
                                mParams.top = (int) MathUtils.lerp(mParams.startPosition[1],
                                        app.position.y, progress);
                                mParams.bottom = (int) MathUtils.lerp(mParams.startPosition[1]
                                                + notificationHeight,
                                        app.position.y + app.sourceContainerBounds.bottom,
                                        progress);
                                applyParamsToWindow(app);
                                applyParamsToNotification(mParams);
                                applyParamsToNotificationList(mParams);
                            }
                        });
                        anim.addListener(new AnimatorListenerAdapter() {
                            @Override
                            public void onAnimationEnd(Animator animation) {
                                setExpandAnimationRunning(false);
                                if (mInstantCollapsePanel) {
                                    mStatusBar.collapsePanel(false /* animate */);
                                }
                                try {
                                    iRemoteAnimationFinishedCallback.onAnimationFinished();
                                } catch (RemoteException e) {
                                    e.printStackTrace();
                                }
                            }
                        });
                        anim.start();
                        break;
                    }
                }
                setAnimationPending(false);
            });
        }

        private void setExpandAnimationRunning(boolean running) {
            mNotificationPanel.setLaunchingNotification(running);
            mSourceNotification.setExpandAnimationRunning(running);
            mStatusBarWindow.setExpandAnimationRunning(running);
            mNotificationContainer.setExpandingNotification(running ? mSourceNotification : null);
            if (!running) {
                applyParamsToNotification(null);
                applyParamsToNotificationList(null);
            }

        }

        private void applyParamsToNotificationList(ExpandAnimationParameters params) {
            mNotificationContainer.applyExpandAnimationParams(params);
            mNotificationPanel.applyExpandAnimationParams(params);
        }

        private void applyParamsToNotification(ExpandAnimationParameters params) {
            mSourceNotification.applyExpandAnimationParams(params);
        }

        private void applyParamsToWindow(RemoteAnimationTarget app) {
            SurfaceControl.Transaction t = new SurfaceControl.Transaction();
            if (!mLeashShown) {
                t.show(app.leash);
                mLeashShown = true;
            }
            Matrix m = new Matrix();
            m.postTranslate(0, (float) (mParams.top - app.position.y));
            t.setMatrix(app.leash, m, new float[9]);
            mWindowCrop.set(mParams.left, 0, mParams.right, mParams.getHeight());
            t.setWindowCrop(app.leash, mWindowCrop);
            ViewRootImpl viewRootImpl = mSourceNotification.getViewRootImpl();
            if (viewRootImpl != null) {
                Surface systemUiSurface = viewRootImpl.mSurface;
                t.deferTransactionUntilSurface(app.leash, systemUiSurface,
                        systemUiSurface.getNextFrameNumber());
            }
            t.apply();
        }

        @Override
        public void onAnimationCancelled() throws RemoteException {
            mSourceNotification.post(() -> {
                setAnimationPending(false);
                mStatusBar.onLaunchAnimationCancelled();
            });
        }
    };

    public static class ExpandAnimationParameters {
        float linearProgress;
        int[] startPosition;
        float startTranslationZ;
        int left;
        int top;
        int right;
        int bottom;

        public ExpandAnimationParameters() {
        }

        public int getTop() {
            return top;
        }

        public int getWidth() {
            return right - left;
        }

        public int getHeight() {
            return bottom - top;
        }

        public int getTopChange() {
            return Math.min(top - startPosition[1], 0);
        }


        public float getProgress(long delay, long duration) {
            return MathUtils.constrain((linearProgress * ANIMATION_DURATION - delay)
                    / duration, 0.0f, 1.0f);
        }

        public float getStartTranslationZ() {
            return startTranslationZ;
        }
    }
}
