#include "precompiled.h"
//
// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// Program.cpp: Implements the gl::Program class. Implements GL program objects
// and related functionality. [OpenGL ES 2.0.24] section 2.10.3 page 28.

#include "libGLESv2/Program.h"
#include "libGLESv2/ProgramBinary.h"
#include "libGLESv2/ResourceManager.h"

namespace gl
{
const char * const g_fakepath = "C:\\fakepath";

AttributeBindings::AttributeBindings()
{
}

AttributeBindings::~AttributeBindings()
{
}

InfoLog::InfoLog() : mInfoLog(NULL)
{
}

InfoLog::~InfoLog()
{
    delete[] mInfoLog;
}


int InfoLog::getLength() const
{
    if (!mInfoLog)
    {
        return 0;
    }
    else
    {
       return strlen(mInfoLog) + 1;
    }
}

void InfoLog::getLog(GLsizei bufSize, GLsizei *length, char *infoLog)
{
    int index = 0;

    if (bufSize > 0)
    {
        if (mInfoLog)
        {
            index = std::min(bufSize - 1, (int)strlen(mInfoLog));
            memcpy(infoLog, mInfoLog, index);
        }

        infoLog[index] = '\0';
    }

    if (length)
    {
        *length = index;
    }
}

// append a santized message to the program info log.
// The D3D compiler includes a fake file path in some of the warning or error 
// messages, so lets remove all occurrences of this fake file path from the log.
void InfoLog::appendSanitized(const char *message)
{
    std::string msg(message);

    size_t found;
    do
    {
        found = msg.find(g_fakepath);
        if (found != std::string::npos)
        {
            msg.erase(found, strlen(g_fakepath));
        }
    }
    while (found != std::string::npos);

    append("%s", msg.c_str());
}

void InfoLog::append(const char *format, ...)
{
    if (!format)
    {
        return;
    }

    va_list vararg;
    va_start(vararg, format);
    size_t infoLength = vsnprintf(NULL, 0, format, vararg);
    va_end(vararg);

    char *logPointer = NULL;

    if (!mInfoLog)
    {
        mInfoLog = new char[infoLength + 2];
        logPointer = mInfoLog;
    }
    else
    {
        size_t currentlogLength = strlen(mInfoLog);
        char *newLog = new char[currentlogLength + infoLength + 2];
        strcpy(newLog, mInfoLog);

        delete[] mInfoLog;
        mInfoLog = newLog;

        logPointer = mInfoLog + currentlogLength;
    }

    va_start(vararg, format);
    vsnprintf(logPointer, infoLength, format, vararg);
    va_end(vararg);

    logPointer[infoLength] = 0;
    strcpy(logPointer + infoLength, "\n");
}

void InfoLog::reset()
{
    if (mInfoLog)
    {
        delete [] mInfoLog;
        mInfoLog = NULL;
    }
}

Program::Program(rx::Renderer *renderer, ResourceManager *manager, GLuint handle) : mResourceManager(manager), mHandle(handle)
{
    mFragmentShader = NULL;
    mVertexShader = NULL;
    mProgramBinary.set(NULL);
    mDeleteStatus = false;
    mLinked = false;
    mRefCount = 0;
    mRenderer = renderer;

    resetUniformBlockBindings();
}

Program::~Program()
{
    unlink(true);

    if (mVertexShader != NULL)
    {
        mVertexShader->release();
    }

    if (mFragmentShader != NULL)
    {
        mFragmentShader->release();
    }
}

bool Program::attachShader(Shader *shader)
{
    if (shader->getType() == GL_VERTEX_SHADER)
    {
        if (mVertexShader)
        {
            return false;
        }

        mVertexShader = (VertexShader*)shader;
        mVertexShader->addRef();
    }
    else if (shader->getType() == GL_FRAGMENT_SHADER)
    {
        if (mFragmentShader)
        {
            return false;
        }

        mFragmentShader = (FragmentShader*)shader;
        mFragmentShader->addRef();
    }
    else UNREACHABLE();

    return true;
}

bool Program::detachShader(Shader *shader)
{
    if (shader->getType() == GL_VERTEX_SHADER)
    {
        if (mVertexShader != shader)
        {
            return false;
        }

        mVertexShader->release();
        mVertexShader = NULL;
    }
    else if (shader->getType() == GL_FRAGMENT_SHADER)
    {
        if (mFragmentShader != shader)
        {
            return false;
        }

        mFragmentShader->release();
        mFragmentShader = NULL;
    }
    else UNREACHABLE();

    return true;
}

int Program::getAttachedShadersCount() const
{
    return (mVertexShader ? 1 : 0) + (mFragmentShader ? 1 : 0);
}

void AttributeBindings::bindAttributeLocation(GLuint index, const char *name)
{
    if (index < MAX_VERTEX_ATTRIBS)
    {
        for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++)
        {
            mAttributeBinding[i].erase(name);
        }

        mAttributeBinding[index].insert(name);
    }
}

