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

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.SurfaceTexture;
import android.opengl.GLUtils;
import android.util.Log;

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;

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 FireflyRenderer {
    private static final String LOG_TAG = "NfcFireflyThread";

    static final int NUM_FIREFLIES = 200;

    static final float NEAR_CLIPPING_PLANE = 50f;
    static final float FAR_CLIPPING_PLANE = 100f;

    // All final variables below only need to be allocated once
    // and can be reused between subsequent Beams
    static final int[] sEglConfig = {
        EGL10.EGL_RED_SIZE, 8,
        EGL10.EGL_GREEN_SIZE, 8,
        EGL10.EGL_BLUE_SIZE, 8,
        EGL10.EGL_ALPHA_SIZE, 0,
        EGL10.EGL_DEPTH_SIZE, 0,
        EGL10.EGL_STENCIL_SIZE, 0,
        EGL10.EGL_NONE
    };

    // Vertices for drawing a 32x32 rect
    static final float mVertices[] = {
        0.0f,  0.0f, 0.0f,  // 0, Top Left
        0.0f,  32.0f, 0.0f, // 1, Bottom Left
        32.0f, 32.0f, 0.0f, // 2, Bottom Right
        32.0f, 0.0f, 0.0f,  // 3, Top Right
    };

    // Mapping coordinates for the texture
    static final float mTextCoords[] = {
        0.0f, 0.0f,
        1.0f, 0.0f,
        1.0f, 1.0f,
        0.0f, 1.0f
    };

    // Connecting order (draws a square)
    static final short[] mIndices = { 0, 1, 2, 0, 2, 3 };

    final Context mContext;

    // Buffer holding the vertices
    final FloatBuffer mVertexBuffer;

    // Buffer holding the indices
    final ShortBuffer mIndexBuffer;

    // Buffer holding the texture mapping coordinates
    final FloatBuffer mTextureBuffer;

    final Firefly[] mFireflies;

    FireflyRenderThread mFireflyRenderThread;

    // The surface to render the flies on, including width and height
    SurfaceTexture mSurface;
    int mDisplayWidth;
    int mDisplayHeight;

    public FireflyRenderer(Context context) {
        mContext = context;

        // First, build the vertex, texture and index buffers
        ByteBuffer vbb = ByteBuffer.allocateDirect(mVertices.length * 4); // Float => 4 bytes
        vbb.order(ByteOrder.nativeOrder());
        mVertexBuffer = vbb.asFloatBuffer();
        mVertexBuffer.put(mVertices);
        mVertexBuffer.position(0);

        ByteBuffer ibb = ByteBuffer.allocateDirect(mIndices.length * 2); // Short => 2 bytes
        ibb.order(ByteOrder.nativeOrder());
        mIndexBuffer = ibb.asShortBuffer();
        mIndexBuffer.put(mIndices);
        mIndexBuffer.position(0);

        ByteBuffer tbb = ByteBuffer.allocateDirect(mTextCoords.length * 4);
        tbb.order(ByteOrder.nativeOrder());
        mTextureBuffer = tbb.asFloatBuffer();
        mTextureBuffer.put(mTextCoords);
        mTextureBuffer.position(0);

        mFireflies = new Firefly[NUM_FIREFLIES];
        for (int i = 0; i < NUM_FIREFLIES; i++) {
            mFireflies[i] = new Firefly();
        }
    }

    /**
     * Starts rendering fireflies on the given surface.
     * Must be called from the UI-thread.
     */
    public void start(SurfaceTexture surface, int width, int height) {
        mSurface = surface;
        mDisplayWidth = width;
        mDisplayHeight = height;

        mFireflyRenderThread = new FireflyRenderThread();
        mFireflyRenderThread.start();
    }

    /**
     * Stops rendering fireflies.
     * Must be called from the UI-thread.
     */
    public void stop() {
        if (mFireflyRenderThread != null) {
            mFireflyRenderThread.finish();
            try {
                mFireflyRenderThread.join();
            } catch (InterruptedException e) {
                Log.e(LOG_TAG, "Couldn't wait for FireflyRenderThread.");
            }
            mFireflyRenderThread = null;
        }
    }

    private class FireflyRenderThread extends Thread {
        EGL10 mEgl;
        EGLDisplay mEglDisplay;
        EGLConfig mEglConfig;
        EGLContext mEglContext;
        EGLSurface mEglSurface;
        GL10 mGL;

        // Holding the handle to the texture
        int mTextureId;

        // Read/written by multiple threads
        volatile boolean mFinished;

        @Override
        public void run() {
            if (!initGL()) {
                Log.e(LOG_TAG, "Failed to initialize OpenGL.");
                return;
            }
            loadStarTexture();

            mGL.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

            mGL.glViewport(0, 0, mDisplayWidth, mDisplayHeight);

            // make adjustments for screen ratio
            mGL.glMatrixMode(GL10.GL_PROJECTION);
            mGL.glLoadIdentity();
            mGL.glFrustumf(-mDisplayWidth, mDisplayWidth, mDisplayHeight, -mDisplayHeight, NEAR_CLIPPING_PLANE, FAR_CLIPPING_PLANE);

            // Switch back to modelview
            mGL.glMatrixMode(GL10.GL_MODELVIEW);
            mGL.glLoadIdentity();

            mGL.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
            mGL.glDepthMask(true);


            for (Firefly firefly : mFireflies) {
                firefly.reset();
            }

            for (int i = 0; i < 3; i++) {
                // Call eglSwapBuffers 3 times - this will allocate the necessary
                // buffers, and make sure the animation looks smooth from the start.
                if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) {
                    Log.e(LOG_TAG, "Could not swap buffers");
                    mFinished = true;
                }
            }

            long startTime = System.currentTimeMillis();

            while (!mFinished) {
                long timeElapsedMs = System.currentTimeMillis() - startTime;
                startTime = System.currentTimeMillis();

                checkCurrent();

                mGL.glClear(GL10.GL_COLOR_BUFFER_BIT);
                mGL.glLoadIdentity();

                mGL.glEnable(GL10.GL_TEXTURE_2D);
                mGL.glEnable(GL10.GL_BLEND);
                mGL.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE);

                for (Firefly firefly : mFireflies) {
                    firefly.updatePositionAndScale(timeElapsedMs);
                    firefly.draw(mGL);
                }

                if (!mEgl.eglSwapBuffers(mEglDisplay, mEglSurface)) {
                    Log.e(LOG_TAG, "Could not swap buffers");
                    mFinished = true;
                }

                long elapsed = System.currentTimeMillis() - startTime;
                try {
                    Thread.sleep(Math.max(30 - elapsed, 0));
                } catch (InterruptedException e) {

                }
            }
            finishGL();
        }

        public void finish() {
            mFinished = true;
        }

        void loadStarTexture() {
            int[] textureIds = new int[1];
            mGL.glGenTextures(1, textureIds, 0);
            mTextureId = textureIds[0];

            InputStream in = null;
            try {
                // Remember that both texture dimensions must be a power of 2!
                in = mContext.getAssets().open("star.png");

                Bitmap bitmap = BitmapFactory.decodeStream(in);
                mGL.glBindTexture(GL10.GL_TEXTURE_2D, mTextureId);

                mGL.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
                mGL.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

                GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

                bitmap.recycle();

            } catch (IOException e) {
                Log.e(LOG_TAG, "IOException opening assets.");
            } finally {
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException e) { }
                }
            }
        }

        private void checkCurrent() {
            if (!mEglContext.equals(mEgl.eglGetCurrentContext()) ||
                    !mEglSurface.equals(mEgl.eglGetCurrentSurface(EGL10.EGL_DRAW))) {
                if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
                    throw new RuntimeException("eglMakeCurrent failed "
                            + GLUtils.getEGLErrorString(mEgl.eglGetError()));
                }
            }
        }

        boolean initGL() {
            // Initialize openGL engine
            mEgl = (EGL10) EGLContext.getEGL();

            mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
            if (mEglDisplay == EGL10.EGL_NO_DISPLAY) {
                Log.e(LOG_TAG, "eglGetDisplay failed " +
                        GLUtils.getEGLErrorString(mEgl.eglGetError()));
                return false;
            }

            int[] version = new int[2];
            if (!mEgl.eglInitialize(mEglDisplay, version)) {
                Log.e(LOG_TAG, "eglInitialize failed " +
                        GLUtils.getEGLErrorString(mEgl.eglGetError()));
                return false;
            }

            mEglConfig = chooseEglConfig();
            if (mEglConfig == null) {
                Log.e(LOG_TAG, "eglConfig not initialized.");
                return false;
            }

            mEglContext = mEgl.eglCreateContext(mEglDisplay, mEglConfig, EGL10.EGL_NO_CONTEXT, null);

            mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay, mEglConfig, mSurface, null);

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

            if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
                Log.e(LOG_TAG, "eglMakeCurrent failed " +
                        GLUtils.getEGLErrorString(mEgl.eglGetError()));
                return false;
            }

            mGL = (GL10) mEglContext.getGL();

            return true;
        }

        private void finishGL() {
            if (mEgl == null || mEglDisplay == null) {
                // Nothing to free
                return;
            }
            // Unbind the current surface and context from the display
            mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE,
                    EGL10.EGL_NO_CONTEXT);

            if (mEglSurface != null) {
                mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
            }

            if (mEglContext != null) {
                mEgl.eglDestroyContext(mEglDisplay, mEglContext);
            }
        }

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

    private class Firefly {
        static final float TEXTURE_HEIGHT = 30f; // TODO use measurement of texture size
        static final float SPEED = .5f;

        float mX; // between -mDisplayHeight and mDisplayHeight
        float mY; // between -mDisplayWidth and mDisplayWidth
        float mZ; // between 0.0 (near) and 1.0 (far)
        float mZ0;
        float mT;
        float mScale;
        float mAlpha;

        public Firefly() {
        }

        void reset() {
            mX = (float) (Math.random() * mDisplayWidth) * 4 - 2 * mDisplayWidth;
            mY = (float) (Math.random() * mDisplayHeight) * 4 - 2 * mDisplayHeight;
            mZ0 = mZ = (float) (Math.random()) * 2 - 1;
            mT = 0f;
            mScale = 1.5f;
            mAlpha = 0f;
        }

        public void updatePositionAndScale(long timeElapsedMs) {
               mT += timeElapsedMs;
               mZ = mZ0 + mT/1000f * SPEED;
               mAlpha = 1f-mZ;
               if(mZ > 1.0) reset();
        }

        public void draw(GL10 gl) {
            gl.glLoadIdentity();

            // Counter clockwise winding
            gl.glFrontFace(GL10.GL_CCW);

            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
            gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
            gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTextureBuffer);

            gl.glTranslatef(mX, mY, -NEAR_CLIPPING_PLANE-mZ*(FAR_CLIPPING_PLANE-NEAR_CLIPPING_PLANE));
            gl.glColor4f(1, 1, 1, mAlpha);

            // scale around center
            gl.glTranslatef(TEXTURE_HEIGHT/2, TEXTURE_HEIGHT/2, 0);
            gl.glScalef(mScale, mScale, 0);
            gl.glTranslatef(-TEXTURE_HEIGHT/2, -TEXTURE_HEIGHT/2, 0);

            gl.glDrawElements(GL10.GL_TRIANGLES, mIndices.length, GL10.GL_UNSIGNED_SHORT,
                    mIndexBuffer);

            gl.glColor4f(1, 1, 1, 1);
            gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
            gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        }
    }
}
