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

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.content.res.Configuration;
import android.os.Handler;
import android.os.RemoteException;
import android.util.Slog;
import android.util.SparseArray;
import android.view.IDisplayWindowInsetsController;
import android.view.InsetsSource;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.WindowInsets;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;

import com.android.systemui.TransactionPool;
import com.android.systemui.dagger.qualifiers.Main;

import java.util.ArrayList;

import javax.inject.Inject;
import javax.inject.Singleton;

/**
 * Manages IME control at the display-level. This occurs when IME comes up in multi-window mode.
 */
@Singleton
public class DisplayImeController implements DisplayController.OnDisplaysChangedListener {
    private static final String TAG = "DisplayImeController";

    private static final boolean DEBUG = false;

    public static final int ANIMATION_DURATION_SHOW_MS = 275;
    public static final int ANIMATION_DURATION_HIDE_MS = 340;
    public static final Interpolator INTERPOLATOR = new PathInterpolator(0.4f, 0f, 0.2f, 1f);
    private static final int DIRECTION_NONE = 0;
    private static final int DIRECTION_SHOW = 1;
    private static final int DIRECTION_HIDE = 2;

    SystemWindows mSystemWindows;
    final Handler mHandler;
    final TransactionPool mTransactionPool;

    final SparseArray<PerDisplay> mImePerDisplay = new SparseArray<>();

    final ArrayList<ImePositionProcessor> mPositionProcessors = new ArrayList<>();

    @Inject
    public DisplayImeController(SystemWindows syswin, DisplayController displayController,
            @Main Handler mainHandler, TransactionPool transactionPool) {
        mHandler = mainHandler;
        mSystemWindows = syswin;
        mTransactionPool = transactionPool;
        displayController.addDisplayWindowListener(this);
    }

    @Override
    public void onDisplayAdded(int displayId) {
        // Add's a system-ui window-manager specifically for ime. This type is special because
        // WM will defer IME inset handling to it in multi-window scenarious.
        PerDisplay pd = new PerDisplay(displayId,
                mSystemWindows.mDisplayController.getDisplayLayout(displayId).rotation());
        try {
            mSystemWindows.mWmService.setDisplayWindowInsetsController(displayId, pd);
        } catch (RemoteException e) {
            Slog.w(TAG, "Unable to set insets controller on display " + displayId);
        }
        mImePerDisplay.put(displayId, pd);
    }

    @Override
    public void onDisplayConfigurationChanged(int displayId, Configuration newConfig) {
        PerDisplay pd = mImePerDisplay.get(displayId);
        if (pd == null) {
            return;
        }
        if (mSystemWindows.mDisplayController.getDisplayLayout(displayId).rotation()
                != pd.mRotation && isImeShowing(displayId)) {
            pd.startAnimation(true);
        }
    }

    @Override
    public void onDisplayRemoved(int displayId) {
        try {
            mSystemWindows.mWmService.setDisplayWindowInsetsController(displayId, null);
        } catch (RemoteException e) {
            Slog.w(TAG, "Unable to remove insets controller on display " + displayId);
        }
        mImePerDisplay.remove(displayId);
    }

    private boolean isImeShowing(int displayId) {
        PerDisplay pd = mImePerDisplay.get(displayId);
        if (pd == null) {
            return false;
        }
        final InsetsSource imeSource = pd.mInsetsState.getSource(InsetsState.ITYPE_IME);
        return imeSource != null && pd.mImeSourceControl != null && imeSource.isVisible();
    }

    private void dispatchPositionChanged(int displayId, int imeTop,
            SurfaceControl.Transaction t) {
        synchronized (mPositionProcessors) {
            for (ImePositionProcessor pp : mPositionProcessors) {
                pp.onImePositionChanged(displayId, imeTop, t);
            }
        }
    }

    private void dispatchStartPositioning(int displayId, int hiddenTop, int shownTop,
            boolean show, SurfaceControl.Transaction t) {
        synchronized (mPositionProcessors) {
            for (ImePositionProcessor pp : mPositionProcessors) {
                pp.onImeStartPositioning(displayId, hiddenTop, shownTop, show, t);
            }
        }
    }

    private void dispatchEndPositioning(int displayId, boolean cancel,
            SurfaceControl.Transaction t) {
        synchronized (mPositionProcessors) {
            for (ImePositionProcessor pp : mPositionProcessors) {
                pp.onImeEndPositioning(displayId, cancel, t);
            }
        }
    }

    /**
     * Adds an {@link ImePositionProcessor} to be called during ime position updates.
     */
    public void addPositionProcessor(ImePositionProcessor processor) {
        synchronized (mPositionProcessors) {
            if (mPositionProcessors.contains(processor)) {
                return;
            }
            mPositionProcessors.add(processor);
        }
    }

