#include "Texture2D.h"

#include "RHI/OpenglDrv/gl.h"


Texture2D::Texture2D() noexcept {
    glGenTextures(1, &texture_);
}

Texture2D::~Texture2D() {
    if (0 == texture_) {
        return;
    }

    glDeleteTextures(1, &texture_);
    texture_ = 0;
}

bool Texture2D::Create(int32 width, int32 height, int32 nrChannels, uint8* data) noexcept {
    if (0 == texture_) {
        return false;
    }
    width_ = width;
    height_ = height;
    channels_ = nrChannels;
    GLenum format = GL_RGB;
    if (nrChannels == 1) {
        format = GL_RED;
    } else if (nrChannels == 3) {
        format = GL_RGB;
    } else if (nrChannels == 4) {
        format = GL_RGBA;
    }
    bool alloced = false;
    if (nullptr == data) {
        const uint32 size = width * height * nrChannels;
        data = new uint8[size];
        memset(data, 0, size);
        alloced = true;
    }

    glBindTexture(GL_TEXTURE_2D, texture_);
    glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); __CHECK_GL_ERROR__
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); __CHECK_GL_ERROR__
    
    if (alloced) {
        delete[] data;
    }

    //glGenerateMipmap(GL_TEXTURE_2D);
    return true;
}

void Texture2D::Update(int32 width, int32 height, int32 channels, uint8* data) noexcept {
    if (0 == texture_ || nullptr == data) {
        return;
    }
    glBindTexture(GL_TEXTURE_2D, texture_); __CHECK_GL_ERROR__
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1); __CHECK_GL_ERROR__
    if (3 == channels){ 
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data); __CHECK_GL_ERROR__
    } else if (4 == channels) {
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); __CHECK_GL_ERROR__
    }    
}

void Texture2D::Active(int32 txture) {
    if (0 == texture_) {
        return;
    }

    glActiveTexture(GL_TEXTURE0 + txture);
    glBindTexture(GL_TEXTURE_2D, texture_);
}
