#include "OpenGlShaderProgram.h"

#include "File.h"
#include "FileLogger.h"

#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <GL/glu.h>

OpenGlShaderProgram::OpenGlShaderProgram(const Path& vertShaderPath, const Path& fragShaderPath)
{
    const auto vert_shader_source = File(vertShaderPath).read();
    const auto frag_shader_source = File(fragShaderPath).read();

    unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);

    const char* vert_source = vert_shader_source.c_str();
    glShaderSource(vertexShader, 1, &vert_source, nullptr);
    glCompileShader(vertexShader);

    int  success;
    char infoLog[512];
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    if(!success)
    {
        glGetShaderInfoLog(vertexShader, 512, nullptr, infoLog);
        MLOG_ERROR("ERROR::SHADER::VERTEX::COMPILATION_FAILED: " << infoLog);
        if (auto errCode = glGetError(); errCode != GL_NO_ERROR)
        {
            auto errString = gluErrorString(errCode);
            MLOG_ERROR("Got gl error " << errString);
        }
    }

    unsigned int fragmentShader;
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    const char* frag_source = frag_shader_source.c_str();
    glShaderSource(fragmentShader, 1, &frag_source, nullptr);
    glCompileShader(fragmentShader);

    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
    if(!success)
    {
        glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
        MLOG_ERROR("ERROR::SHADER::FRAGMENT::COMPILATION_FAILED: " << infoLog);
    }

    mHandle = glCreateProgram();

    glAttachShader(mHandle, vertexShader);
    glAttachShader(mHandle, fragmentShader);
    glLinkProgram(mHandle);

    glGetProgramiv(mHandle, GL_LINK_STATUS, &success);
    if(!success)
    {
        glGetProgramInfoLog(mHandle, 512, NULL, infoLog);
        MLOG_ERROR("Shader linking FAILED: " << infoLog);
    }

    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
}

unsigned int OpenGlShaderProgram::getHandle() const
{
    return mHandle;
}
