/*
 * 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.pip.tv;

import static android.view.KeyEvent.KEYCODE_DPAD_DOWN;
import static android.view.KeyEvent.KEYCODE_DPAD_LEFT;
import static android.view.KeyEvent.KEYCODE_DPAD_RIGHT;
import static android.view.KeyEvent.KEYCODE_DPAD_UP;

import static com.android.wm.shell.pip.tv.TvPipBoundsState.ORIENTATION_HORIZONTAL;
import static com.android.wm.shell.pip.tv.TvPipBoundsState.ORIENTATION_UNDETERMINED;
import static com.android.wm.shell.pip.tv.TvPipBoundsState.ORIENTATION_VERTICAL;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Insets;
import android.graphics.Rect;
import android.util.ArraySet;
import android.util.Size;
import android.view.Gravity;

import androidx.annotation.NonNull;

import com.android.internal.protolog.common.ProtoLog;
import com.android.wm.shell.R;
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.pip.PipBoundsAlgorithm;
import com.android.wm.shell.pip.PipKeepClearAlgorithm;
import com.android.wm.shell.pip.PipSnapAlgorithm;
import com.android.wm.shell.pip.tv.TvPipKeepClearAlgorithm.Placement;
import com.android.wm.shell.protolog.ShellProtoLogGroup;

import java.util.Set;

/**
 * Contains pip bounds calculations that are specific to TV.
 */
public class TvPipBoundsAlgorithm extends PipBoundsAlgorithm {

    private static final String TAG = TvPipBoundsAlgorithm.class.getSimpleName();
    private static final boolean DEBUG = TvPipController.DEBUG;

    private final @NonNull TvPipBoundsState mTvPipBoundsState;

    private int mFixedExpandedHeightInPx;
    private int mFixedExpandedWidthInPx;

    private final TvPipKeepClearAlgorithm mKeepClearAlgorithm;

    public TvPipBoundsAlgorithm(Context context,
            @NonNull TvPipBoundsState tvPipBoundsState,
            @NonNull PipSnapAlgorithm pipSnapAlgorithm) {
        super(context, tvPipBoundsState, pipSnapAlgorithm,
                new PipKeepClearAlgorithm() {});
        this.mTvPipBoundsState = tvPipBoundsState;
        this.mKeepClearAlgorithm = new TvPipKeepClearAlgorithm();
        reloadResources(context);
    }

    private void reloadResources(Context context) {
        final Resources res = context.getResources();
        mFixedExpandedHeightInPx = res.getDimensionPixelSize(
                com.android.internal.R.dimen.config_pictureInPictureExpandedHorizontalHeight);
        mFixedExpandedWidthInPx = res.getDimensionPixelSize(
                com.android.internal.R.dimen.config_pictureInPictureExpandedVerticalWidth);
        mKeepClearAlgorithm.setPipAreaPadding(
                res.getDimensionPixelSize(R.dimen.pip_keep_clear_area_padding));
        mKeepClearAlgorithm.setMaxRestrictedDistanceFraction(
                res.getFraction(R.fraction.config_pipMaxRestrictedMoveDistance, 1, 1));
    }

    @Override
    public void onConfigurationChanged(Context context) {
        super.onConfigurationChanged(context);
        reloadResources(context);
    }

