/*
 * Copyright (C) 2012 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.camera;

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.opengl.Matrix;
import android.util.Log;

import com.android.gallery3d.common.ApiHelper;
import com.android.gallery3d.glrenderer.GLCanvas;
import com.android.gallery3d.glrenderer.RawTexture;
import com.android.gallery3d.ui.SurfaceTextureScreenNail;

/*
 * This is a ScreenNail which can display camera's preview.
 */
@TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
public class CameraScreenNail extends SurfaceTextureScreenNail {
    private static final String TAG = "CAM_ScreenNail";
    private static final int ANIM_NONE = 0;
    // Capture animation is about to start.
    private static final int ANIM_CAPTURE_START = 1;
    // Capture animation is running.
    private static final int ANIM_CAPTURE_RUNNING = 2;
    // Switch camera animation needs to copy texture.
    private static final int ANIM_SWITCH_COPY_TEXTURE = 3;
    // Switch camera animation shows the initial feedback by darkening the
    // preview.
    private static final int ANIM_SWITCH_DARK_PREVIEW = 4;
    // Switch camera animation is waiting for the first frame.
    private static final int ANIM_SWITCH_WAITING_FIRST_FRAME = 5;
    // Switch camera animation is about to start.
    private static final int ANIM_SWITCH_START = 6;
    // Switch camera animation is running.
    private static final int ANIM_SWITCH_RUNNING = 7;

    private boolean mVisible;
    // True if first onFrameAvailable has been called. If screen nail is drawn
    // too early, it will be all white.
    private boolean mFirstFrameArrived;
    private Listener mListener;
    private final float[] mTextureTransformMatrix = new float[16];

    // Animation.
    private CaptureAnimManager mCaptureAnimManager;
    private SwitchAnimManager mSwitchAnimManager = new SwitchAnimManager();
    private int mAnimState = ANIM_NONE;
    private RawTexture mAnimTexture;
    // Some methods are called by GL thread and some are called by main thread.
    // This protects mAnimState, mVisible, and surface texture. This also makes
    // sure some code are atomic. For example, requestRender and setting
    // mAnimState.
    private Object mLock = new Object();

    private OnFrameDrawnListener mOneTimeFrameDrawnListener;
    private int mRenderWidth;
    private int mRenderHeight;
    // This represents the scaled, uncropped size of the texture
    // Needed for FaceView
    private int mUncroppedRenderWidth;
    private int mUncroppedRenderHeight;
    private float mScaleX = 1f, mScaleY = 1f;
    private boolean mFullScreen;
    private boolean mEnableAspectRatioClamping = false;
    private boolean mAcquireTexture = false;
    private final DrawClient mDefaultDraw = new DrawClient() {
        @Override
        public void onDraw(GLCanvas canvas, int x, int y, int width, int height) {
            CameraScreenNail.super.draw(canvas, x, y, width, height);
        }

        @Override
        public boolean requiresSurfaceTexture() {
            return true;
        }

        @Override
        public RawTexture copyToTexture(GLCanvas c, RawTexture texture, int w, int h) {
            // We shouldn't be here since requireSurfaceTexture() returns true.
            return null;
        }
    };
    private DrawClient mDraw = mDefaultDraw;
    private float mAlpha = 1f;
    private Runnable mOnFrameDrawnListener;

    public interface Listener {
        void requestRender();
        // Preview has been copied to a texture.
        void onPreviewTextureCopied();

        void onCaptureTextureCopied();
    }

    public interface OnFrameDrawnListener {
        void onFrameDrawn(CameraScreenNail c);
    }

    public interface DrawClient {
        void onDraw(GLCanvas canvas, int x, int y, int width, int height);

        boolean requiresSurfaceTexture();
        // The client should implement this if requiresSurfaceTexture() is false;
        RawTexture copyToTexture(GLCanvas c, RawTexture texture, int width, int height);
    }

    public CameraScreenNail(Listener listener, Context ctx) {
        mListener = listener;
        mCaptureAnimManager = new CaptureAnimManager(ctx);
    }

    public void setFullScreen(boolean full) {
        synchronized (mLock) {
            mFullScreen = full;
        }
    }

