//
// Created by Tristan on 1/4/2026.
//

#include "texture.h"
#include <string.h>
#include "../logger/log.h"

GLuint texture_load_from_blp_memory(const uint8_t* file_data, size_t file_size) {
    if (!file_data || file_size < sizeof(BLPHeader)) {
        log_error("BLP texture data is empty or too small");
        return 0;
    }

    const BLPHeader* h = (const BLPHeader*)file_data;

    if (memcmp(h->magic, "BLP2", 4) != 0) {
        log_error("Invalid BLP Magic. Expected BLP2, got %s", h->magic);
        return 0;
    }

    if (h->compression != 2) {
        log_error("Unsupported BLP compression type: %d", h->compression);
        return 0;
    }

    GLenum glFormat = 0;
    switch (h->pixelFormat) {
        case 0: // DXT1
            glFormat = (h->alphaBits > 0) ? GL_COMPRESSED_RGBA_S3TC_DXT1_EXT : GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
            break;
        case 1: // DXT3
            glFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
            break;
        case 7:
            glFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
            break;
        default:
            log_error("Unsupported DXT pixelFormat: %d", h->pixelFormat);
            return 0;
    }

    GLuint textureID;
    glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_2D, textureID);

    // WMO textures standard settings
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    uint32_t width = h->width;
    uint32_t height = h->height;
    int blockSize = (glFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || glFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) ? 8 : 16;

    for (int i = 0; i < 16; i++) {
        if (h->mipOffset[i] == 0 || (width == 0 && height == 0)) break;

        const uint8_t* dataPtr = file_data + h->mipOffset[i];
        uint32_t mipSize = ((width + 3) / 4) * ((height + 3) / 4) * blockSize;
        if (mipSize == 0)
            mipSize = blockSize;

        glCompressedTexImage2D(GL_TEXTURE_2D, i, glFormat, width, height, 0, mipSize, dataPtr);

        width /= 2;
        height /= 2;
        if (width == 0)
            width = 1;
        if (height == 0)
            height = 1;
    }

    return textureID;
}
