/*
 * 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.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.util.Slog;
import android.view.Display;
import android.view.Surface;
import android.view.Surface.OutOfResourcesException;
import android.view.SurfaceControl;

import java.util.function.Supplier;

class CircularDisplayMask {
    private static final String TAG = TAG_WITH_CLASS_NAME ? "CircularDisplayMask" : TAG_WM;

    // size of the chin
    private int mScreenOffset = 0;
    // Display dimensions
    private Point mScreenSize;

    private final SurfaceControl mSurfaceControl;
    private final Surface mSurface;
    private int mLastDW;
    private int mLastDH;
    private boolean mDrawNeeded;
    private Paint mPaint;
    private int mRotation;
    private boolean mVisible;
    private boolean mDimensionsUnequal = false;
    private int mMaskThickness;

    CircularDisplayMask(Supplier<Surface> surfaceFactory, DisplayContent dc, int zOrder,
            int screenOffset, int maskThickness, SurfaceControl.Transaction t) {
        final Display display = dc.getDisplay();
        mSurface = surfaceFactory.get();
        mScreenSize = new Point();
        display.getSize(mScreenSize);
        if (mScreenSize.x != mScreenSize.y + screenOffset) {
            Slog.w(TAG, "Screen dimensions of displayId = " + display.getDisplayId() +
                    "are not equal, circularMask will not be drawn.");
            mDimensionsUnequal = true;
        }

        SurfaceControl ctrl = null;
        try {
            ctrl = dc.makeOverlay()
                    .setName("CircularDisplayMask")
                    .setBufferSize(mScreenSize.x, mScreenSize.y) // not a typo
                    .setFormat(PixelFormat.TRANSLUCENT)
                    .build();

            t.setLayerStack(ctrl, display.getLayerStack());
            t.setLayer(ctrl, zOrder);
            t.setPosition(ctrl, 0, 0);
            t.show(ctrl);
            mSurface.copyFrom(ctrl);
        } catch (OutOfResourcesException e) {
        }
        mSurfaceControl = ctrl;
        mDrawNeeded = true;
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
        mScreenOffset = screenOffset;
        mMaskThickness = maskThickness;
    }

    private void drawIfNeeded(SurfaceControl.Transaction t) {
        if (!mDrawNeeded || !mVisible || mDimensionsUnequal) {
            return;
        }
        mDrawNeeded = false;

        Rect dirty = new Rect(0, 0, mScreenSize.x, mScreenSize.y);
        Canvas c = null;
        try {
            c = mSurface.lockCanvas(dirty);
        } catch (IllegalArgumentException e) {
        } catch (Surface.OutOfResourcesException e) {
        }
        if (c == null) {
            return;
        }
        switch (mRotation) {
            case Surface.ROTATION_0:
            case Surface.ROTATION_90:
                // chin bottom or right
                t.setPosition(mSurfaceControl, 0, 0);
                break;
            case Surface.ROTATION_180:
                // chin top
                t.setPosition(mSurfaceControl, 0, -mScreenOffset);
                break;
            case Surface.ROTATION_270:
                // chin left
                t.setPosition(mSurfaceControl, -mScreenOffset, 0);
                break;
        }

        int circleRadius = mScreenSize.x / 2;
        c.drawColor(Color.BLACK);

        // The radius is reduced by mMaskThickness to provide an anti aliasing effect on the
        // display edges.
        c.drawCircle(circleRadius, circleRadius, circleRadius - mMaskThickness, mPaint);
        mSurface.unlockCanvasAndPost(c);
    }

    // Note: caller responsible for being inside
    // Surface.openTransaction() / closeTransaction()
    public void setVisibility(boolean on, SurfaceControl.Transaction t) {
        if (mSurfaceControl == null) {
            return;
        }
        mVisible = on;
        drawIfNeeded(t);
        if (on) {
            t.show(mSurfaceControl);
        } else {
            t.hide(mSurfaceControl);
        }
    }

    void positionSurface(int dw, int dh, int rotation, SurfaceControl.Transaction t) {
        if (mLastDW == dw && mLastDH == dh && mRotation == rotation) {
            return;
        }
        mLastDW = dw;
        mLastDH = dh;
        mDrawNeeded = true;
        mRotation = rotation;
        drawIfNeeded(t);
    }

}