    /**
     * returns the uncropped, but scaled, width of the rendered texture
     */
    public int getUncroppedRenderWidth() {
        return mUncroppedRenderWidth;
    }

    /**
     * returns the uncropped, but scaled, width of the rendered texture
     */
    public int getUncroppedRenderHeight() {
        return mUncroppedRenderHeight;
    }

    @Override
    public int getWidth() {
        return mEnableAspectRatioClamping ? mRenderWidth : getTextureWidth();
    }

    @Override
    public int getHeight() {
        return mEnableAspectRatioClamping ? mRenderHeight : getTextureHeight();
    }

    private int getTextureWidth() {
        return super.getWidth();
    }

    private int getTextureHeight() {
        return super.getHeight();
    }

    @Override
    public void setSize(int w, int h) {
        super.setSize(w,  h);
        mEnableAspectRatioClamping = false;
        if (mRenderWidth == 0) {
            mRenderWidth = w;
            mRenderHeight = h;
        }
        updateRenderSize();
    }

    /**
     * Tells the ScreenNail to override the default aspect ratio scaling
     * and instead perform custom scaling to basically do a centerCrop instead
     * of the default centerInside
     *
     * Note that calls to setSize will disable this
     */
    public void enableAspectRatioClamping() {
        mEnableAspectRatioClamping = true;
        updateRenderSize();
    }

    private void setPreviewLayoutSize(int w, int h) {
        Log.i(TAG, "preview layout size: "+w+"/"+h);
        mRenderWidth = w;
        mRenderHeight = h;
        updateRenderSize();
    }

    private void updateRenderSize() {
        if (!mEnableAspectRatioClamping) {
            mScaleX = mScaleY = 1f;
            mUncroppedRenderWidth = getTextureWidth();
            mUncroppedRenderHeight = getTextureHeight();
            Log.i(TAG, "aspect ratio clamping disabled");
            return;
        }

        float aspectRatio;
        if (getTextureWidth() > getTextureHeight()) {
            aspectRatio = (float) getTextureWidth() / (float) getTextureHeight();
        } else {
            aspectRatio = (float) getTextureHeight() / (float) getTextureWidth();
        }
        float scaledTextureWidth, scaledTextureHeight;
        if (mRenderWidth > mRenderHeight) {
            scaledTextureWidth = Math.max(mRenderWidth,
                    (int) (mRenderHeight * aspectRatio));
            scaledTextureHeight = Math.max(mRenderHeight,
                    (int)(mRenderWidth / aspectRatio));
        } else {
            scaledTextureWidth = Math.max(mRenderWidth,
                    (int) (mRenderHeight / aspectRatio));
            scaledTextureHeight = Math.max(mRenderHeight,
                    (int) (mRenderWidth * aspectRatio));
        }
        mScaleX = mRenderWidth / scaledTextureWidth;
        mScaleY = mRenderHeight / scaledTextureHeight;
        mUncroppedRenderWidth = Math.round(scaledTextureWidth);
        mUncroppedRenderHeight = Math.round(scaledTextureHeight);
        Log.i(TAG, "aspect ratio clamping enabled, surfaceTexture scale: " + mScaleX + ", " + mScaleY);
    }

    public void acquireSurfaceTexture() {
        synchronized (mLock) {
            mFirstFrameArrived = false;
            mAnimTexture = new RawTexture(getTextureWidth(), getTextureHeight(), true);
            mAcquireTexture = true;
        }
        mListener.requestRender();
    }

    @Override
    public void releaseSurfaceTexture() {
        synchronized (mLock) {
            if (mAcquireTexture) {
                mAcquireTexture = false;
                mLock.notifyAll();
            } else {
                if (super.getSurfaceTexture() != null) {
                    super.releaseSurfaceTexture();
                }
                mAnimState = ANIM_NONE; // stop the animation
            }
        }
    }

    public void copyTexture() {
        synchronized (mLock) {
            mListener.requestRender();
            mAnimState = ANIM_SWITCH_COPY_TEXTURE;
        }
    }

    public void animateSwitchCamera() {
        Log.v(TAG, "animateSwitchCamera");
        synchronized (mLock) {
            if (mAnimState == ANIM_SWITCH_DARK_PREVIEW) {
                // Do not request render here because camera has been just
                // started. We do not want to draw black frames.
                mAnimState = ANIM_SWITCH_WAITING_FIRST_FRAME;
            }
        }
    }

