/*
 * Copyright (C) 2010 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 android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.util.Slog;
import android.view.Surface;
import android.view.SurfaceSession;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Transformation;

class ScreenRotationAnimation {
    static final String TAG = "ScreenRotationAnimation";
    static final boolean DEBUG = false;

    static final int FREEZE_LAYER = WindowManagerService.TYPE_LAYER_MULTIPLIER * 200;

    final Context mContext;
    Surface mSurface;
    BlackFrame mBlackFrame;
    int mWidth, mHeight;

    int mSnapshotRotation;
    int mSnapshotDeltaRotation;
    int mOriginalRotation;
    int mOriginalWidth, mOriginalHeight;
    int mCurRotation;

    Animation mExitAnimation;
    final Transformation mExitTransformation = new Transformation();
    Animation mEnterAnimation;
    final Transformation mEnterTransformation = new Transformation();
    boolean mStarted;

    final Matrix mSnapshotInitialMatrix = new Matrix();
    final Matrix mSnapshotFinalMatrix = new Matrix();
    final Matrix mTmpMatrix = new Matrix();
    final float[] mTmpFloats = new float[9];

    public ScreenRotationAnimation(Context context, SurfaceSession session,
            boolean inTransaction, int originalWidth, int originalHeight, int originalRotation) {
        mContext = context;

        // Screenshot does NOT include rotation!
        mSnapshotRotation = 0;
        if (originalRotation == Surface.ROTATION_90
                || originalRotation == Surface.ROTATION_270) {
            mWidth = originalHeight;
            mHeight = originalWidth;
        } else {
            mWidth = originalWidth;
            mHeight = originalHeight;
        }

        mOriginalRotation = originalRotation;
        mOriginalWidth = originalWidth;
        mOriginalHeight = originalHeight;

        if (!inTransaction) {
            if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
                    ">>> OPEN TRANSACTION ScreenRotationAnimation");
            Surface.openTransaction();
        }
        
        try {
            try {
                mSurface = new Surface(session, 0, "FreezeSurface",
                        -1, mWidth, mHeight, PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT | Surface.HIDDEN);
                if (mSurface == null || !mSurface.isValid()) {
                    // Screenshot failed, punt.
                    mSurface = null;
                    return;
                }
                mSurface.setLayer(FREEZE_LAYER + 1);
                mSurface.show();
            } catch (Surface.OutOfResourcesException e) {
                Slog.w(TAG, "Unable to allocate freeze surface", e);
            }

            if (WindowManagerService.SHOW_TRANSACTIONS ||
                    WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG,
                            "  FREEZE " + mSurface + ": CREATE");

            setRotation(originalRotation);
        } finally {
            if (!inTransaction) {
                Surface.closeTransaction();
                if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
                        "<<< CLOSE TRANSACTION ScreenRotationAnimation");
            }
        }
    }

    boolean hasScreenshot() {
        return mSurface != null;
    }

    static int deltaRotation(int oldRotation, int newRotation) {
        int delta = newRotation - oldRotation;
        if (delta < 0) delta += 4;
        return delta;
    }

    void setSnapshotTransform(Matrix matrix, float alpha) {
        if (mSurface != null) {
            matrix.getValues(mTmpFloats);
            mSurface.setPosition(mTmpFloats[Matrix.MTRANS_X],
                    mTmpFloats[Matrix.MTRANS_Y]);
            mSurface.setMatrix(
                    mTmpFloats[Matrix.MSCALE_X], mTmpFloats[Matrix.MSKEW_Y],
                    mTmpFloats[Matrix.MSKEW_X], mTmpFloats[Matrix.MSCALE_Y]);
            mSurface.setAlpha(alpha);
            if (DEBUG) {
                float[] srcPnts = new float[] { 0, 0, mWidth, mHeight };
                float[] dstPnts = new float[4];
                matrix.mapPoints(dstPnts, srcPnts);
                Slog.i(TAG, "Original  : (" + srcPnts[0] + "," + srcPnts[1]
                        + ")-(" + srcPnts[2] + "," + srcPnts[3] + ")");
                Slog.i(TAG, "Transformed: (" + dstPnts[0] + "," + dstPnts[1]
                        + ")-(" + dstPnts[2] + "," + dstPnts[3] + ")");
            }
        }
    }

    public static void createRotationMatrix(int rotation, int width, int height,
            Matrix outMatrix) {
        switch (rotation) {
            case Surface.ROTATION_0:
                outMatrix.reset();
                break;
            case Surface.ROTATION_90:
                outMatrix.setRotate(90, 0, 0);
                outMatrix.postTranslate(height, 0);
                break;
            case Surface.ROTATION_180:
                outMatrix.setRotate(180, 0, 0);
                outMatrix.postTranslate(width, height);
                break;
            case Surface.ROTATION_270:
                outMatrix.setRotate(270, 0, 0);
                outMatrix.postTranslate(0, width);
                break;
        }
    }

    // Must be called while in a transaction.
    public void setRotation(int rotation) {
        mCurRotation = rotation;

        // Compute the transformation matrix that must be applied
        // to the snapshot to make it stay in the same original position
        // with the current screen rotation.
        int delta = deltaRotation(rotation, mSnapshotRotation);
        createRotationMatrix(delta, mWidth, mHeight, mSnapshotInitialMatrix);

        if (DEBUG) Slog.v(TAG, "**** ROTATION: " + delta);
        setSnapshotTransform(mSnapshotInitialMatrix, 1.0f);
    }

    /**
     * Returns true if animating.
     */
    public boolean dismiss(SurfaceSession session, long maxAnimationDuration,
            float animationScale, int finalWidth, int finalHeight) {
        if (mSurface == null) {
            // Can't do animation.
            return false;
        }

        // Figure out how the screen has moved from the original rotation.
        int delta = deltaRotation(mCurRotation, mOriginalRotation);

        switch (delta) {
            case Surface.ROTATION_0:
                mExitAnimation = AnimationUtils.loadAnimation(mContext,
                        com.android.internal.R.anim.screen_rotate_0_exit);
                mEnterAnimation = AnimationUtils.loadAnimation(mContext,
                        com.android.internal.R.anim.screen_rotate_0_enter);
                break;
            case Surface.ROTATION_90:
                mExitAnimation = AnimationUtils.loadAnimation(mContext,
                        com.android.internal.R.anim.screen_rotate_plus_90_exit);
                mEnterAnimation = AnimationUtils.loadAnimation(mContext,
                        com.android.internal.R.anim.screen_rotate_plus_90_enter);
                break;
            case Surface.ROTATION_180:
                mExitAnimation = AnimationUtils.loadAnimation(mContext,
                        com.android.internal.R.anim.screen_rotate_180_exit);
                mEnterAnimation = AnimationUtils.loadAnimation(mContext,
                        com.android.internal.R.anim.screen_rotate_180_enter);
                break;
            case Surface.ROTATION_270:
                mExitAnimation = AnimationUtils.loadAnimation(mContext,
                        com.android.internal.R.anim.screen_rotate_minus_90_exit);
                mEnterAnimation = AnimationUtils.loadAnimation(mContext,
                        com.android.internal.R.anim.screen_rotate_minus_90_enter);
                break;
        }

        // Initialize the animations.  This is a hack, redefining what "parent"
        // means to allow supplying the last and next size.  In this definition
        // "%p" is the original (let's call it "previous") size, and "%" is the
        // screen's current/new size.
        mEnterAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
        mExitAnimation.initialize(finalWidth, finalHeight, mOriginalWidth, mOriginalHeight);
        mStarted = false;

        mExitAnimation.restrictDuration(maxAnimationDuration);
        mExitAnimation.scaleCurrentDuration(animationScale);
        mEnterAnimation.restrictDuration(maxAnimationDuration);
        mEnterAnimation.scaleCurrentDuration(animationScale);

        if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
                ">>> OPEN TRANSACTION ScreenRotationAnimation.dismiss");
        Surface.openTransaction();

        try {
            Rect outer = new Rect(-finalWidth, -finalHeight, finalWidth * 2, finalHeight * 2);
            Rect inner = new Rect(0, 0, finalWidth, finalHeight);
            mBlackFrame = new BlackFrame(session, outer, inner, FREEZE_LAYER);
        } catch (Surface.OutOfResourcesException e) {
            Slog.w(TAG, "Unable to allocate black surface", e);
        } finally {
            Surface.closeTransaction();
            if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG,
                    "<<< CLOSE TRANSACTION ScreenRotationAnimation.dismiss");
        }

        return true;
    }

    public void kill() {
        if (mSurface != null) {
            if (WindowManagerService.SHOW_TRANSACTIONS ||
                    WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG,
                            "  FREEZE " + mSurface + ": DESTROY");
            mSurface.destroy();
            mSurface = null;
        }
        if (mBlackFrame != null) {
            mBlackFrame.kill();
        }
        if (mExitAnimation != null) {
            mExitAnimation.cancel();
            mExitAnimation = null;
        }
        if (mEnterAnimation != null) {
            mEnterAnimation.cancel();
            mEnterAnimation = null;
        }
    }

    public boolean isAnimating() {
        return mEnterAnimation != null || mExitAnimation != null;
    }

    public boolean stepAnimation(long now) {
        if (mEnterAnimation == null && mExitAnimation == null) {
            return false;
        }

        if (!mStarted) {
            if (mEnterAnimation != null) {
                mEnterAnimation.setStartTime(now);
            }
            if (mExitAnimation != null) {
                mExitAnimation.setStartTime(now);
            }
            mStarted = true;
        }

        mExitTransformation.clear();
        boolean moreExit = false;
        if (mExitAnimation != null) {
            moreExit = mExitAnimation.getTransformation(now, mExitTransformation);
            if (DEBUG) Slog.v(TAG, "Stepped exit: " + mExitTransformation);
            if (!moreExit) {
                if (DEBUG) Slog.v(TAG, "Exit animation done!");
                mExitAnimation.cancel();
                mExitAnimation = null;
                mExitTransformation.clear();
                if (mSurface != null) {
                    mSurface.hide();
                }
            }
        }

        mEnterTransformation.clear();
        boolean moreEnter = false;
        if (mEnterAnimation != null) {
            moreEnter = mEnterAnimation.getTransformation(now, mEnterTransformation);
            if (!moreEnter) {
                mEnterAnimation.cancel();
                mEnterAnimation = null;
                mEnterTransformation.clear();
                if (mBlackFrame != null) {
                    mBlackFrame.hide();
                }
            } else {
                if (mBlackFrame != null) {
                    mBlackFrame.setMatrix(mEnterTransformation.getMatrix());
                }
            }
        }

        mSnapshotFinalMatrix.setConcat(mExitTransformation.getMatrix(), mSnapshotInitialMatrix);
        setSnapshotTransform(mSnapshotFinalMatrix, mExitTransformation.getAlpha());

        return moreEnter || moreExit;
    }

    public Transformation getEnterTransformation() {
        return mEnterTransformation;
    }
}
