/*
 * Copyright (C) 2013 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.photos.views;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.SurfaceTexture;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLUtils;
import android.util.Log;
import android.view.TextureView;
import android.view.TextureView.SurfaceTextureListener;

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;


public class BlockingGLTextureView extends TextureView
        implements SurfaceTextureListener {

    private RenderThread mRenderThread;

    public BlockingGLTextureView(Context context) {
        super(context);
        setSurfaceTextureListener(this);
    }

    public void setRenderer(Renderer renderer) {
        if (mRenderThread != null) {
            throw new IllegalArgumentException("Renderer already set");
        }
        mRenderThread = new RenderThread(renderer);
    }

    public void render() {
        mRenderThread.render();
    }

    public void destroy() {
        if (mRenderThread != null) {
            mRenderThread.finish();
            mRenderThread = null;
        }
    }

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width,
            int height) {
        mRenderThread.setSurface(surface);
        mRenderThread.setSize(width, height);
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width,
            int height) {
        mRenderThread.setSize(width, height);
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        if (mRenderThread != null) {
            mRenderThread.setSurface(null);
        }
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
    }

    @Override
    protected void finalize() throws Throwable {
        try {
            destroy();
        } catch (Throwable t) {}
        super.finalize();
    }

    /**
     * An EGL helper class.
     */

    private static class EglHelper {
        private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
        private static final int EGL_OPENGL_ES2_BIT = 4;

        EGL10 mEgl;
        EGLDisplay mEglDisplay;
        EGLSurface mEglSurface;
        EGLConfig mEglConfig;
        EGLContext mEglContext;

        private EGLConfig chooseEglConfig() {
            int[] configsCount = new int[1];
            EGLConfig[] configs = new EGLConfig[1];
            int[] configSpec = getConfig();
            if (!mEgl.eglChooseConfig(mEglDisplay, configSpec, configs, 1, configsCount)) {
                throw new IllegalArgumentException("eglChooseConfig failed " +
                        GLUtils.getEGLErrorString(mEgl.eglGetError()));
            } else if (configsCount[0] > 0) {
                return configs[0];
            }
            return null;
        }

        private static int[] getConfig() {
            return 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_ALPHA_SIZE, 8,
                    EGL10.EGL_DEPTH_SIZE, 0,
                    EGL10.EGL_STENCIL_SIZE, 0,
                    EGL10.EGL_NONE
            };
        }

        EGLContext createContext(EGL10 egl, EGLDisplay eglDisplay, EGLConfig eglConfig) {
            int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE };
            return egl.eglCreateContext(eglDisplay, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
        }

        /**
         * Initialize EGL for a given configuration spec.
         */
        public void start() {
            /*
             * Get an EGL instance
             */
            mEgl = (EGL10) EGLContext.getEGL();

            /*
             * Get to the default display.
             */
            mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);

            if (mEglDisplay == EGL10.EGL_NO_DISPLAY) {
                throw new RuntimeException("eglGetDisplay failed");
            }

            /*
             * We can now initialize EGL for that display
             */
            int[] version = new int[2];
            if(!mEgl.eglInitialize(mEglDisplay, version)) {
                throw new RuntimeException("eglInitialize failed");
            }
            mEglConfig = chooseEglConfig();

            /*
            * Create an EGL context. We want to do this as rarely as we can, because an
            * EGL context is a somewhat heavy object.
            */
            mEglContext = createContext(mEgl, mEglDisplay, mEglConfig);

            if (mEglContext == null || mEglContext == EGL10.EGL_NO_CONTEXT) {
                mEglContext = null;
                throwEglException("createContext");
            }

            mEglSurface = null;
        }

        /**
         * Create an egl surface for the current SurfaceTexture surface. If a surface
         * already exists, destroy it before creating the new surface.
         *
         * @return true if the surface was created successfully.
         */
        public boolean createSurface(SurfaceTexture surface) {
            /*
             * Check preconditions.
             */
            if (mEgl == null) {
                throw new RuntimeException("egl not initialized");
            }
            if (mEglDisplay == null) {
                throw new RuntimeException("eglDisplay not initialized");
            }
            if (mEglConfig == null) {
                throw new RuntimeException("mEglConfig not initialized");
            }

            /*
             *  The window size has changed, so we need to create a new
             *  surface.
             */
            destroySurfaceImp();

            /*
             * Create an EGL surface we can render into.
             */
            if (surface != null) {
                mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, mEglConfig, surface, null);
            } else {
                mEglSurface = null;
            }

            if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) {
                int error = mEgl.eglGetError();
                if (error == EGL10.EGL_BAD_NATIVE_WINDOW) {
                    Log.e("EglHelper", "createWindowSurface returned EGL_BAD_NATIVE_WINDOW.");
                }
                return false;
            }

            /*
             * Before we can issue GL commands, we need to make sure
             * the context is current and bound to a surface.
             */
            if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
                /*
                 * Could not make the context current, probably because the underlying
                 * SurfaceView surface has been destroyed.
                 */
                logEglErrorAsWarning("EGLHelper", "eglMakeCurrent", mEgl.eglGetError());
                return false;
            }

            return true;
        }

        /**
         * Create a GL object for the current EGL context.
         */
        public GL10 createGL() {
            return (GL10) mEglContext.getGL();
        }

        /**
         * Display the current render surface.
         * @return the EGL error code from eglSwapBuffers.
         */
        public int swap() {
            if (! mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) {
                return mEgl.eglGetError();
            }
            return EGL10.EGL_SUCCESS;
        }

        public void destroySurface() {
            destroySurfaceImp();
        }

        private void destroySurfaceImp() {
            if (mEglSurface != null && mEglSurface != EGL10.EGL_NO_SURFACE) {
                mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE,
                        EGL10.EGL_NO_SURFACE,
                        EGL10.EGL_NO_CONTEXT);
                mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
                mEglSurface = null;
            }
        }

        public void finish() {
            if (mEglContext != null) {
                mEgl.eglDestroyContext(mEglDisplay, mEglContext);
                mEglContext = null;
            }
            if (mEglDisplay != null) {
                mEgl.eglTerminate(mEglDisplay);
                mEglDisplay = null;
            }
        }

        private void throwEglException(String function) {
            throwEglException(function, mEgl.eglGetError());
        }

        public static void throwEglException(String function, int error) {
            String message = formatEglError(function, error);
            throw new RuntimeException(message);
        }

        public static void logEglErrorAsWarning(String tag, String function, int error) {
            Log.w(tag, formatEglError(function, error));
        }

        public static String formatEglError(String function, int error) {
            return function + " failed: " + error;
        }

    }

    private static class RenderThread extends Thread {
        private static final int INVALID = -1;
        private static final int RENDER = 1;
        private static final int CHANGE_SURFACE = 2;
        private static final int RESIZE_SURFACE = 3;
        private static final int FINISH = 4;

        private EglHelper mEglHelper = new EglHelper();

        private Object mLock = new Object();
        private int mExecMsgId = INVALID;
        private SurfaceTexture mSurface;
        private Renderer mRenderer;
        private int mWidth, mHeight;

        private boolean mFinished = false;
        private GL10 mGL;

        public RenderThread(Renderer renderer) {
            super("RenderThread");
            mRenderer = renderer;
            start();
        }

        private void checkRenderer() {
            if (mRenderer == null) {
                throw new IllegalArgumentException("Renderer is null!");
            }
        }

        private void checkSurface() {
            if (mSurface == null) {
                throw new IllegalArgumentException("surface is null!");
            }
        }

        public void setSurface(SurfaceTexture surface) {
            // If the surface is null we're being torn down, don't need a
            // renderer then
            if (surface != null) {
                checkRenderer();
            }
            mSurface = surface;
            exec(CHANGE_SURFACE);
        }

        public void setSize(int width, int height) {
            checkRenderer();
            checkSurface();
            mWidth = width;
            mHeight = height;
            exec(RESIZE_SURFACE);
        }

        public void render() {
            checkRenderer();
            if (mSurface != null) {
                exec(RENDER);
                mSurface.updateTexImage();
            }
        }

        public void finish() {
            mSurface = null;
            exec(FINISH);
            try {
                join();
            } catch (InterruptedException e) {}
        }

        private void exec(int msgid) {
            synchronized (mLock) {
                if (mExecMsgId != INVALID) {
                    throw new IllegalArgumentException("Message already set - multithreaded access?");
                }
                mExecMsgId = msgid;
                mLock.notify();
                try {
                    mLock.wait();
                } catch (InterruptedException e) {}
            }
        }

        private void handleMessageLocked(int what) {
            switch (what) {
            case CHANGE_SURFACE:
                if (mEglHelper.createSurface(mSurface)) {
                    mGL = mEglHelper.createGL();
                    mRenderer.onSurfaceCreated(mGL, mEglHelper.mEglConfig);
                }
                break;
            case RESIZE_SURFACE:
                mRenderer.onSurfaceChanged(mGL, mWidth, mHeight);
                break;
            case RENDER:
                mRenderer.onDrawFrame(mGL);
                mEglHelper.swap();
                break;
            case FINISH:
                mEglHelper.destroySurface();
                mEglHelper.finish();
                mFinished = true;
                break;
            }
        }

        @Override
        public void run() {
            synchronized (mLock) {
                mEglHelper.start();
                while (!mFinished) {
                    while (mExecMsgId == INVALID) {
                        try {
                            mLock.wait();
                        } catch (InterruptedException e) {}
                    }
                    handleMessageLocked(mExecMsgId);
                    mExecMsgId = INVALID;
                    mLock.notify();
                }
            }
        }
    }
}
