/*
 * 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.server.wm;

import static android.view.Surface.ROTATION_270;
import static android.view.Surface.ROTATION_90;

import android.graphics.Matrix;
import android.os.IBinder;
import android.view.DisplayInfo;
import android.view.Surface.Rotation;
import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;

import com.android.server.wm.utils.CoordinateTransforms;

import java.io.PrintWriter;
import java.io.StringWriter;

/**
 * Helper class for seamless rotation.
 *
 * Works by transforming the {@link WindowState} back into the old display rotation.
 *
 * Uses {@link Transaction#deferTransactionUntil(SurfaceControl, IBinder, long)} instead of
 * latching on the buffer size to allow for seamless 180 degree rotations.
 */
public class SeamlessRotator {

    private final Matrix mTransform = new Matrix();
    private final float[] mFloat9 = new float[9];
    private final int mOldRotation;
    private final int mNewRotation;

    public SeamlessRotator(@Rotation int oldRotation, @Rotation int newRotation, DisplayInfo info) {
        mOldRotation = oldRotation;
        mNewRotation = newRotation;

        final boolean flipped = info.rotation == ROTATION_90 || info.rotation == ROTATION_270;
        final int pH = flipped ? info.logicalWidth : info.logicalHeight;
        final int pW = flipped ? info.logicalHeight : info.logicalWidth;
        // Initialize transform matrix by physical size.
        final Matrix tmp = new Matrix();
        CoordinateTransforms.transformLogicalToPhysicalCoordinates(oldRotation, pW, pH, mTransform);
        CoordinateTransforms.transformPhysicalToLogicalCoordinates(newRotation, pW, pH, tmp);
        mTransform.postConcat(tmp);
    }

    /**
     * Applies a transform to the {@link WindowContainer} surface that undoes the effect of the
     * global display rotation.
     */
    public void unrotate(Transaction transaction, WindowContainer win) {
        transaction.setMatrix(win.getSurfaceControl(), mTransform, mFloat9);
        // WindowState sets the position of the window so transform the position and update it.
        final float[] winSurfacePos = {win.mLastSurfacePosition.x, win.mLastSurfacePosition.y};
        mTransform.mapPoints(winSurfacePos);
        transaction.setPosition(win.getSurfaceControl(), winSurfacePos[0], winSurfacePos[1]);
    }

    /**
     * Returns the rotation of the display before it started rotating.
     *
     * @return the old rotation of the display
     */
    @Rotation
    public int getOldRotation() {
        return mOldRotation;
    }

    /**
     * Removes the transform and sets the previously known surface position for {@link WindowState}
     * surface that undoes the effect of the global display rotation.
     *
     * Removing the transform and the result of the {@link WindowState} layout are both tied to the
     * {@link WindowState} next frame, such that they apply at the same time the client draws the
     * window in the new orientation.
     *
     * In the case of a rotation timeout, we want to remove the transform immediately and not defer
     * it.
     */
    public void finish(WindowState win, boolean timeout) {
        final Transaction t = win.getPendingTransaction();
        finish(t, win);
        if (win.mWinAnimator.mSurfaceController != null && !timeout) {
            t.deferTransactionUntil(win.mSurfaceControl,
                    win.getClientViewRootSurface(), win.getFrameNumber());
            t.deferTransactionUntil(win.mWinAnimator.mSurfaceController.mSurfaceControl,
                    win.getClientViewRootSurface(), win.getFrameNumber());
        }
    }

    /** Removes the transform and restore to the original last position. */
    void finish(Transaction t, WindowContainer win) {
        mTransform.reset();
        t.setMatrix(win.mSurfaceControl, mTransform, mFloat9);
        t.setPosition(win.mSurfaceControl, win.mLastSurfacePosition.x, win.mLastSurfacePosition.y);
    }

    public void dump(PrintWriter pw) {
        pw.print("{old="); pw.print(mOldRotation); pw.print(", new="); pw.print(mNewRotation);
        pw.print("}");
    }

    @Override
    public String toString() {
        StringWriter sw = new StringWriter();
        dump(new PrintWriter(sw));
        return "ForcedSeamlessRotator" + sw.toString();
    }
}
