/*
 * 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.camera;

import android.annotation.TargetApi;
import android.graphics.SurfaceTexture;
import android.os.ConditionVariable;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

import com.android.gallery3d.common.ApiHelper;

import javax.microedition.khronos.egl.EGL10;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.egl.EGLContext;
import javax.microedition.khronos.egl.EGLDisplay;
import javax.microedition.khronos.egl.EGLSurface;
import javax.microedition.khronos.opengles.GL10;

@TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB) // uses SurfaceTexture
public class MosaicPreviewRenderer {
    private static final String TAG = "MosaicPreviewRenderer";
    private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
    private static final boolean DEBUG = false;

    private int mWidth; // width of the view in UI
    private int mHeight; // height of the view in UI

    private boolean mIsLandscape = true;
    private final float[] mTransformMatrix = new float[16];

    private ConditionVariable mEglThreadBlockVar = new ConditionVariable();
    private HandlerThread mEglThread;
    private EGLHandler mEglHandler;

    private EGLConfig mEglConfig;
    private EGLDisplay mEglDisplay;
    private EGLContext mEglContext;
    private EGLSurface mEglSurface;
    private SurfaceTexture mMosaicOutputSurfaceTexture;
    private SurfaceTexture mInputSurfaceTexture;
    private EGL10 mEgl;
    private GL10 mGl;

    private class EGLHandler extends Handler {
        public static final int MSG_INIT_EGL_SYNC = 0;
        public static final int MSG_SHOW_PREVIEW_FRAME_SYNC = 1;
        public static final int MSG_SHOW_PREVIEW_FRAME = 2;
        public static final int MSG_ALIGN_FRAME_SYNC = 3;
        public static final int MSG_RELEASE = 4;

        public EGLHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_INIT_EGL_SYNC:
                    doInitGL();
                    mEglThreadBlockVar.open();
                    break;
                case MSG_SHOW_PREVIEW_FRAME_SYNC:
                    doShowPreviewFrame();
                    mEglThreadBlockVar.open();
                    break;
                case MSG_SHOW_PREVIEW_FRAME:
                    doShowPreviewFrame();
                    break;
                case MSG_ALIGN_FRAME_SYNC:
                    doAlignFrame();
                    mEglThreadBlockVar.open();
                    break;
                case MSG_RELEASE:
                    doRelease();
                    mEglThreadBlockVar.open();
                    break;
            }
        }

        private void doAlignFrame() {
            mInputSurfaceTexture.updateTexImage();
            mInputSurfaceTexture.getTransformMatrix(mTransformMatrix);

            MosaicRenderer.setWarping(true);
            // Call preprocess to render it to low-res and high-res RGB textures.
            MosaicRenderer.preprocess(mTransformMatrix);
            // Now, transfer the textures from GPU to CPU memory for processing
            MosaicRenderer.transferGPUtoCPU();
            MosaicRenderer.updateMatrix();
            draw();
            mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);
        }

        private void doShowPreviewFrame() {
            mInputSurfaceTexture.updateTexImage();
            mInputSurfaceTexture.getTransformMatrix(mTransformMatrix);

            MosaicRenderer.setWarping(false);
            // Call preprocess to render it to low-res and high-res RGB textures.
            MosaicRenderer.preprocess(mTransformMatrix);
            MosaicRenderer.updateMatrix();
            draw();
            mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);
        }

        private void doInitGL() {
            // These are copied from GLSurfaceView
            mEgl = (EGL10) EGLContext.getEGL();
            mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
            if (mEglDisplay == EGL10.EGL_NO_DISPLAY) {
                throw new RuntimeException("eglGetDisplay failed");
            }
            int[] version = new int[2];
            if (!mEgl.eglInitialize(mEglDisplay, version)) {
                throw new RuntimeException("eglInitialize failed");
            } else {
                Log.v(TAG, "EGL version: " + version[0] + '.' + version[1]);
            }
            int[] attribList = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
            mEglConfig = chooseConfig(mEgl, mEglDisplay);
            mEglContext = mEgl.eglCreateContext(mEglDisplay, mEglConfig, EGL10.EGL_NO_CONTEXT,
                                                attribList);

            if (mEglContext == null || mEglContext == EGL10.EGL_NO_CONTEXT) {
                throw new RuntimeException("failed to createContext");
            }
            mEglSurface = mEgl.eglCreateWindowSurface(
                    mEglDisplay, mEglConfig, mMosaicOutputSurfaceTexture, null);
            if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) {
                throw new RuntimeException("failed to createWindowSurface");
            }

            if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
                throw new RuntimeException("failed to eglMakeCurrent");
            }

            mGl = (GL10) mEglContext.getGL();

            mInputSurfaceTexture = new SurfaceTexture(MosaicRenderer.init());
            MosaicRenderer.reset(mWidth, mHeight, mIsLandscape);
        }

        private void doRelease() {
            mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
            mEgl.eglDestroyContext(mEglDisplay, mEglContext);
            mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE,
                    EGL10.EGL_NO_CONTEXT);
            mEgl.eglTerminate(mEglDisplay);
            mEglSurface = null;
            mEglContext = null;
            mEglDisplay = null;
            releaseSurfaceTexture(mInputSurfaceTexture);
            mEglThread.quit();
        }

        @TargetApi(ApiHelper.VERSION_CODES.ICE_CREAM_SANDWICH)
        private void releaseSurfaceTexture(SurfaceTexture st) {
            if (ApiHelper.HAS_RELEASE_SURFACE_TEXTURE) {
                st.release();
            }
        }

        // Should be called from other thread.
        public void sendMessageSync(int msg) {
            mEglThreadBlockVar.close();
            sendEmptyMessage(msg);
            mEglThreadBlockVar.block();
        }

    }

    public MosaicPreviewRenderer(SurfaceTexture tex, int w, int h, boolean isLandscape) {
        mMosaicOutputSurfaceTexture = tex;
        mWidth = w;
        mHeight = h;
        mIsLandscape = isLandscape;

        mEglThread = new HandlerThread("PanoramaRealtimeRenderer");
        mEglThread.start();
        mEglHandler = new EGLHandler(mEglThread.getLooper());

        // We need to sync this because the generation of surface texture for input is
        // done here and the client will continue with the assumption that the
        // generation is completed.
        mEglHandler.sendMessageSync(EGLHandler.MSG_INIT_EGL_SYNC);
    }

    public void release() {
        mEglHandler.sendMessageSync(EGLHandler.MSG_RELEASE);
    }

    public void showPreviewFrameSync() {
        mEglHandler.sendMessageSync(EGLHandler.MSG_SHOW_PREVIEW_FRAME_SYNC);
    }

    public void showPreviewFrame() {
        mEglHandler.sendEmptyMessage(EGLHandler.MSG_SHOW_PREVIEW_FRAME);
    }

    public void alignFrameSync() {
        mEglHandler.sendMessageSync(EGLHandler.MSG_ALIGN_FRAME_SYNC);
    }

    public SurfaceTexture getInputSurfaceTexture() {
        return mInputSurfaceTexture;
    }

    private void draw() {
        MosaicRenderer.step();
    }

    private static void checkEglError(String prompt, EGL10 egl) {
        int error;
        while ((error = egl.eglGetError()) != EGL10.EGL_SUCCESS) {
            Log.e(TAG, String.format("%s: EGL error: 0x%x", prompt, error));
        }
    }

    private static final int EGL_OPENGL_ES2_BIT = 4;
    private static final int[] CONFIG_SPEC = new int[] {
            EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
            EGL10.EGL_RED_SIZE, 8,
            EGL10.EGL_GREEN_SIZE, 8,
            EGL10.EGL_BLUE_SIZE, 8,
            EGL10.EGL_NONE
    };

    private static EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) {
        int[] numConfig = new int[1];
        if (!egl.eglChooseConfig(display, CONFIG_SPEC, null, 0, numConfig)) {
            throw new IllegalArgumentException("eglChooseConfig failed");
        }

        int numConfigs = numConfig[0];
        if (numConfigs <= 0) {
            throw new IllegalArgumentException("No configs match configSpec");
        }

        EGLConfig[] configs = new EGLConfig[numConfigs];
        if (!egl.eglChooseConfig(
                display, CONFIG_SPEC, configs, numConfigs, numConfig)) {
            throw new IllegalArgumentException("eglChooseConfig#2 failed");
        }

        return configs[0];
    }
}