void Program::bindAttributeLocation(GLuint index, const char *name)
{
    mAttributeBindings.bindAttributeLocation(index, name);
}

// Links the HLSL code of the vertex and pixel shader by matching up their varyings,
// compiling them into binaries, determining the attribute mappings, and collecting
// a list of uniforms
bool Program::link()
{
    unlink(false);

    mInfoLog.reset();
    resetUniformBlockBindings();

    mProgramBinary.set(new ProgramBinary(mRenderer));
    mLinked = mProgramBinary->link(mInfoLog, mAttributeBindings, mFragmentShader, mVertexShader,
                                   mTransformFeedbackVaryings, mTransformFeedbackBufferMode);

    return mLinked;
}

int AttributeBindings::getAttributeBinding(const std::string &name) const
{
    for (int location = 0; location < MAX_VERTEX_ATTRIBS; location++)
    {
        if (mAttributeBinding[location].find(name) != mAttributeBinding[location].end())
        {
            return location;
        }
    }

    return -1;
}

// Returns the program object to an unlinked state, before re-linking, or at destruction
void Program::unlink(bool destroy)
{
    if (destroy)   // Object being destructed
    {
        if (mFragmentShader)
        {
            mFragmentShader->release();
            mFragmentShader = NULL;
        }

        if (mVertexShader)
        {
            mVertexShader->release();
            mVertexShader = NULL;
        }
    }

    mProgramBinary.set(NULL);
    mLinked = false;
}

bool Program::isLinked()
{
    return mLinked;
}

ProgramBinary* Program::getProgramBinary() const
{
    return mProgramBinary.get();
}

bool Program::setProgramBinary(const void *binary, GLsizei length)
{
    unlink(false);

    mInfoLog.reset();

    mProgramBinary.set(new ProgramBinary(mRenderer));
    mLinked = mProgramBinary->load(mInfoLog, binary, length);
    if (!mLinked)
    {
        mProgramBinary.set(NULL);
    }

    return mLinked;
}

void Program::release()
{
    mRefCount--;

    if (mRefCount == 0 && mDeleteStatus)
    {
        mResourceManager->deleteProgram(mHandle);
    }
}

void Program::addRef()
{
    mRefCount++;
}

unsigned int Program::getRefCount() const
{
    return mRefCount;
}

GLint Program::getProgramBinaryLength() const
{
    ProgramBinary *programBinary = mProgramBinary.get();
    if (programBinary)
    {
        return programBinary->getLength();
    }
    else
    {
        return 0;
    }
}

int Program::getInfoLogLength() const
{
    return mInfoLog.getLength();
}

void Program::getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog)
{
    return mInfoLog.getLog(bufSize, length, infoLog);
}

void Program::getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders)
{
    int total = 0;

    if (mVertexShader)
    {
        if (total < maxCount)
        {
            shaders[total] = mVertexShader->getHandle();
        }

        total++;
    }

    if (mFragmentShader)
    {
        if (total < maxCount)
        {
            shaders[total] = mFragmentShader->getHandle();
        }

        total++;
    }

    if (count)
    {
        *count = total;
    }
}

void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
{
    ProgramBinary *programBinary = getProgramBinary();
    if (programBinary)
    {
        programBinary->getActiveAttribute(index, bufsize, length, size, type, name);
    }
    else
    {
        if (bufsize > 0)
        {
            name[0] = '\0';
        }
        
        if (length)
        {
            *length = 0;
        }

        *type = GL_NONE;
        *size = 1;
    }
}

GLint Program::getActiveAttributeCount()
{
    ProgramBinary *programBinary = getProgramBinary();
    if (programBinary)
    {
        return programBinary->getActiveAttributeCount();
    }
    else
    {
        return 0;
    }
}

GLint Program::getActiveAttributeMaxLength()
{
    ProgramBinary *programBinary = getProgramBinary();
    if (programBinary)
    {
        return programBinary->getActiveAttributeMaxLength();
    }
    else
    {
        return 0;
    }
}

void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
{
    ProgramBinary *programBinary = getProgramBinary();
    if (programBinary)
    {
        return programBinary->getActiveUniform(index, bufsize, length, size, type, name);
    }
    else
    {
        if (bufsize > 0)
        {
            name[0] = '\0';
        }

        if (length)
        {
            *length = 0;
        }

        *size = 0;
        *type = GL_NONE;
    }
}

