/*
 * Copyright (C) 2007 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 android.view;

import android.content.res.CompatibilityInfo.Translator;
import android.graphics.*;
import android.os.Parcelable;
import android.os.Parcel;
import android.util.DisplayMetrics;
import android.util.Log;

/**
 * Handle on to a raw buffer that is being managed by the screen compositor.
 */
public class Surface implements Parcelable {
    private static final String LOG_TAG = "Surface";
    private static final boolean DEBUG_RELEASE = false;
    
    /* flags used in constructor (keep in sync with ISurfaceComposer.h) */

    /** Surface is created hidden */
    public static final int HIDDEN              = 0x00000004;

    /** The surface is to be used by hardware accelerators or DMA engines 
     * @deprecated this is ignored, this value is set automatically when needed.
     */
    @Deprecated
    public static final int HARDWARE            = 0x00000010;

    /** Implies "HARDWARE", the surface is to be used by the GPU
     * additionally the backbuffer is never preserved for these
     * surfaces. 
     * @deprecated this is ignored, this value is set automatically when needed.
     */
    @Deprecated
    public static final int GPU                 = 0x00000028;

    /** The surface contains secure content, special measures will
     * be taken to disallow the surface's content to be copied from
     * another process. In particular, screenshots and VNC servers will
     * be disabled, but other measures can take place, for instance the
     * surface might not be hardware accelerated. */
    public static final int SECURE              = 0x00000080;
    
    /** Creates a surface where color components are interpreted as 
     *  "non pre-multiplied" by their alpha channel. Of course this flag is
     *  meaningless for surfaces without an alpha channel. By default
     *  surfaces are pre-multiplied, which means that each color component is
     *  already multiplied by its alpha value. In this case the blending
     *  equation used is:
     *  
     *    DEST = SRC + DEST * (1-SRC_ALPHA)
     *    
     *  By contrast, non pre-multiplied surfaces use the following equation:
     *  
     *    DEST = SRC * SRC_ALPHA * DEST * (1-SRC_ALPHA)
     *    
     *  pre-multiplied surfaces must always be used if transparent pixels are
     *  composited on top of each-other into the surface. A pre-multiplied
     *  surface can never lower the value of the alpha component of a given
     *  pixel.
     *  
     *  In some rare situations, a non pre-multiplied surface is preferable.
     *  
     */
    public static final int NON_PREMULTIPLIED   = 0x00000100;
    
    /**
     * Creates a surface without a rendering buffer. Instead, the content
     * of the surface must be pushed by an external entity. This is type
     * of surface can be used for efficient camera preview or movie
     * play back.
     */
    public static final int PUSH_BUFFERS        = 0x00000200;
    /**
     * Indicates that the surface must be considered opaque, even if its
     * pixel format is set to translucent. This can be useful if an
     * application needs full RGBA 8888 support for instance but will
     * still draw every pixel opaque.
     * 
     * @hide
     */
    public static final int OPAQUE              = 0x00000400;
    
    /** Creates a normal surface. This is the default */
    public static final int FX_SURFACE_NORMAL   = 0x00000000;
    
    /** Creates a Blur surface. Everything behind this surface is blurred
     * by some amount. The quality and refresh speed of the blur effect
     * is not settable or guaranteed.
     * It is an error to lock a Blur surface, since it doesn't have
     * a backing store.
     */
    public static final int FX_SURFACE_BLUR     = 0x00010000;
    
    /** Creates a Dim surface. Everything behind this surface is dimmed
     * by the amount specified in setAlpha(). 
     * It is an error to lock a Dim surface, since it doesn't have
     * a backing store.
     */
    public static final int FX_SURFACE_DIM     = 0x00020000;

    /** Mask used for FX values above */
    public static final int FX_SURFACE_MASK     = 0x000F0000;

    /* flags used with setFlags() (keep in sync with ISurfaceComposer.h) */
    
    /** Hide the surface. Equivalent to calling hide() */
    public static final int SURFACE_HIDDEN    = 0x01;
    
    /** Freeze the surface. Equivalent to calling freeze() */ 
    public static final int SURFACE_FROZEN     = 0x02;

    /**
     * @deprecated use {@link #SURFACE_FROZEN} instead.
     */
    @Deprecated
    public static final int SURACE_FROZEN     = 0x02;

    /** Enable dithering when compositing this surface */
    public static final int SURFACE_DITHER    = 0x04;

    public static final int SURFACE_BLUR_FREEZE= 0x10;

    /* orientations for setOrientation() */
    public static final int ROTATION_0       = 0;
    public static final int ROTATION_90      = 1;
    public static final int ROTATION_180     = 2;
    public static final int ROTATION_270     = 3;
    