    /**
     * Removes an {@link ImePositionProcessor} to be called during ime position updates.
     */
    public void removePositionProcessor(ImePositionProcessor processor) {
        synchronized (mPositionProcessors) {
            mPositionProcessors.remove(processor);
        }
    }

    class PerDisplay extends IDisplayWindowInsetsController.Stub {
        final int mDisplayId;
        final InsetsState mInsetsState = new InsetsState();
        InsetsSourceControl mImeSourceControl = null;
        int mAnimationDirection = DIRECTION_NONE;
        ValueAnimator mAnimation = null;
        int mRotation = Surface.ROTATION_0;
        boolean mImeShowing = false;

        private float mX;
        private float mHiddenY;
        private float mShownY;
        private float mStartY;
        private float mEndY;

        private final Runnable mUpdateAnimationParams = () -> {
            final InsetsSource imeSource = mInsetsState.getSource(InsetsState.ITYPE_IME);
            final boolean show = mAnimationDirection == DIRECTION_SHOW;
            final float defaultY = mImeSourceControl.getSurfacePosition().y;
            mX = mImeSourceControl.getSurfacePosition().x;
            mHiddenY = defaultY + imeSource.getFrame().height();
            mShownY = defaultY;
            mStartY = show ? mHiddenY : mShownY;
            mEndY = show ? mShownY : mHiddenY;
        };

        PerDisplay(int displayId, int initialRotation) {
            mDisplayId = displayId;
            mRotation = initialRotation;
        }

        @Override
        public void insetsChanged(InsetsState insetsState) {
            if (mInsetsState.equals(insetsState)) {
                return;
            }
            mInsetsState.set(insetsState, true /* copySources */);
        }

        @Override
        public void insetsControlChanged(InsetsState insetsState,
                InsetsSourceControl[] activeControls) {
            insetsChanged(insetsState);
            if (activeControls != null) {
                for (InsetsSourceControl activeControl : activeControls) {
                    if (activeControl == null) {
                        continue;
                    }
                    if (activeControl.getType() == InsetsState.ITYPE_IME) {
                        if (mImeSourceControl != activeControl) {
                            mImeSourceControl = activeControl;
                            mHandler.post(mUpdateAnimationParams);
                        }
                    }
                }
            }
        }

        @Override
        public void showInsets(int types, boolean fromIme) {
            if ((types & WindowInsets.Type.ime()) == 0) {
                return;
            }
            if (DEBUG) Slog.d(TAG, "Got showInsets for ime");
            startAnimation(true /* show */);
        }

        @Override
        public void hideInsets(int types, boolean fromIme) {
            if ((types & WindowInsets.Type.ime()) == 0) {
                return;
            }
            if (DEBUG) Slog.d(TAG, "Got hideInsets for ime");
            startAnimation(false /* show */);
        }

        /**
         * Sends the local visibility state back to window manager. Needed for legacy adjustForIme.
         */
        private void setVisibleDirectly(boolean visible) {
            mInsetsState.getSource(InsetsState.ITYPE_IME).setVisible(visible);
            try {
                mSystemWindows.mWmService.modifyDisplayWindowInsets(mDisplayId, mInsetsState);
            } catch (RemoteException e) {
            }
        }

        private int imeTop(InsetsSource imeSource, float surfaceOffset) {
            return imeSource.getFrame().top + (int) surfaceOffset;
        }

