/*
 * Copyright (C) 2014 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 com.android.server.wm.WindowManagerDebugConfig.DEBUG_DIM_LAYER;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;

import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.SystemClock;
import android.util.Slog;
import android.view.DisplayInfo;
import android.view.SurfaceControl;

import java.io.PrintWriter;

public class DimLayer {
    private static final String TAG = TAG_WITH_CLASS_NAME ? "DimLayer" : TAG_WM;
    private final WindowManagerService mService;

    /** Actual surface that dims */
    private SurfaceControl mDimSurface;

    /** Last value passed to mDimSurface.setAlpha() */
    private float mAlpha = 0;

    /** Last value passed to mDimSurface.setLayer() */
    private int mLayer = -1;

    /** Next values to pass to mDimSurface.setPosition() and mDimSurface.setSize() */
    private final Rect mBounds = new Rect();

    /** Last values passed to mDimSurface.setPosition() and mDimSurface.setSize() */
    private final Rect mLastBounds = new Rect();

    /** True after mDimSurface.show() has been called, false after mDimSurface.hide(). */
    private boolean mShowing = false;

    /** Value of mAlpha when beginning transition to mTargetAlpha */
    private float mStartAlpha = 0;

    /** Final value of mAlpha following transition */
    private float mTargetAlpha = 0;

    /** Time in units of SystemClock.uptimeMillis() at which the current transition started */
    private long mStartTime;

    /** Time in milliseconds to take to transition from mStartAlpha to mTargetAlpha */
    private long mDuration;

    private boolean mDestroyed = false;

    private final int mDisplayId;


    /** Interface implemented by users of the dim layer */
    interface DimLayerUser {
        /** Returns true if the  dim should be fullscreen. */
        boolean dimFullscreen();
        /** Returns the display info. of the dim layer user. */
        DisplayInfo getDisplayInfo();
        /** Returns true if the dim layer user is currently attached to a display */
        boolean isAttachedToDisplay();
        /** Gets the bounds of the dim layer user. */
        void getDimBounds(Rect outBounds);
        /** Returns the layer to place a dim layer. */
        default int getLayerForDim(WindowStateAnimator animator, int layerOffset,
                int defaultLayer) {
            return defaultLayer;
        }

        String toShortString();
    }
    /** The user of this dim layer. */
    private final DimLayerUser mUser;

    private final String mName;

    DimLayer(WindowManagerService service, DimLayerUser user, int displayId, String name) {
        mUser = user;
        mDisplayId = displayId;
        mService = service;
        mName = name;
        if (DEBUG_DIM_LAYER) Slog.v(TAG, "Ctor: displayId=" + displayId);
    }

    private void constructSurface(WindowManagerService service) {
        service.openSurfaceTransaction();
        try {
            if (DEBUG_SURFACE_TRACE) {
                mDimSurface = new WindowSurfaceController.SurfaceTrace(service.mFxSession,
                    "DimSurface",
                    16, 16, PixelFormat.OPAQUE,
                    SurfaceControl.FX_SURFACE_DIM | SurfaceControl.HIDDEN);
            } else {
                mDimSurface = new SurfaceControl(service.mFxSession, mName,
                    16, 16, PixelFormat.OPAQUE,
                    SurfaceControl.FX_SURFACE_DIM | SurfaceControl.HIDDEN);
            }
            if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG,
                    "  DIM " + mDimSurface + ": CREATE");
            mDimSurface.setLayerStack(mDisplayId);
            adjustBounds();
            adjustAlpha(mAlpha);
            adjustLayer(mLayer);
        } catch (Exception e) {
            Slog.e(TAG_WM, "Exception creating Dim surface", e);
        } finally {
            service.closeSurfaceTransaction();
        }
    }

    /** Return true if dim layer is showing */
    boolean isDimming() {
        return mTargetAlpha != 0;
    }

    /** Return true if in a transition period */
    boolean isAnimating() {
        return mTargetAlpha != mAlpha;
    }

    float getTargetAlpha() {
        return mTargetAlpha;
    }

    void setLayer(int layer) {
        if (mLayer == layer) {
            return;
        }
        mLayer = layer;
        adjustLayer(layer);
    }

    private void adjustLayer(int layer) {
        if (mDimSurface != null) {
            mDimSurface.setLayer(layer);
        }
    }

    int getLayer() {
        return mLayer;
    }

    private void setAlpha(float alpha) {
        if (mAlpha == alpha) {
            return;
        }
        mAlpha = alpha;
        adjustAlpha(alpha);
    }

    private void adjustAlpha(float alpha) {
        if (DEBUG_DIM_LAYER) Slog.v(TAG, "setAlpha alpha=" + alpha);
        try {
            if (mDimSurface != null) {
                mDimSurface.setAlpha(alpha);
            }
            if (alpha == 0 && mShowing) {
                if (DEBUG_DIM_LAYER) Slog.v(TAG, "setAlpha hiding");
                if (mDimSurface != null) {
                    mDimSurface.hide();
                    mShowing = false;
                }
            } else if (alpha > 0 && !mShowing) {
                if (DEBUG_DIM_LAYER) Slog.v(TAG, "setAlpha showing");
                if (mDimSurface != null) {
                    mDimSurface.show();
                    mShowing = true;
                }
            }
        } catch (RuntimeException e) {
            Slog.w(TAG, "Failure setting alpha immediately", e);
        }
    }

    /**
     * NOTE: Must be called with Surface transaction open.
     */
    private void adjustBounds() {
        if (mUser.dimFullscreen()) {
            getBoundsForFullscreen(mBounds);
        }

        if (mDimSurface != null) {
            mDimSurface.setPosition(mBounds.left, mBounds.top);
            mDimSurface.setSize(mBounds.width(), mBounds.height());
            if (DEBUG_DIM_LAYER) Slog.v(TAG,
                    "adjustBounds user=" + mUser.toShortString() + " mBounds=" + mBounds);
        }

        mLastBounds.set(mBounds);
    }

    private void getBoundsForFullscreen(Rect outBounds) {
        final int dw, dh;
        final float xPos, yPos;
        // Set surface size to screen size.
        final DisplayInfo info = mUser.getDisplayInfo();
        // Multiply by 1.5 so that rotating a frozen surface that includes this does not expose
        // a corner.
        dw = (int) (info.logicalWidth * 1.5);
        dh = (int) (info.logicalHeight * 1.5);
        // back off position so 1/4 of Surface is before and 1/4 is after.
        xPos = -1 * dw / 6;
        yPos = -1 * dh / 6;
        outBounds.set((int) xPos, (int) yPos, (int) xPos + dw, (int) yPos + dh);
    }

    void setBoundsForFullscreen() {
        getBoundsForFullscreen(mBounds);
        setBounds(mBounds);
    }

    /** @param bounds The new bounds to set */
    void setBounds(Rect bounds) {
        mBounds.set(bounds);
        if (isDimming() && !mLastBounds.equals(bounds)) {
            try {
                mService.openSurfaceTransaction();
                adjustBounds();
            } catch (RuntimeException e) {
                Slog.w(TAG, "Failure setting size", e);
            } finally {
                mService.closeSurfaceTransaction();
            }
        }
    }

    /**
     * @param duration The time to test.
     * @return True if the duration would lead to an earlier end to the current animation.
     */
    private boolean durationEndsEarlier(long duration) {
        return SystemClock.uptimeMillis() + duration < mStartTime + mDuration;
    }

    /** Jump to the end of the animation.
     * NOTE: Must be called with Surface transaction open. */
    void show() {
        if (isAnimating()) {
            if (DEBUG_DIM_LAYER) Slog.v(TAG, "show: immediate");
            show(mLayer, mTargetAlpha, 0);
        }
    }

    /**
     * Begin an animation to a new dim value.
     * NOTE: Must be called with Surface transaction open.
     *
     * @param layer The layer to set the surface to.
     * @param alpha The dim value to end at.
     * @param duration How long to take to get there in milliseconds.
     */
    void show(int layer, float alpha, long duration) {
        if (DEBUG_DIM_LAYER) Slog.v(TAG, "show: layer=" + layer + " alpha=" + alpha
                + " duration=" + duration + ", mDestroyed=" + mDestroyed);
        if (mDestroyed) {
            Slog.e(TAG, "show: no Surface");
            // Make sure isAnimating() returns false.
            mTargetAlpha = mAlpha = 0;
            return;
        }

        if (mDimSurface == null) {
            constructSurface(mService);
        }

        if (!mLastBounds.equals(mBounds)) {
            adjustBounds();
        }
        setLayer(layer);

        long curTime = SystemClock.uptimeMillis();
        final boolean animating = isAnimating();
        if ((animating && (mTargetAlpha != alpha || durationEndsEarlier(duration)))
                || (!animating && mAlpha != alpha)) {
            if (duration <= 0) {
                // No animation required, just set values.
                setAlpha(alpha);
            } else {
                // Start or continue animation with new parameters.
                mStartAlpha = mAlpha;
                mStartTime = curTime;
                mDuration = duration;
            }
        }
        mTargetAlpha = alpha;
        if (DEBUG_DIM_LAYER) Slog.v(TAG, "show: mStartAlpha=" + mStartAlpha + " mStartTime="
                + mStartTime + " mTargetAlpha=" + mTargetAlpha);
    }

    /** Immediate hide.
     * NOTE: Must be called with Surface transaction open. */
    void hide() {
        if (mShowing) {
            if (DEBUG_DIM_LAYER) Slog.v(TAG, "hide: immediate");
            hide(0);
        }
    }

    /**
     * Gradually fade to transparent.
     * NOTE: Must be called with Surface transaction open.
     *
     * @param duration Time to fade in milliseconds.
     */
    void hide(long duration) {
        if (mShowing && (mTargetAlpha != 0 || durationEndsEarlier(duration))) {
            if (DEBUG_DIM_LAYER) Slog.v(TAG, "hide: duration=" + duration);
            show(mLayer, 0, duration);
        }
    }

    /**
     * Advance the dimming per the last #show(int, float, long) call.
     * NOTE: Must be called with Surface transaction open.
     *
     * @return True if animation is still required after this step.
     */
    boolean stepAnimation() {
        if (mDestroyed) {
            Slog.e(TAG, "stepAnimation: surface destroyed");
            // Ensure that isAnimating() returns false;
            mTargetAlpha = mAlpha = 0;
            return false;
        }
        if (isAnimating()) {
            final long curTime = SystemClock.uptimeMillis();
            final float alphaDelta = mTargetAlpha - mStartAlpha;
            float alpha = mStartAlpha + alphaDelta * (curTime - mStartTime) / mDuration;
            if (alphaDelta > 0 && alpha > mTargetAlpha ||
                    alphaDelta < 0 && alpha < mTargetAlpha) {
                // Don't exceed limits.
                alpha = mTargetAlpha;
            }
            if (DEBUG_DIM_LAYER) Slog.v(TAG, "stepAnimation: curTime=" + curTime + " alpha=" + alpha);
            setAlpha(alpha);
        }

        return isAnimating();
    }

    /** Cleanup */
    void destroySurface() {
        if (DEBUG_DIM_LAYER) Slog.v(TAG, "destroySurface.");
        if (mDimSurface != null) {
            mDimSurface.destroy();
            mDimSurface = null;
        }
        mDestroyed = true;
    }

    public void printTo(String prefix, PrintWriter pw) {
        pw.print(prefix); pw.print("mDimSurface="); pw.print(mDimSurface);
                pw.print(" mLayer="); pw.print(mLayer);
                pw.print(" mAlpha="); pw.println(mAlpha);
        pw.print(prefix); pw.print("mLastBounds="); pw.print(mLastBounds.toShortString());
                pw.print(" mBounds="); pw.println(mBounds.toShortString());
        pw.print(prefix); pw.print("Last animation: ");
                pw.print(" mDuration="); pw.print(mDuration);
                pw.print(" mStartTime="); pw.print(mStartTime);
                pw.print(" curTime="); pw.println(SystemClock.uptimeMillis());
        pw.print(prefix); pw.print(" mStartAlpha="); pw.print(mStartAlpha);
                pw.print(" mTargetAlpha="); pw.println(mTargetAlpha);
    }
}