    public void animateCapture(int displayRotation) {
        synchronized (mLock) {
            mCaptureAnimManager.setOrientation(displayRotation);
            mCaptureAnimManager.animateFlashAndSlide();
            mListener.requestRender();
            mAnimState = ANIM_CAPTURE_START;
        }
    }

    public RawTexture getAnimationTexture() {
        return mAnimTexture;
    }

    public void animateFlash(int displayRotation) {
        synchronized (mLock) {
            mCaptureAnimManager.setOrientation(displayRotation);
            mCaptureAnimManager.animateFlash();
            mListener.requestRender();
            mAnimState = ANIM_CAPTURE_START;
        }
    }

    public void animateSlide() {
        synchronized (mLock) {
            mCaptureAnimManager.animateSlide();
            mListener.requestRender();
        }
    }

    private void callbackIfNeeded() {
        if (mOneTimeFrameDrawnListener != null) {
            mOneTimeFrameDrawnListener.onFrameDrawn(this);
            mOneTimeFrameDrawnListener = null;
        }
    }

    @Override
    protected void updateTransformMatrix(float[] matrix) {
        super.updateTransformMatrix(matrix);
        Matrix.translateM(matrix, 0, .5f, .5f, 0);
        Matrix.scaleM(matrix, 0, mScaleX, mScaleY, 1f);
        Matrix.translateM(matrix, 0, -.5f, -.5f, 0);
    }

    public void directDraw(GLCanvas canvas, int x, int y, int width, int height) {
        DrawClient draw;
        synchronized (mLock) {
            draw = mDraw;
        }
        draw.onDraw(canvas, x, y, width, height);
    }

    public void setDraw(DrawClient draw) {
        synchronized (mLock) {
            if (draw == null) {
                mDraw = mDefaultDraw;
            } else {
                mDraw = draw;
            }
        }
        mListener.requestRender();
    }

    @Override
    public void draw(GLCanvas canvas, int x, int y, int width, int height) {
        synchronized (mLock) {
            allocateTextureIfRequested(canvas);
            if (!mVisible) mVisible = true;
            SurfaceTexture surfaceTexture = getSurfaceTexture();
            if (mDraw.requiresSurfaceTexture() && (surfaceTexture == null || !mFirstFrameArrived)) {
                return;
            }
            if (mOnFrameDrawnListener != null) {
                mOnFrameDrawnListener.run();
                mOnFrameDrawnListener = null;
            }
            float oldAlpha = canvas.getAlpha();
            canvas.setAlpha(mAlpha);

            switch (mAnimState) {
                case ANIM_NONE:
                    directDraw(canvas, x, y, width, height);
                    break;
                case ANIM_SWITCH_COPY_TEXTURE:
                    copyPreviewTexture(canvas);
                    mSwitchAnimManager.setReviewDrawingSize(width, height);
                    mListener.onPreviewTextureCopied();
                    mAnimState = ANIM_SWITCH_DARK_PREVIEW;
                    // The texture is ready. Fall through to draw darkened
                    // preview.
                case ANIM_SWITCH_DARK_PREVIEW:
                case ANIM_SWITCH_WAITING_FIRST_FRAME:
                    // Consume the frame. If the buffers are full,
                    // onFrameAvailable will not be called. Animation state
                    // relies on onFrameAvailable.
                    surfaceTexture.updateTexImage();
                    mSwitchAnimManager.drawDarkPreview(canvas, x, y, width,
                            height, mAnimTexture);
                    break;
                case ANIM_SWITCH_START:
                    mSwitchAnimManager.startAnimation();
                    mAnimState = ANIM_SWITCH_RUNNING;
                    break;
                case ANIM_CAPTURE_START:
                    copyPreviewTexture(canvas);
                    mListener.onCaptureTextureCopied();
                    mCaptureAnimManager.startAnimation();
                    mAnimState = ANIM_CAPTURE_RUNNING;
                    break;
            }

            if (mAnimState == ANIM_CAPTURE_RUNNING || mAnimState == ANIM_SWITCH_RUNNING) {
                boolean drawn;
                if (mAnimState == ANIM_CAPTURE_RUNNING) {
                    if (!mFullScreen) {
                        // Skip the animation if no longer in full screen mode
                        drawn = false;
                    } else {
                        drawn = mCaptureAnimManager.drawAnimation(canvas, this, mAnimTexture,
                                x, y, width, height);
                    }
                } else {
                    drawn = mSwitchAnimManager.drawAnimation(canvas, x, y,
                            width, height, this, mAnimTexture);
                }
                if (drawn) {
                    mListener.requestRender();
                } else {
                    // Continue to the normal draw procedure if the animation is
                    // not drawn.
                    mAnimState = ANIM_NONE;
                    directDraw(canvas, x, y, width, height);
                }
            }
            canvas.setAlpha(oldAlpha);
            callbackIfNeeded();
        } // mLock
    }