    /** 
     * Disable the orientation animation 
     * {@hide} 
     */
    public static final int FLAGS_ORIENTATION_ANIMATION_DISABLE = 0x000000001;

    @SuppressWarnings("unused")
    private int mSurfaceControl;
    @SuppressWarnings("unused")
    private int mSaveCount;
    @SuppressWarnings("unused")
    private Canvas mCanvas;
    @SuppressWarnings("unused")
    private int mNativeSurface;
    private String mName;

    // The display metrics used to provide the pseudo canvas size for applications
    // running in compatibility mode. This is set to null for non compatibility mode.
    private DisplayMetrics mCompatibleDisplayMetrics;

    // A matrix to scale the matrix set by application. This is set to null for
    // non compatibility mode.
    private Matrix mCompatibleMatrix;

    @SuppressWarnings("unused")
    private Exception mCreationStack;

    /**
     * Exception thrown when a surface couldn't be created or resized
     */
    public static class OutOfResourcesException extends Exception {
        public OutOfResourcesException() {
        }
        public OutOfResourcesException(String name) {
            super(name);
        }
    }

    /*
     * We use a class initializer to allow the native code to cache some
     * field offsets.
     */
    native private static void nativeClassInit();
    static { nativeClassInit(); }

    
    /**
     * create a surface
     * {@hide}
     */
    public Surface(SurfaceSession s,
            int pid, int display, int w, int h, int format, int flags)
        throws OutOfResourcesException {
        if (DEBUG_RELEASE) {
            mCreationStack = new Exception();
        }
        mCanvas = new CompatibleCanvas();
        init(s,pid,null,display,w,h,format,flags);
    }

    /**
     * create a surface with a name
     * {@hide}
     */
    public Surface(SurfaceSession s,
            int pid, String name, int display, int w, int h, int format, int flags)
        throws OutOfResourcesException {
        if (DEBUG_RELEASE) {
            mCreationStack = new Exception();
        }
        mCanvas = new CompatibleCanvas();
        init(s,pid,name,display,w,h,format,flags);
        mName = name;
    }

    /**
     * Create an empty surface, which will later be filled in by
     * readFromParcel().
     * {@hide}
     */
    public Surface() {
        if (DEBUG_RELEASE) {
            mCreationStack = new Exception();
        }
        mCanvas = new CompatibleCanvas();
    }

    /**
     * A Canvas class that can handle the compatibility mode. This does two things differently.
     * <ul>
     *  <li> Returns the width and height of the target metrics, rather than native.
     *  For example, the canvas returns 320x480 even if an app is running in WVGA high density.
     *  <li> Scales the matrix in setMatrix by the application scale, except if the matrix looks
     *  like obtained from getMatrix. This is a hack to handle the case that an application
     *  uses getMatrix to keep the original matrix, set matrix of its own, then set the original
     *  matrix back. There is no perfect solution that works for all cases, and there are a lot of
     *  cases that this model dose not work, but we hope this works for many apps.
     * </ul>
     */
    private class CompatibleCanvas extends Canvas {
        // A temp matrix to remember what an application obtained via {@link getMatrix}
        private Matrix mOrigMatrix = null;

        @Override
        public int getWidth() {
            return mCompatibleDisplayMetrics == null ?
                    super.getWidth() : mCompatibleDisplayMetrics.widthPixels;
        }

        @Override
        public int getHeight() {
            return mCompatibleDisplayMetrics == null ?
                    super.getHeight() : mCompatibleDisplayMetrics.heightPixels;
        }

        @Override
        public void setMatrix(Matrix matrix) {
            if (mCompatibleMatrix == null || mOrigMatrix == null || mOrigMatrix.equals(matrix)) {
                // don't scale the matrix if it's not compatibility mode, or
                // the matrix was obtained from getMatrix.
                super.setMatrix(matrix);
            } else {
                Matrix m = new Matrix(mCompatibleMatrix);
                m.preConcat(matrix);
                super.setMatrix(m);
            }
        }

        @Override
        public void getMatrix(Matrix m) {
            super.getMatrix(m);
            if (mOrigMatrix == null) {
                mOrigMatrix = new Matrix(); 
            }
            mOrigMatrix.set(m);
        }
    }

    /**
     * Sets the display metrics used to provide canva's width/height in compatibility mode.
     */
    void setCompatibleDisplayMetrics(DisplayMetrics metrics, Translator translator) {
        mCompatibleDisplayMetrics = metrics;
        if (translator != null) {
            float appScale = translator.applicationScale;
            mCompatibleMatrix = new Matrix();
            mCompatibleMatrix.setScale(appScale, appScale);
        }
    }
    
