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

#include <EGL/egl.h>
#include <GLES2/gl2.h>

#include "shader.h"
#include "JNIHelper.h"

namespace ndk_helper
{

#define DEBUG (1)

bool shader::CompileShader( GLuint *shader,
        const GLenum type,
        const char *str_file_name,
        const std::map<std::string, std::string>& map_parameters )
{
    std::vector<uint8_t> data;
    if( !JNIHelper::GetInstance()->ReadFile( str_file_name, &data ) )
    {
        LOGI( "Can not open a file:%s", str_file_name );
        return false;
    }

    const char REPLACEMENT_TAG = '*';
    //Fill-in parameters
    std::string str( data.begin(), data.end() );
    std::string str_replacement_map( data.size(), ' ' );

    std::map<std::string, std::string>::const_iterator it = map_parameters.begin();
    std::map<std::string, std::string>::const_iterator itEnd = map_parameters.end();
    while( it != itEnd )
    {
        size_t pos = 0;
        while( (pos = str.find( it->first, pos )) != std::string::npos )
        {
            //Check if the sub string is already touched

            size_t replaced_pos = str_replacement_map.find( REPLACEMENT_TAG, pos );
            if( replaced_pos == std::string::npos || replaced_pos > pos )
            {

                str.replace( pos, it->first.length(), it->second );
                str_replacement_map.replace( pos, it->first.length(), it->first.length(),
                        REPLACEMENT_TAG );
                pos += it->second.length();
            }
            else
            {
                //The replacement target has been touched by other tag, skipping them
                pos += it->second.length();
            }
        }
        it++;
    }

    LOGI( "Patched Shdader:\n%s", str.c_str() );

    std::vector<uint8_t> v( str.begin(), str.end() );
    str.clear();
    return shader::CompileShader( shader, type, v );
}

bool shader::CompileShader( GLuint *shader,
        const GLenum type,
        const GLchar *source,
        const int32_t iSize )
{
    if( source == NULL || iSize <= 0 )
        return false;

    *shader = glCreateShader( type );
    glShaderSource( *shader, 1, &source, &iSize ); //Not specifying 3rd parameter (size) could be troublesome..

    glCompileShader( *shader );

#if defined(DEBUG)
    GLint logLength;
    glGetShaderiv( *shader, GL_INFO_LOG_LENGTH, &logLength );
    if( logLength > 0 )
    {
        GLchar *log = (GLchar *) malloc( logLength );
        glGetShaderInfoLog( *shader, logLength, &logLength, log );
        LOGI( "Shader compile log:\n%s", log );
        free( log );
    }
#endif

    GLint status;
    glGetShaderiv( *shader, GL_COMPILE_STATUS, &status );
    if( status == 0 )
    {
        glDeleteShader( *shader );
        return false;
    }

    return true;
}

bool shader::CompileShader( GLuint *shader,
        const GLenum type,
        std::vector<uint8_t>& data )
{
    if( !data.size() )
        return false;

    const GLchar *source = (GLchar *) &data[0];
    int32_t iSize = data.size();
    return shader::CompileShader( shader, type, source, iSize );
}

bool shader::CompileShader( GLuint *shader,
        const GLenum type,
        const char *strFileName )
{
    std::vector<uint8_t> data;
    bool b = JNIHelper::GetInstance()->ReadFile( strFileName, &data );
    if( !b )
    {
        LOGI( "Can not open a file:%s", strFileName );
        return false;
    }

    return shader::CompileShader( shader, type, data );
}

bool shader::LinkProgram( const GLuint prog )
{
    GLint status;

    glLinkProgram( prog );

#if defined(DEBUG)
    GLint logLength;
    glGetProgramiv( prog, GL_INFO_LOG_LENGTH, &logLength );
    if( logLength > 0 )
    {
        GLchar *log = (GLchar *) malloc( logLength );
        glGetProgramInfoLog( prog, logLength, &logLength, log );
        LOGI( "Program link log:\n%s", log );
        free( log );
    }
#endif

    glGetProgramiv( prog, GL_LINK_STATUS, &status );
    if( status == 0 )
    {
        LOGI( "Program link failed\n" );
        return false;
    }

    return true;
}

bool shader::ValidateProgram( const GLuint prog )
{
    GLint logLength, status;

    glValidateProgram( prog );
    glGetProgramiv( prog, GL_INFO_LOG_LENGTH, &logLength );
    if( logLength > 0 )
    {
        GLchar *log = (GLchar *) malloc( logLength );
        glGetProgramInfoLog( prog, logLength, &logLength, log );
        LOGI( "Program validate log:\n%s", log );
        free( log );
    }

    glGetProgramiv( prog, GL_VALIDATE_STATUS, &status );
    if( status == 0 )
        return false;

    return true;
}

} //namespace ndkHelper

