#include <GL/glew.h>
#include <iostream>

#include "client/rendering/wrapper/GLWrapper.h"

bool GLWrapper::checkAndPrintError(const char* message) {
    GLenum error = glGetError();
    switch(error) {
        case GL_NO_ERROR:
            return false;
        case GL_INVALID_ENUM:
            std::cout << message << ": an unacceptable value is specified for an enumerated argument.\n";
            break;
        case GL_INVALID_VALUE:
            std::cout << message << ": a numeric argument is out of range.\n";
            break;
        case GL_INVALID_OPERATION:
            std::cout << message << ": the specified operation is not allowed in the current state.\n";
            break;
        case GL_INVALID_FRAMEBUFFER_OPERATION:
            std::cout << message << ": the framebuffer object is not complete.\n";
            break;
        case GL_OUT_OF_MEMORY:
            std::cout << message << ": there is not enough memory left to execute the command.\n";
            break;
        case GL_STACK_UNDERFLOW:
            std::cout << message << ": an attempt has been made to perform an operation that would cause an internal stack to underflow.\n";
            break;
        case GL_STACK_OVERFLOW:
            std::cout << message << ": an attempt has been made to perform an operation that would cause an internal stack to overflow.\n";
            break;
        default:
            std::cout << message << ": unknown OpenGL error: " << error << "\n";
    }
    return true;
}

void GLWrapper::enableDepthTesting() {
    glEnable(GL_DEPTH_TEST);
}

void GLWrapper::disableDepthTesting() {
    glDisable(GL_DEPTH_TEST);
}

void GLWrapper::prepareMainFramebuffer() {
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
}

void GLWrapper::enableBlending() {
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glBlendEquation(GL_FUNC_ADD);
}

void GLWrapper::disableBlending() {
    glDisable(GL_BLEND);
}