    /**
     * Copy another surface to this one.  This surface now holds a reference
     * to the same data as the original surface, and is -not- the owner.
     * {@hide}
     */
    public native   void copyFrom(Surface o);
    
    /**
     * Does this object hold a valid surface?  Returns true if it holds
     * a physical surface, so lockCanvas() will succeed.  Otherwise
     * returns false.
     */
    public native   boolean isValid();
    
    /** Free all server-side state associated with this surface and
     * release this object's reference. {@hide} */
    public native void destroy();
    
    /** Release the local reference to the server-side surface. @hide */
    public native void release();
    
    /** draw into a surface */
    public Canvas lockCanvas(Rect dirty) throws OutOfResourcesException, IllegalArgumentException
    {
        /* the dirty rectangle may be expanded to the surface's size, if
         * for instance it has been resized or if the bits were lost, since
         * the last call.
         */
        return lockCanvasNative(dirty);
    }

    private native Canvas lockCanvasNative(Rect dirty);

    /** unlock the surface and asks a page flip */
    public native   void unlockCanvasAndPost(Canvas canvas);

    /** 
     * unlock the surface. the screen won't be updated until
     * post() or postAll() is called
     */
    public native   void unlockCanvas(Canvas canvas);
    
    /** start/end a transaction {@hide} */
    public static native   void openTransaction();
    /** {@hide} */
    public static native   void closeTransaction();

    /**
     * Freezes the specified display, No updating of the screen will occur
     * until unfreezeDisplay() is called. Everything else works as usual though,
     * in particular transactions.
     * @param display
     * {@hide}
     */
    public static native   void freezeDisplay(int display);

    /**
     * resume updating the specified display.
     * @param display
     * {@hide}
     */
    public static native   void unfreezeDisplay(int display);

    /**
     * set the orientation of the given display.
     * @param display
     * @param orientation
     * @param flags
     * {@hide}
     */
    public static native   void setOrientation(int display, int orientation, int flags);

    /**
     * set the orientation of the given display.
     * @param display
     * @param orientation
     */
    public static void setOrientation(int display, int orientation) {
        setOrientation(display, orientation, 0);
    }
    
    /**
     * Copy the current screen contents into a bitmap and return it.
     *
     * @param width The desired width of the returned bitmap; the raw
     * screen will be scaled down to this size.
     * @param height The desired height of the returned bitmap; the raw
     * screen will be scaled down to this size.
     * @return Returns a Bitmap containing the screen contents.
     *
     * @hide
     */
    public static native Bitmap screenshot(int width, int height);

    /**
     * set surface parameters.
     * needs to be inside open/closeTransaction block
     */
    public native   void setLayer(int zorder);
    public native   void setPosition(int x, int y);
    public native   void setSize(int w, int h);

    public native   void hide();
    public native   void show();
    public native   void setTransparentRegionHint(Region region);
    public native   void setAlpha(float alpha);
    public native   void setMatrix(float dsdx, float dtdx,
                                   float dsdy, float dtdy);

    public native   void freeze();
    public native   void unfreeze();

    public native   void setFreezeTint(int tint);

    public native   void setFlags(int flags, int mask);

    @Override
    public String toString() {
        return "Surface(name=" + mName + ", identity=" + getIdentity() + ")";
    }

    private Surface(Parcel source) throws OutOfResourcesException {
        init(source);
    }
    
    public int describeContents() {
        return 0;
    }

    public native   void readFromParcel(Parcel source);
    public native   void writeToParcel(Parcel dest, int flags);
    
    public static final Parcelable.Creator<Surface> CREATOR
            = new Parcelable.Creator<Surface>()
    {
        public Surface createFromParcel(Parcel source) {
            try {
                return new Surface(source);
            } catch (Exception e) {
                Log.e(LOG_TAG, "Exception creating surface from parcel", e);
            }
            return null;
        }

        public Surface[] newArray(int size) {
            return new Surface[size];
        }
    };

    /* no user serviceable parts here ... */
    @Override
    protected void finalize() throws Throwable {
        try {
            super.finalize();
        } finally {
            if (mNativeSurface != 0 || mSurfaceControl != 0) {
                if (DEBUG_RELEASE) {
                    Log.w(LOG_TAG, "Surface.finalize() has work. You should have called release() (" 
                            + mNativeSurface + ", " + mSurfaceControl + ")", mCreationStack);
                } else {
                    Log.w(LOG_TAG, "Surface.finalize() has work. You should have called release() (" 
                            + mNativeSurface + ", " + mSurfaceControl + ")");
                }
            }
            release();            
        }
    }
    
    private native void init(SurfaceSession s,
            int pid, String name, int display, int w, int h, int format, int flags)
            throws OutOfResourcesException;

    private native void init(Parcel source);

    private native int getIdentity();
}
