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

#include "SurfaceTextureRenderer.h"

#include <string.h>

#include <GLES2/gl2ext.h>
const GLfloat g_vVertices[] = {
    -1.f, -1.f, 0.0f, 1.0f,  // Position 0
    0.0f,  0.0f,         // TexCoord 0
     1.f, -1.f, 0.0f, 1.0f, // Position 1
    1.0f,  0.0f,         // TexCoord 1
    -1.f,  1.f, 0.0f, 1.0f, // Position 2
    0.0f,  1.0f,         // TexCoord 2
    1.f,   1.f, 0.0f, 1.0f, // Position 3
    1.0f,  1.0f          // TexCoord 3
};
GLushort g_iIndices2[] = { 0, 1, 2, 3 };

const int GL_TEXTURE_EXTERNAL_OES_ENUM = 0x8D65;

const int VERTEX_STRIDE = 6 * sizeof(GLfloat);

SurfaceTextureRenderer::SurfaceTextureRenderer() : Renderer() {
    memset(mSTMatrix, 0.0, 16*sizeof(float));
    mSTMatrix[0] = 1.0f;
    mSTMatrix[5] = 1.0f;
    mSTMatrix[10] = 1.0f;
    mSTMatrix[15] = 1.0f;
}

SurfaceTextureRenderer::~SurfaceTextureRenderer() {
}

void SurfaceTextureRenderer::SetViewportMatrix(int w, int h, int W, int H)
{
    for(int i=0; i<16; i++)
    {
        mViewportMatrix[i] = 0.0f;
    }

    mViewportMatrix[0] = float(w)/float(W);
    mViewportMatrix[5] = float(h)/float(H);
    mViewportMatrix[10] = 1.0f;
    mViewportMatrix[12] = -1.0f + float(w)/float(W);
    mViewportMatrix[13] = -1.0f + float(h)/float(H);
    mViewportMatrix[15] = 1.0f;
}

void SurfaceTextureRenderer::SetScalingMatrix(float xscale, float yscale)
{
    for(int i=0; i<16; i++)
    {
        mScalingMatrix[i] = 0.0f;
    }

    mScalingMatrix[0] = xscale;
    mScalingMatrix[5] = yscale;
    mScalingMatrix[10] = 1.0f;
    mScalingMatrix[15] = 1.0f;
}

void SurfaceTextureRenderer::SetSTMatrix(float *stmat)
{
    memcpy(mSTMatrix, stmat, 16*sizeof(float));
}


bool SurfaceTextureRenderer::InitializeGLProgram()
{
    bool succeeded = false;
    do {
        GLuint glProgram;
        glProgram = createProgram(VertexShaderSource(),
                FragmentShaderSource());
        if (!glProgram) {
            break;
        }

        glUseProgram(glProgram);
        if (!checkGlError("glUseProgram")) break;

        maPositionHandle = glGetAttribLocation(glProgram, "aPosition");
        checkGlError("glGetAttribLocation aPosition");
        maTextureHandle = glGetAttribLocation(glProgram, "aTextureCoord");
        checkGlError("glGetAttribLocation aTextureCoord");
        muSTMatrixHandle = glGetUniformLocation(glProgram, "uSTMatrix");
        checkGlError("glGetUniformLocation uSTMatrix");
        mScalingtransLoc = glGetUniformLocation(glProgram, "u_scalingtrans");

        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
        mGlProgram = glProgram;
        succeeded = true;
    } while (false);

    if (!succeeded && (mGlProgram != 0))
    {
        glDeleteProgram(mGlProgram);
        checkGlError("glDeleteProgram");
        mGlProgram = 0;
    }
    return succeeded;
}

bool SurfaceTextureRenderer::DrawTexture(GLfloat *affine)
{
    bool succeeded = false;
    do {
        bool rt = (mFrameBuffer == NULL)?
            SetupGraphics(mSurfaceWidth, mSurfaceHeight) :
            SetupGraphics(mFrameBuffer);

        if(!rt)
            break;

        glDisable(GL_BLEND);

        glActiveTexture(GL_TEXTURE0);
        if (!checkGlError("glActiveTexture")) break;

        const GLenum texture_type = InputTextureType();
        glBindTexture(texture_type, mInputTextureName);
        if (!checkGlError("glBindTexture")) break;

        glUniformMatrix4fv(mScalingtransLoc, 1, GL_FALSE, mScalingMatrix);
        glUniformMatrix4fv(muSTMatrixHandle, 1, GL_FALSE, mSTMatrix);

        // Load the vertex position
        glVertexAttribPointer(maPositionHandle, 4, GL_FLOAT,
                GL_FALSE, VERTEX_STRIDE, g_vVertices);
        glEnableVertexAttribArray(maPositionHandle);
        // Load the texture coordinate
        glVertexAttribPointer(maTextureHandle, 2, GL_FLOAT,
                GL_FALSE, VERTEX_STRIDE, &g_vVertices[4]);
        glEnableVertexAttribArray(maTextureHandle);

        // And, finally, execute the GL draw command.
        glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_SHORT, g_iIndices2);

        glBindFramebuffer(GL_FRAMEBUFFER, 0);
        succeeded = true;
    } while (false);
    return succeeded;
}

const char* SurfaceTextureRenderer::VertexShaderSource() const
{
    static const char gVertexShader[] =
        "uniform mat4 uSTMatrix;\n"
        "uniform mat4 u_scalingtrans;  \n"
        "attribute vec4 aPosition;\n"
        "attribute vec4 aTextureCoord;\n"
        "varying vec2 vTextureNormCoord;\n"
        "void main() {\n"
        "  gl_Position = u_scalingtrans * aPosition;\n"
        "  vTextureNormCoord = (uSTMatrix * aTextureCoord).xy;\n"
        "}\n";

    return gVertexShader;
}

const char* SurfaceTextureRenderer::FragmentShaderSource() const
{
    static const char gFragmentShader[] =
        "#extension GL_OES_EGL_image_external : require\n"
        "precision mediump float;\n"
        "varying vec2 vTextureNormCoord;\n"
        "uniform samplerExternalOES sTexture;\n"
        "void main() {\n"
        "  gl_FragColor = texture2D(sTexture, vTextureNormCoord);\n"
        "}\n";

    return gFragmentShader;
}