        private void startAnimation(final boolean show) {
            final InsetsSource imeSource = mInsetsState.getSource(InsetsState.ITYPE_IME);
            if (imeSource == null || mImeSourceControl == null) {
                return;
            }
            mHandler.post(() -> {
                if (DEBUG) {
                    Slog.d(TAG, "Run startAnim  show:" + show + "  was:"
                            + (mAnimationDirection == DIRECTION_SHOW ? "SHOW"
                            : (mAnimationDirection == DIRECTION_HIDE ? "HIDE" : "NONE")));
                }
                if ((mAnimationDirection == DIRECTION_SHOW && show)
                        || (mAnimationDirection == DIRECTION_HIDE && !show)) {
                    return;
                }
                boolean seek = false;
                float seekValue = 0;
                if (mAnimation != null) {
                    if (mAnimation.isRunning()) {
                        seekValue = (float) mAnimation.getAnimatedValue();
                        seek = true;
                    }
                    mAnimation.cancel();
                }
                mAnimationDirection = show ? DIRECTION_SHOW : DIRECTION_HIDE;
                final float defaultY = mImeSourceControl.getSurfacePosition().y;
                mX = mImeSourceControl.getSurfacePosition().x;
                mHiddenY = defaultY + imeSource.getFrame().height();
                mShownY = defaultY;
                mStartY = show ? mHiddenY : mShownY;
                mEndY = show ? mShownY : mHiddenY;
                if (mImeShowing && show) {
                    // IME is already showing, so set seek to end
                    seekValue = mShownY;
                    seek = true;
                }
                mImeShowing = show;
                mAnimation = ValueAnimator.ofFloat(mStartY, mEndY);
                mAnimation.setDuration(
                        show ? ANIMATION_DURATION_SHOW_MS : ANIMATION_DURATION_HIDE_MS);
                if (seek) {
                    mAnimation.setCurrentFraction((seekValue - mStartY) / (mEndY - mStartY));
                }

                mAnimation.addUpdateListener(animation -> {
                    SurfaceControl.Transaction t = mTransactionPool.acquire();
                    float value = (float) animation.getAnimatedValue();
                    t.setPosition(mImeSourceControl.getLeash(), mX, value);
                    dispatchPositionChanged(mDisplayId, imeTop(imeSource, value), t);
                    t.apply();
                    mTransactionPool.release(t);
                });
                mAnimation.setInterpolator(INTERPOLATOR);
                mAnimation.addListener(new AnimatorListenerAdapter() {
                    private boolean mCancelled = false;
                    @Override
                    public void onAnimationStart(Animator animation) {
                        SurfaceControl.Transaction t = mTransactionPool.acquire();
                        t.setPosition(mImeSourceControl.getLeash(), mX, mStartY);
                        if (DEBUG) {
                            Slog.d(TAG, "onAnimationStart d:" + mDisplayId + " top:"
                                    + imeTop(imeSource, mHiddenY) + "->"
                                    + imeTop(imeSource, mShownY)
                                    + " showing:" + (mAnimationDirection == DIRECTION_SHOW));
                        }
                        dispatchStartPositioning(mDisplayId, imeTop(imeSource, mHiddenY),
                                imeTop(imeSource, mShownY), mAnimationDirection == DIRECTION_SHOW,
                                t);
                        if (mAnimationDirection == DIRECTION_SHOW) {
                            t.show(mImeSourceControl.getLeash());
                        }
                        t.apply();
                        mTransactionPool.release(t);
                    }
                    @Override
                    public void onAnimationCancel(Animator animation) {
                        mCancelled = true;
                    }
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        if (DEBUG) Slog.d(TAG, "onAnimationEnd " + mCancelled);
                        SurfaceControl.Transaction t = mTransactionPool.acquire();
                        if (!mCancelled) {
                            t.setPosition(mImeSourceControl.getLeash(), mX, mEndY);
                        }
                        dispatchEndPositioning(mDisplayId, mCancelled, t);
                        if (mAnimationDirection == DIRECTION_HIDE && !mCancelled) {
                            t.hide(mImeSourceControl.getLeash());
                        }
                        t.apply();
                        mTransactionPool.release(t);

                        mAnimationDirection = DIRECTION_NONE;
                        mAnimation = null;
                    }
                });
                if (!show) {
                    // When going away, queue up insets change first, otherwise any bounds changes
                    // can have a "flicker" of ime-provided insets.
                    setVisibleDirectly(false /* visible */);
                }
                mAnimation.start();
                if (show) {
                    // When showing away, queue up insets change last, otherwise any bounds changes
                    // can have a "flicker" of ime-provided insets.
                    setVisibleDirectly(true /* visible */);
                }
            });
        }
    }

    /**
     * Allows other things to synchronize with the ime position
     */
    public interface ImePositionProcessor {
        /**
         * Called when the IME position is starting to animate.
         *
         * @param hiddenTop The y position of the top of the IME surface when it is hidden.
         * @param shownTop The y position of the top of the IME surface when it is shown.
         * @param showing {@code true} when we are animating from hidden to shown, {@code false}
         *                            when animating from shown to hidden.
         */
        default void onImeStartPositioning(int displayId, int hiddenTop, int shownTop,
                boolean showing, SurfaceControl.Transaction t) {}

        /**
         * Called when the ime position changed. This is expected to be a synchronous call on the
         * animation thread. Operations can be added to the transaction to be applied in sync.
         *
         * @param imeTop The current y position of the top of the IME surface.
         */
        default void onImePositionChanged(int displayId, int imeTop,
                SurfaceControl.Transaction t) {}

        /**
         * Called when the IME position is done animating.
         *
         * @param cancel {@code true} if this was cancelled. This implies another start is coming.
         */
        default void onImeEndPositioning(int displayId, boolean cancel,
                SurfaceControl.Transaction t) {}
    }
}
