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

import android.graphics.Canvas;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.SystemClock;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;

import java.util.ArrayList;
import java.util.concurrent.locks.ReentrantLock;

public abstract class BaseSurfaceHolder implements SurfaceHolder {
    private static final String TAG = "BaseSurfaceHolder";
    static final boolean DEBUG = false;

    public final ArrayList<SurfaceHolder.Callback> mCallbacks
            = new ArrayList<SurfaceHolder.Callback>();
    SurfaceHolder.Callback[] mGottenCallbacks;
    boolean mHaveGottenCallbacks;
    
    public final ReentrantLock mSurfaceLock = new ReentrantLock();
    public Surface mSurface = new Surface();

    int mRequestedWidth = -1;
    int mRequestedHeight = -1;
    /** @hide */
    protected int mRequestedFormat = PixelFormat.OPAQUE;
    int mRequestedType = -1;

    long mLastLockTime = 0;
    
    int mType = -1;
    final Rect mSurfaceFrame = new Rect();
    Rect mTmpDirty;
    
    public abstract void onUpdateSurface();
    public abstract void onRelayoutContainer();
    public abstract boolean onAllowLockCanvas();
    
    public int getRequestedWidth() {
        return mRequestedWidth;
    }
    
    public int getRequestedHeight() {
        return mRequestedHeight;
    }
    
    public int getRequestedFormat() {
        return mRequestedFormat;
    }
    
    public int getRequestedType() {
        return mRequestedType;
    }
    
    public void addCallback(Callback callback) {
        synchronized (mCallbacks) {
            // This is a linear search, but in practice we'll 
            // have only a couple callbacks, so it doesn't matter.
            if (mCallbacks.contains(callback) == false) {      
                mCallbacks.add(callback);
            }
        }
    }

    public void removeCallback(Callback callback) {
        synchronized (mCallbacks) {
            mCallbacks.remove(callback);
        }
    }
    
    public SurfaceHolder.Callback[] getCallbacks() {
        if (mHaveGottenCallbacks) {
            return mGottenCallbacks;
        }
        
        synchronized (mCallbacks) {
            final int N = mCallbacks.size();
            if (N > 0) {
                if (mGottenCallbacks == null || mGottenCallbacks.length != N) {
                    mGottenCallbacks = new SurfaceHolder.Callback[N];
                }
                mCallbacks.toArray(mGottenCallbacks);
            } else {
                mGottenCallbacks = null;
            }
            mHaveGottenCallbacks = true;
        }
        
        return mGottenCallbacks;
    }
    
    public void ungetCallbacks() {
        mHaveGottenCallbacks = false;
    }
    
    public void setFixedSize(int width, int height) {
        if (mRequestedWidth != width || mRequestedHeight != height) {
            mRequestedWidth = width;
            mRequestedHeight = height;
            onRelayoutContainer();
        }
    }

    public void setSizeFromLayout() {
        if (mRequestedWidth != -1 || mRequestedHeight != -1) {
            mRequestedWidth = mRequestedHeight = -1;
            onRelayoutContainer();
        }
    }

    public void setFormat(int format) {
        if (mRequestedFormat != format) {
            mRequestedFormat = format;
            onUpdateSurface();
        }
    }

    public void setType(int type) {
        switch (type) {
        case SURFACE_TYPE_HARDWARE:
        case SURFACE_TYPE_GPU:
            // these are deprecated, treat as "NORMAL"
            type = SURFACE_TYPE_NORMAL;
            break;
        }
        switch (type) {
        case SURFACE_TYPE_NORMAL:
        case SURFACE_TYPE_PUSH_BUFFERS:
            if (mRequestedType != type) {
                mRequestedType = type;
                onUpdateSurface();
            }
            break;
        }
    }

    public Canvas lockCanvas() {
        return internalLockCanvas(null);
    }

    public Canvas lockCanvas(Rect dirty) {
        return internalLockCanvas(dirty);
    }

    private final Canvas internalLockCanvas(Rect dirty) {
        if (mType == SURFACE_TYPE_PUSH_BUFFERS) {
            throw new BadSurfaceTypeException(
                    "Surface type is SURFACE_TYPE_PUSH_BUFFERS");
        }
        mSurfaceLock.lock();

        if (DEBUG) Log.i(TAG, "Locking canvas..,");

        Canvas c = null;
        if (onAllowLockCanvas()) {
            if (dirty == null) {
                if (mTmpDirty == null) {
                    mTmpDirty = new Rect();
                }
                mTmpDirty.set(mSurfaceFrame);
                dirty = mTmpDirty;
            }

            try {
                c = mSurface.lockCanvas(dirty);
            } catch (Exception e) {
                Log.e(TAG, "Exception locking surface", e);
            }
        }

        if (DEBUG) Log.i(TAG, "Returned canvas: " + c);
        if (c != null) {
            mLastLockTime = SystemClock.uptimeMillis();
            return c;
        }
        
        // If the Surface is not ready to be drawn, then return null,
        // but throttle calls to this function so it isn't called more
        // than every 100ms.
        long now = SystemClock.uptimeMillis();
        long nextTime = mLastLockTime + 100;
        if (nextTime > now) {
            try {
                Thread.sleep(nextTime-now);
            } catch (InterruptedException e) {
            }
            now = SystemClock.uptimeMillis();
        }
        mLastLockTime = now;
        mSurfaceLock.unlock();
        
        return null;
    }

    public void unlockCanvasAndPost(Canvas canvas) {
        mSurface.unlockCanvasAndPost(canvas);
        mSurfaceLock.unlock();
    }

    public Surface getSurface() {
        return mSurface;
    }

    public Rect getSurfaceFrame() {
        return mSurfaceFrame;
    }

    public void setSurfaceFrameSize(int width, int height) {
        mSurfaceFrame.top = 0;
        mSurfaceFrame.left = 0;
        mSurfaceFrame.right = width;
        mSurfaceFrame.bottom = height;
    }
};