    private void copyPreviewTexture(GLCanvas canvas) {
        if (!mDraw.requiresSurfaceTexture()) {
            mAnimTexture =  mDraw.copyToTexture(
                    canvas, mAnimTexture, getTextureWidth(), getTextureHeight());
        } else {
            int width = mAnimTexture.getWidth();
            int height = mAnimTexture.getHeight();
            canvas.beginRenderTarget(mAnimTexture);
            // Flip preview texture vertically. OpenGL uses bottom left point
            // as the origin (0, 0).
            canvas.translate(0, height);
            canvas.scale(1, -1, 1);
            getSurfaceTexture().getTransformMatrix(mTextureTransformMatrix);
            updateTransformMatrix(mTextureTransformMatrix);
            canvas.drawTexture(mExtTexture, mTextureTransformMatrix, 0, 0, width, height);
            canvas.endRenderTarget();
        }
    }

    @Override
    public void noDraw() {
        synchronized (mLock) {
            mVisible = false;
        }
    }

    @Override
    public void recycle() {
        synchronized (mLock) {
            mVisible = false;
        }
    }

    @Override
    public void onFrameAvailable(SurfaceTexture surfaceTexture) {
        synchronized (mLock) {
            if (getSurfaceTexture() != surfaceTexture) {
                return;
            }
            mFirstFrameArrived = true;
            if (mVisible) {
                if (mAnimState == ANIM_SWITCH_WAITING_FIRST_FRAME) {
                    mAnimState = ANIM_SWITCH_START;
                }
                // We need to ask for re-render if the SurfaceTexture receives a new
                // frame.
                mListener.requestRender();
            }
        }
    }

    // We need to keep track of the size of preview frame on the screen because
    // it's needed when we do switch-camera animation. See comments in
    // SwitchAnimManager.java. This is based on the natural orientation, not the
    // view system orientation.
    public void setPreviewFrameLayoutSize(int width, int height) {
        synchronized (mLock) {
            mSwitchAnimManager.setPreviewFrameLayoutSize(width, height);
            setPreviewLayoutSize(width, height);
        }
    }

    public void setOneTimeOnFrameDrawnListener(OnFrameDrawnListener l) {
        synchronized (mLock) {
            mFirstFrameArrived = false;
            mOneTimeFrameDrawnListener = l;
        }
    }

    @Override
    public SurfaceTexture getSurfaceTexture() {
        synchronized (mLock) {
            SurfaceTexture surfaceTexture = super.getSurfaceTexture();
            if (surfaceTexture == null && mAcquireTexture) {
                try {
                    mLock.wait();
                    surfaceTexture = super.getSurfaceTexture();
                } catch (InterruptedException e) {
                    Log.w(TAG, "unexpected interruption");
                }
            }
            return surfaceTexture;
        }
    }

    private void allocateTextureIfRequested(GLCanvas canvas) {
        synchronized (mLock) {
            if (mAcquireTexture) {
                super.acquireSurfaceTexture(canvas);
                mAcquireTexture = false;
                mLock.notifyAll();
            }
        }
    }

    public void setOnFrameDrawnOneShot(Runnable run) {
        synchronized (mLock) {
            mOnFrameDrawnListener = run;
        }
    }

    public float getAlpha() {
        synchronized (mLock) {
            return mAlpha;
        }
    }

    public void setAlpha(float alpha) {
        synchronized (mLock) {
            mAlpha = alpha;
            mListener.requestRender();
        }
    }
}