    /** Returns the destination bounds to place the PIP window on entry. */
    @Override
    public Rect getEntryDestinationBounds() {
        if (DEBUG) {
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                    "%s: getEntryDestinationBounds()", TAG);
        }
        updateExpandedPipSize();
        final boolean isPipExpanded = mTvPipBoundsState.isTvExpandedPipSupported()
                && mTvPipBoundsState.getDesiredTvExpandedAspectRatio() != 0
                && !mTvPipBoundsState.isTvPipManuallyCollapsed();
        if (isPipExpanded) {
            updateGravityOnExpandToggled(Gravity.NO_GRAVITY, true);
        }
        mTvPipBoundsState.setTvPipExpanded(isPipExpanded);
        return adjustBoundsForTemporaryDecor(getTvPipPlacement().getBounds());
    }

    /** Returns the current bounds adjusted to the new aspect ratio, if valid. */
    @Override
    public Rect getAdjustedDestinationBounds(Rect currentBounds, float newAspectRatio) {
        if (DEBUG) {
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                    "%s: getAdjustedDestinationBounds: %f", TAG, newAspectRatio);
        }
        return adjustBoundsForTemporaryDecor(getTvPipPlacement().getBounds());
    }

    Rect adjustBoundsForTemporaryDecor(Rect bounds) {
        Rect boundsWithDecor = new Rect(bounds);
        Insets decorInset = mTvPipBoundsState.getPipMenuTemporaryDecorInsets();
        Insets pipDecorReverseInsets = Insets.subtract(Insets.NONE, decorInset);
        boundsWithDecor.inset(decorInset);
        Gravity.apply(mTvPipBoundsState.getTvPipGravity(),
                boundsWithDecor.width(), boundsWithDecor.height(), bounds, boundsWithDecor);

        // remove temporary decoration again
        boundsWithDecor.inset(pipDecorReverseInsets);
        return boundsWithDecor;
    }

    /**
     * Calculates the PiP bounds.
     */
    @NonNull
    public Placement getTvPipPlacement() {
        final Size pipSize = getPipSize();
        final Rect displayBounds = mTvPipBoundsState.getDisplayBounds();
        final Size screenSize = new Size(displayBounds.width(), displayBounds.height());
        final Rect insetBounds = new Rect();
        getInsetBounds(insetBounds);

        Set<Rect> restrictedKeepClearAreas = mTvPipBoundsState.getRestrictedKeepClearAreas();
        Set<Rect> unrestrictedKeepClearAreas = mTvPipBoundsState.getUnrestrictedKeepClearAreas();

        if (mTvPipBoundsState.isImeShowing()) {
            if (DEBUG) {
                ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                        "%s: IME showing, height: %d",
                        TAG, mTvPipBoundsState.getImeHeight());
            }

            final Rect imeBounds = new Rect(
                    0,
                    insetBounds.bottom - mTvPipBoundsState.getImeHeight(),
                    insetBounds.right,
                    insetBounds.bottom);

            unrestrictedKeepClearAreas = new ArraySet<>(unrestrictedKeepClearAreas);
            unrestrictedKeepClearAreas.add(imeBounds);
        }

        mKeepClearAlgorithm.setGravity(mTvPipBoundsState.getTvPipGravity());
        mKeepClearAlgorithm.setScreenSize(screenSize);
        mKeepClearAlgorithm.setMovementBounds(insetBounds);
        mKeepClearAlgorithm.setStashOffset(mTvPipBoundsState.getStashOffset());
        mKeepClearAlgorithm.setPipPermanentDecorInsets(
                mTvPipBoundsState.getPipMenuPermanentDecorInsets());

        final Placement placement = mKeepClearAlgorithm.calculatePipPosition(
                pipSize,
                restrictedKeepClearAreas,
                unrestrictedKeepClearAreas);

        if (DEBUG) {
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                    "%s: screenSize: %s", TAG, screenSize);
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                    "%s: stashOffset: %d", TAG, mTvPipBoundsState.getStashOffset());
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                    "%s: insetBounds: %s", TAG, insetBounds.toShortString());
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                    "%s: pipSize: %s", TAG, pipSize);
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                    "%s: gravity: %s", TAG, Gravity.toString(mTvPipBoundsState.getTvPipGravity()));
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                    "%s: restrictedKeepClearAreas: %s", TAG, restrictedKeepClearAreas);
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                    "%s: unrestrictedKeepClearAreas: %s", TAG, unrestrictedKeepClearAreas);
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                    "%s: placement: %s", TAG, placement);
        }

        return placement;
    }

    /**
     * @return previous gravity if it is to be saved, or {@link Gravity#NO_GRAVITY} if not.
     */
    int updateGravityOnExpandToggled(int previousGravity, boolean expanding) {
        if (DEBUG) {
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                    "%s: updateGravityOnExpandToggled(), expanding: %b"
                    + ", mOrientation: %d, previous gravity: %s",
                    TAG, expanding, mTvPipBoundsState.getTvFixedPipOrientation(),
                    Gravity.toString(previousGravity));
        }

        if (!mTvPipBoundsState.isTvExpandedPipSupported()) {
            return Gravity.NO_GRAVITY;
        }

        if (expanding && mTvPipBoundsState.getTvFixedPipOrientation() == ORIENTATION_UNDETERMINED) {
            float expandedRatio = mTvPipBoundsState.getDesiredTvExpandedAspectRatio();
            if (expandedRatio == 0) {
                return Gravity.NO_GRAVITY;
            }
            if (expandedRatio < 1) {
                mTvPipBoundsState.setTvFixedPipOrientation(ORIENTATION_VERTICAL);
            } else {
                mTvPipBoundsState.setTvFixedPipOrientation(ORIENTATION_HORIZONTAL);
            }
        }

        int gravityToSave = Gravity.NO_GRAVITY;
        int currentGravity = mTvPipBoundsState.getTvPipGravity();
        int updatedGravity;

        if (expanding) {
            // save collapsed gravity
            gravityToSave = mTvPipBoundsState.getTvPipGravity();

            if (mTvPipBoundsState.getTvFixedPipOrientation() == ORIENTATION_HORIZONTAL) {
                updatedGravity =
                        Gravity.CENTER_HORIZONTAL | (currentGravity
                                & Gravity.VERTICAL_GRAVITY_MASK);
            } else {
                updatedGravity =
                        Gravity.CENTER_VERTICAL | (currentGravity
                                & Gravity.HORIZONTAL_GRAVITY_MASK);
            }
        } else {
            if (previousGravity != Gravity.NO_GRAVITY) {
                // The pip hasn't been moved since expanding,
                // go back to previous collapsed position.
                updatedGravity = previousGravity;
            } else {
                if (mTvPipBoundsState.getTvFixedPipOrientation() == ORIENTATION_HORIZONTAL) {
                    updatedGravity =
                            Gravity.RIGHT | (currentGravity & Gravity.VERTICAL_GRAVITY_MASK);
                } else {
                    updatedGravity =
                            Gravity.BOTTOM | (currentGravity & Gravity.HORIZONTAL_GRAVITY_MASK);
                }
            }
        }
        mTvPipBoundsState.setTvPipGravity(updatedGravity);
        if (DEBUG) {
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                    "%s: new gravity: %s", TAG, Gravity.toString(updatedGravity));
        }

        return gravityToSave;
    }

    /**
     * @return true if gravity changed
     */
    boolean updateGravity(int keycode) {
        if (DEBUG) {
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                    "%s: updateGravity, keycode: %d", TAG, keycode);
        }

        // Check if position change is valid
        if (mTvPipBoundsState.isTvPipExpanded()) {
            int mOrientation = mTvPipBoundsState.getTvFixedPipOrientation();
            if (mOrientation == ORIENTATION_VERTICAL
                    && (keycode == KEYCODE_DPAD_UP || keycode == KEYCODE_DPAD_DOWN)
                    || mOrientation == ORIENTATION_HORIZONTAL
                    && (keycode == KEYCODE_DPAD_RIGHT || keycode == KEYCODE_DPAD_LEFT)) {
                return false;
            }
        }

        int currentGravity = mTvPipBoundsState.getTvPipGravity();
        int updatedGravity;
        // First axis
        switch (keycode) {
            case KEYCODE_DPAD_UP:
                updatedGravity = Gravity.TOP;
                break;
            case KEYCODE_DPAD_DOWN:
                updatedGravity = Gravity.BOTTOM;
                break;
            case KEYCODE_DPAD_LEFT:
                updatedGravity = Gravity.LEFT;
                break;
            case KEYCODE_DPAD_RIGHT:
                updatedGravity = Gravity.RIGHT;
                break;
            default:
                updatedGravity = currentGravity;
        }

        // Second axis
        switch (keycode) {
            case KEYCODE_DPAD_UP:
            case KEYCODE_DPAD_DOWN:
                if (mTvPipBoundsState.isTvPipExpanded()) {
                    updatedGravity |= Gravity.CENTER_HORIZONTAL;
                } else {
                    updatedGravity |= (currentGravity & Gravity.HORIZONTAL_GRAVITY_MASK);
                }
                break;
            case KEYCODE_DPAD_LEFT:
            case KEYCODE_DPAD_RIGHT:
                if (mTvPipBoundsState.isTvPipExpanded()) {
                    updatedGravity |= Gravity.CENTER_VERTICAL;
                } else {
                    updatedGravity |= (currentGravity & Gravity.VERTICAL_GRAVITY_MASK);
                }
                break;
            default:
                break;
        }

        if (updatedGravity != currentGravity) {
            mTvPipBoundsState.setTvPipGravity(updatedGravity);
            if (DEBUG) {
                ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                        "%s: new gravity: %s", TAG, Gravity.toString(updatedGravity));
            }
            return true;
        }
        return false;
    }

    private Size getPipSize() {
        final boolean isExpanded =
                mTvPipBoundsState.isTvExpandedPipSupported() && mTvPipBoundsState.isTvPipExpanded()
                        && mTvPipBoundsState.getDesiredTvExpandedAspectRatio() != 0;
        if (isExpanded) {
            return mTvPipBoundsState.getTvExpandedSize();
        } else {
            final Rect normalBounds = getNormalBounds();
            return new Size(normalBounds.width(), normalBounds.height());
        }
    }

    /**
     * Updates {@link TvPipBoundsState#getTvExpandedSize()} based on
     * {@link TvPipBoundsState#getDesiredTvExpandedAspectRatio()}, the screen size.
     */
    void updateExpandedPipSize() {
        final DisplayLayout displayLayout = mTvPipBoundsState.getDisplayLayout();
        final float expandedRatio =
                mTvPipBoundsState.getDesiredTvExpandedAspectRatio(); // width / height
        final Insets pipDecorations = mTvPipBoundsState.getPipMenuPermanentDecorInsets();

        final Size expandedSize;
        if (expandedRatio == 0) {
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                       "%s: updateExpandedPipSize(): Expanded mode aspect ratio"
                               + " of 0 not supported", TAG);
            return;
        } else if (expandedRatio < 1) {
            // vertical
            if (mTvPipBoundsState.getTvFixedPipOrientation() == ORIENTATION_HORIZONTAL) {
                expandedSize = mTvPipBoundsState.getTvExpandedSize();
            } else {
                int maxHeight = displayLayout.height() - (2 * mScreenEdgeInsets.y)
                        - pipDecorations.top - pipDecorations.bottom;
                float aspectRatioHeight = mFixedExpandedWidthInPx / expandedRatio;

                if (maxHeight > aspectRatioHeight) {
                    if (DEBUG) {
                        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                                "%s: Accommodate aspect ratio", TAG);
                    }
                    expandedSize = new Size(mFixedExpandedWidthInPx, (int) aspectRatioHeight);
                } else {
                    if (DEBUG) {
                        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                                "%s: Aspect ratio is too extreme, use max size", TAG);
                    }
                    expandedSize = new Size(mFixedExpandedWidthInPx, maxHeight);
                }
            }
        } else {
            // horizontal
            if (mTvPipBoundsState.getTvFixedPipOrientation() == ORIENTATION_VERTICAL) {
                expandedSize = mTvPipBoundsState.getTvExpandedSize();
            } else {
                int maxWidth = displayLayout.width() - (2 * mScreenEdgeInsets.x)
                        - pipDecorations.left - pipDecorations.right;
                float aspectRatioWidth = mFixedExpandedHeightInPx * expandedRatio;
                if (maxWidth > aspectRatioWidth) {
                    if (DEBUG) {
                        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                                "%s: Accommodate aspect ratio", TAG);
                    }
                    expandedSize = new Size((int) aspectRatioWidth, mFixedExpandedHeightInPx);
                } else {
                    if (DEBUG) {
                        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                                "%s: Aspect ratio is too extreme, use max size", TAG);
                    }
                    expandedSize = new Size(maxWidth, mFixedExpandedHeightInPx);
                }
            }
        }

        mTvPipBoundsState.setTvExpandedSize(expandedSize);
        if (DEBUG) {
            ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
                       "%s: updateExpandedPipSize(): expanded size, width: %d, height: %d",
                    TAG, expandedSize.getWidth(), expandedSize.getHeight());
        }
    }
}
