#include "twn_gpu_texture_c.h"
#include "twn_util_c.h"


GPUTexture create_gpu_texture(TextureFilter filter, bool generate_mipmaps) {
    GLuint texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);

    glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, (GLboolean)generate_mipmaps);

    if (filter == TEXTURE_FILTER_NEAREAST) {
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    } else if (filter == TEXTURE_FILTER_LINEAR) {
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    }

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

#if !defined(EMSCRIPTEN)
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
#endif

    glBindTexture(GL_TEXTURE_2D, 0);
    return texture;
}


void delete_gpu_texture(GPUTexture texture) {
    glDeleteTextures(1, &texture);
}


void upload_gpu_texture(GPUTexture texture, void *pixels, int channels, int width, int height) {
    glBindTexture(GL_TEXTURE_2D, texture);

    int format_internal, format;
    if (channels == 4) {
        format_internal = GL_RGBA8;
        format = GL_RGBA;
    } else if (channels == 3) {
        format_internal = GL_RGBA8;
        format = GL_RGB;
    } else if (channels == 1) {
        format_internal = GL_ALPHA;
        format = GL_ALPHA;
    } else {
        CRY("upload_gpu_texture", "Unsupported channel count");
        return;
    }

    glTexImage2D(GL_TEXTURE_2D,
                 0,
                 format_internal,
                 width,
                 height,
                 0,
                 format,
                 GL_UNSIGNED_BYTE,
                 pixels);

    glBindTexture(GL_TEXTURE_2D, 0);
}


void bind_gpu_texture(GPUTexture texture) {
    glBindTexture(GL_TEXTURE_2D, texture);
}
