/*
 * Copyright (C) 2021 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.wm.shell.common.split;

import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Binder;
import android.view.IWindow;
import android.view.LayoutInflater;
import android.view.SurfaceControl;
import android.view.SurfaceControlViewHost;
import android.view.SurfaceSession;
import android.view.View;
import android.view.WindowManager;
import android.view.WindowlessWindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;

import androidx.annotation.NonNull;

import com.android.launcher3.icons.IconProvider;
import com.android.wm.shell.R;
import com.android.wm.shell.common.SurfaceUtils;

/**
 * Handles split decor like showing resizing hint for a specific split.
 */
public class SplitDecorManager extends WindowlessWindowManager {
    private static final String TAG = SplitDecorManager.class.getSimpleName();
    private static final String RESIZING_BACKGROUND_SURFACE_NAME = "ResizingBackground";
    private static final long FADE_DURATION = 133;

    private final IconProvider mIconProvider;
    private final SurfaceSession mSurfaceSession;

    private Drawable mIcon;
    private ImageView mResizingIconView;
    private SurfaceControlViewHost mViewHost;
    private SurfaceControl mHostLeash;
    private SurfaceControl mIconLeash;
    private SurfaceControl mBackgroundLeash;

    private boolean mShown;
    private boolean mIsResizing;
    private Rect mBounds = new Rect();
    private ValueAnimator mFadeAnimator;

    private int mIconSize;

    public SplitDecorManager(Configuration configuration, IconProvider iconProvider,
            SurfaceSession surfaceSession) {
        super(configuration, null /* rootSurface */, null /* hostInputToken */);
        mIconProvider = iconProvider;
        mSurfaceSession = surfaceSession;
    }

    @Override
    protected void attachToParentSurface(IWindow window, SurfaceControl.Builder b) {
        // Can't set position for the ViewRootImpl SC directly. Create a leash to manipulate later.
        final SurfaceControl.Builder builder = new SurfaceControl.Builder(new SurfaceSession())
                .setContainerLayer()
                .setName(TAG)
                .setHidden(true)
                .setParent(mHostLeash)
                .setCallsite("SplitDecorManager#attachToParentSurface");
        mIconLeash = builder.build();
        b.setParent(mIconLeash);
    }

