/*
 * 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;
        }
    }

    @Override
    public Canvas lockCanvas() {
        return internalLockCanvas(null, false);
    }

    @Override
    public Canvas lockCanvas(Rect dirty) {
        return internalLockCanvas(dirty, false);
    }

    @Override
    public Canvas lockHardwareCanvas() {
        return internalLockCanvas(null, true);
    }

    private final Canvas internalLockCanvas(Rect dirty, boolean hardware) {
        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 {
                if (hardware) {
                    c = mSurface.lockHardwareCanvas();
                } else {
                    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;
    }
};
