/*
 * Copyright (C) 2011 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_WM;

import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.Paint.FontMetricsInt;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
import android.view.Display;
import android.view.Surface.OutOfResourcesException;
import android.view.Surface;
import android.view.SurfaceControl;
import android.view.SurfaceSession;

/**
 * Displays a watermark on top of the window manager's windows.
 */
class Watermark {
    private final Display mDisplay;
    private final String[] mTokens;
    private final String mText;
    private final Paint mTextPaint;
    private final int mTextWidth;
    private final int mTextHeight;
    private final int mDeltaX;
    private final int mDeltaY;

    private final SurfaceControl mSurfaceControl;
    private final Surface mSurface = new Surface();
    private int mLastDW;
    private int mLastDH;
    private boolean mDrawNeeded;

    Watermark(DisplayContent dc, DisplayMetrics dm, String[] tokens) {
        if (false) {
            Log.i(TAG_WM, "*********************** WATERMARK");
            for (int i=0; i<tokens.length; i++) {
                Log.i(TAG_WM, "  TOKEN #" + i + ": " + tokens[i]);
            }
        }

        mDisplay = dc.getDisplay();
        mTokens = tokens;

        StringBuilder builder = new StringBuilder(32);
        int len = mTokens[0].length();
        len = len & ~1;
        for (int i=0; i<len; i+=2) {
            int c1 = mTokens[0].charAt(i);
            int c2 = mTokens[0].charAt(i+1);
            if (c1 >= 'a' && c1 <= 'f') c1 = c1 - 'a' + 10;
            else if (c1 >= 'A' && c1 <= 'F') c1 = c1 - 'A' + 10;
            else c1 -= '0';
            if (c2 >= 'a' && c2 <= 'f') c2 = c2 - 'a' + 10;
            else if (c2 >= 'A' && c2 <= 'F') c2 = c2 - 'A' + 10;
            else c2 -= '0';
            builder.append((char)(255-((c1*16)+c2)));
        }
        mText = builder.toString();
        if (false) {
            Log.i(TAG_WM, "Final text: " + mText);
        }

        int fontSize = WindowManagerService.getPropertyInt(tokens, 1,
                TypedValue.COMPLEX_UNIT_DIP, 20, dm);

        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mTextPaint.setTextSize(fontSize);
        mTextPaint.setTypeface(Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD));

        FontMetricsInt fm = mTextPaint.getFontMetricsInt();
        mTextWidth = (int)mTextPaint.measureText(mText);
        mTextHeight = fm.descent - fm.ascent;

        mDeltaX = WindowManagerService.getPropertyInt(tokens, 2,
                TypedValue.COMPLEX_UNIT_PX, mTextWidth*2, dm);
        mDeltaY = WindowManagerService.getPropertyInt(tokens, 3,
                TypedValue.COMPLEX_UNIT_PX, mTextHeight*3, dm);
        int shadowColor = WindowManagerService.getPropertyInt(tokens, 4,
                TypedValue.COMPLEX_UNIT_PX, 0xb0000000, dm);
        int color = WindowManagerService.getPropertyInt(tokens, 5,
                TypedValue.COMPLEX_UNIT_PX, 0x60ffffff, dm);
        int shadowRadius = WindowManagerService.getPropertyInt(tokens, 6,
                TypedValue.COMPLEX_UNIT_PX, 7, dm);
        int shadowDx = WindowManagerService.getPropertyInt(tokens, 8,
                TypedValue.COMPLEX_UNIT_PX, 0, dm);
        int shadowDy = WindowManagerService.getPropertyInt(tokens, 9,
                TypedValue.COMPLEX_UNIT_PX, 0, dm);

        mTextPaint.setColor(color);
        mTextPaint.setShadowLayer(shadowRadius, shadowDx, shadowDy, shadowColor);

        SurfaceControl ctrl = null;
        try {
            ctrl = dc.makeOverlay()
                    .setName("WatermarkSurface")
                    .setSize(1, 1)
                    .setFormat(PixelFormat.TRANSLUCENT)
                    .build();
            ctrl.setLayerStack(mDisplay.getLayerStack());
            ctrl.setLayer(WindowManagerService.TYPE_LAYER_MULTIPLIER*100);
            ctrl.setPosition(0, 0);
            ctrl.show();
            mSurface.copyFrom(ctrl);
        } catch (OutOfResourcesException e) {
        }
        mSurfaceControl = ctrl;
    }

    void positionSurface(int dw, int dh) {
        if (mLastDW != dw || mLastDH != dh) {
            mLastDW = dw;
            mLastDH = dh;
            mSurfaceControl.setSize(dw, dh);
            mDrawNeeded = true;
        }
    }

    void drawIfNeeded() {
        if (mDrawNeeded) {
            final int dw = mLastDW;
            final int dh = mLastDH;

            mDrawNeeded = false;
            Rect dirty = new Rect(0, 0, dw, dh);
            Canvas c = null;
            try {
                c = mSurface.lockCanvas(dirty);
            } catch (IllegalArgumentException e) {
            } catch (Surface.OutOfResourcesException e) {
            }
            if (c != null) {
                c.drawColor(0, PorterDuff.Mode.CLEAR);

                int deltaX = mDeltaX;
                int deltaY = mDeltaY;

                // deltaX shouldn't be close to a round fraction of our
                // x step, or else things will line up too much.
                int div = (dw+mTextWidth)/deltaX;
                int rem = (dw+mTextWidth) - (div*deltaX);
                int qdelta = deltaX/4;
                if (rem < qdelta || rem > (deltaX-qdelta)) {
                    deltaX += deltaX/3;
                }

                int y = -mTextHeight;
                int x = -mTextWidth;
                while (y < (dh+mTextHeight)) {
                    c.drawText(mText, x, y, mTextPaint);
                    x += deltaX;
                    if (x >= dw) {
                        x -= (dw+mTextWidth);
                        y += deltaY;
                    }
                }
                mSurface.unlockCanvasAndPost(c);
            }
        }
    }
}