    /** Inflates split decor surface on the root surface. */
    public void inflate(Context context, SurfaceControl rootLeash, Rect rootBounds) {
        if (mIconLeash != null && mViewHost != null) {
            return;
        }

        context = context.createWindowContext(context.getDisplay(), TYPE_APPLICATION_OVERLAY,
                null /* options */);
        mHostLeash = rootLeash;
        mViewHost = new SurfaceControlViewHost(context, context.getDisplay(), this);

        mIconSize = context.getResources().getDimensionPixelSize(R.dimen.split_icon_size);
        final FrameLayout rootLayout = (FrameLayout) LayoutInflater.from(context)
                .inflate(R.layout.split_decor, null);
        mResizingIconView = rootLayout.findViewById(R.id.split_resizing_icon);

        final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
                0 /* width */, 0 /* height */, TYPE_APPLICATION_OVERLAY,
                FLAG_NOT_FOCUSABLE | FLAG_NOT_TOUCHABLE, PixelFormat.TRANSLUCENT);
        lp.width = rootBounds.width();
        lp.height = rootBounds.height();
        lp.token = new Binder();
        lp.setTitle(TAG);
        lp.privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION | PRIVATE_FLAG_TRUSTED_OVERLAY;
        // TODO(b/189839391): Set INPUT_FEATURE_NO_INPUT_CHANNEL after WM supports
        //  TRUSTED_OVERLAY for windowless window without input channel.
        mViewHost.setView(rootLayout, lp);
    }

    /** Releases the surfaces for split decor. */
    public void release(SurfaceControl.Transaction t) {
        if (mFadeAnimator != null && mFadeAnimator.isRunning()) {
            mFadeAnimator.cancel();
        }
        if (mViewHost != null) {
            mViewHost.release();
            mViewHost = null;
        }
        if (mIconLeash != null) {
            t.remove(mIconLeash);
            mIconLeash = null;
        }
        if (mBackgroundLeash != null) {
            t.remove(mBackgroundLeash);
            mBackgroundLeash = null;
        }
        mHostLeash = null;
        mIcon = null;
        mResizingIconView = null;
        mIsResizing = false;
        mShown = false;
    }

    /** Showing resizing hint. */
    public void onResizing(ActivityManager.RunningTaskInfo resizingTask, Rect newBounds,
            SurfaceControl.Transaction t) {
        if (mResizingIconView == null) {
            return;
        }

        if (!mIsResizing) {
            mIsResizing = true;
            mBounds.set(newBounds);
        }

        final boolean show =
                newBounds.width() > mBounds.width() || newBounds.height() > mBounds.height();
        final boolean animate = show != mShown;
        if (animate && mFadeAnimator != null && mFadeAnimator.isRunning()) {
            // If we need to animate and animator still running, cancel it before we ensure both
            // background and icon surfaces are non null for next animation.
            mFadeAnimator.cancel();
        }

        if (mBackgroundLeash == null) {
            mBackgroundLeash = SurfaceUtils.makeColorLayer(mHostLeash,
                    RESIZING_BACKGROUND_SURFACE_NAME, mSurfaceSession);
            t.setColor(mBackgroundLeash, getResizingBackgroundColor(resizingTask))
                    .setLayer(mBackgroundLeash, Integer.MAX_VALUE - 1);
        }

        if (mIcon == null && resizingTask.topActivityInfo != null) {
            mIcon = mIconProvider.getIcon(resizingTask.topActivityInfo);
            mResizingIconView.setImageDrawable(mIcon);
            mResizingIconView.setVisibility(View.VISIBLE);

            WindowManager.LayoutParams lp =
                    (WindowManager.LayoutParams) mViewHost.getView().getLayoutParams();
            lp.width = mIconSize;
            lp.height = mIconSize;
            mViewHost.relayout(lp);
            t.setLayer(mIconLeash, Integer.MAX_VALUE);
        }
        t.setPosition(mIconLeash,
                newBounds.width() / 2 - mIconSize / 2,
                newBounds.height() / 2 - mIconSize / 2);

        if (animate) {
            startFadeAnimation(show, false /* isResized */);
            mShown = show;
        }
    }

    /** Stops showing resizing hint. */
    public void onResized(SurfaceControl.Transaction t) {
        if (mResizingIconView == null) {
            return;
        }

        mIsResizing = false;
        if (mFadeAnimator != null && mFadeAnimator.isRunning()) {
            if (!mShown) {
                // If fade-out animation is running, just add release callback to it.
                SurfaceControl.Transaction finishT = new SurfaceControl.Transaction();
                mFadeAnimator.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        releaseDecor(finishT);
                        finishT.apply();
                        finishT.close();
                    }
                });
                return;
            }

            // If fade-in animation is running, cancel it and re-run fade-out one.
            mFadeAnimator.cancel();
        }
        if (mShown) {
            startFadeAnimation(false /* show */, true /* isResized */);
        } else {
            // Decor surface is hidden so release it directly.
            releaseDecor(t);
        }
    }

    private void startFadeAnimation(boolean show, boolean isResized) {
        final SurfaceControl.Transaction animT = new SurfaceControl.Transaction();
        mFadeAnimator = ValueAnimator.ofFloat(0f, 1f);
        mFadeAnimator.setDuration(FADE_DURATION);
        mFadeAnimator.addUpdateListener(valueAnimator-> {
            final float progress = (float) valueAnimator.getAnimatedValue();
            if (mBackgroundLeash != null) {
                animT.setAlpha(mBackgroundLeash, show ? progress : 1 - progress);
            }
            if (mIconLeash != null) {
                animT.setAlpha(mIconLeash, show ? progress : 1 - progress);
            }
            animT.apply();
        });
        mFadeAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationStart(@NonNull Animator animation) {
                if (show) {
                    animT.show(mBackgroundLeash).show(mIconLeash).apply();
                }
            }

            @Override
            public void onAnimationEnd(@NonNull Animator animation) {
                if (!show) {
                    if (mBackgroundLeash != null) {
                        animT.hide(mBackgroundLeash);
                    }
                    if (mIconLeash != null) {
                        animT.hide(mIconLeash);
                    }
                }
                if (isResized) {
                    releaseDecor(animT);
                }
                animT.apply();
                animT.close();
            }
        });
        mFadeAnimator.start();
    }

    /** Release or hide decor hint. */
    private void releaseDecor(SurfaceControl.Transaction t) {
        if (mBackgroundLeash != null) {
            t.remove(mBackgroundLeash);
            mBackgroundLeash = null;
        }

        if (mIcon != null) {
            mResizingIconView.setVisibility(View.GONE);
            mResizingIconView.setImageDrawable(null);
            t.hide(mIconLeash);
            mIcon = null;
        }
    }

    private static float[] getResizingBackgroundColor(ActivityManager.RunningTaskInfo taskInfo) {
        final int taskBgColor = taskInfo.taskDescription.getBackgroundColor();
        return Color.valueOf(taskBgColor == -1 ? Color.WHITE : taskBgColor).getComponents();
    }
}