GLint Program::getActiveUniformCount()
{
    ProgramBinary *programBinary = getProgramBinary();
    if (programBinary)
    {
        return programBinary->getActiveUniformCount();
    }
    else
    {
        return 0;
    }
}

GLint Program::getActiveUniformMaxLength()
{
    ProgramBinary *programBinary = getProgramBinary();
    if (programBinary)
    {
        return programBinary->getActiveUniformMaxLength();
    }
    else
    {
        return 0;
    }
}

void Program::flagForDeletion()
{
    mDeleteStatus = true;
}

bool Program::isFlaggedForDeletion() const
{
    return mDeleteStatus;
}

void Program::validate()
{
    mInfoLog.reset();

    ProgramBinary *programBinary = getProgramBinary();
    if (isLinked() && programBinary)
    {
        programBinary->validate(mInfoLog);
    }
    else
    {
        mInfoLog.append("Program has not been successfully linked.");
    }
}

bool Program::isValidated() const
{
    ProgramBinary *programBinary = mProgramBinary.get();
    if (programBinary)
    {
        return programBinary->isValidated();
    }
    else
    {
        return false;
    }
}

GLint Program::getActiveUniformBlockCount()
{
    ProgramBinary *programBinary = getProgramBinary();
    if (programBinary)
    {
        return static_cast<GLint>(programBinary->getActiveUniformBlockCount());
    }
    else
    {
        return 0;
    }
}

GLint Program::getActiveUniformBlockMaxLength()
{
    ProgramBinary *programBinary = getProgramBinary();
    if (programBinary)
    {
        return static_cast<GLint>(programBinary->getActiveUniformBlockMaxLength());
    }
    else
    {
        return 0;
    }
}

void Program::bindUniformBlock(GLuint uniformBlockIndex, GLuint uniformBlockBinding)
{
    mUniformBlockBindings[uniformBlockIndex] = uniformBlockBinding;
}

GLuint Program::getUniformBlockBinding(GLuint uniformBlockIndex) const
{
    return mUniformBlockBindings[uniformBlockIndex];
}

void Program::resetUniformBlockBindings()
{
    for (unsigned int blockId = 0; blockId < IMPLEMENTATION_MAX_COMBINED_SHADER_UNIFORM_BUFFERS; blockId++)
    {
        mUniformBlockBindings[blockId] = 0;
    }
}

void Program::setTransformFeedbackVaryings(GLsizei count, const GLchar *const *varyings, GLenum bufferMode)
{
    mTransformFeedbackVaryings.resize(count);
    for (GLsizei i = 0; i < count; i++)
    {
        mTransformFeedbackVaryings[i] = varyings[i];
    }

    mTransformFeedbackBufferMode = bufferMode;
}

void Program::getTransformFeedbackVarying(GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name) const
{
    ProgramBinary *programBinary = getProgramBinary();
    if (programBinary && index < programBinary->getTransformFeedbackVaryingCount())
    {
        const LinkedVarying &varying = programBinary->getTransformFeedbackVarying(index);
        GLsizei lastNameIdx = std::min(bufSize - 1, static_cast<GLsizei>(varying.name.length()));
        if (length)
        {
            *length = lastNameIdx;
        }
        if (size)
        {
            *size = varying.size;
        }
        if (type)
        {
            *type = varying.type;
        }
        if (name)
        {
            memcpy(name, varying.name.c_str(), lastNameIdx);
            name[lastNameIdx] = '\0';
        }
    }
}

GLsizei Program::getTransformFeedbackVaryingCount() const
{
    ProgramBinary *programBinary = getProgramBinary();
    if (programBinary)
    {
        return static_cast<GLsizei>(programBinary->getTransformFeedbackVaryingCount());
    }
    else
    {
        return 0;
    }
}

GLsizei Program::getTransformFeedbackVaryingMaxLength() const
{
    ProgramBinary *programBinary = getProgramBinary();
    if (programBinary)
    {
        GLsizei maxSize = 0;
        for (size_t i = 0; i < programBinary->getTransformFeedbackVaryingCount(); i++)
        {
            const LinkedVarying &varying = programBinary->getTransformFeedbackVarying(i);
            maxSize = std::max(maxSize, static_cast<GLsizei>(varying.name.length() + 1));
        }

        return maxSize;
    }
    else
    {
        return 0;
    }
}

GLenum Program::getTransformFeedbackBufferMode() const
{
    ProgramBinary *programBinary = getProgramBinary();
    if (programBinary)
    {
        return programBinary->getTransformFeedbackBufferMode();
    }
    else
    {
        return mTransformFeedbackBufferMode;
    }
}

}
