//
// Created by sebastian on 07.02.26.
//

#include "TextureLoader.h"

#include <stdexcept>

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

Texture2D TextureLoader::loadTexture(const std::string &path) {
    Texture2D texture;

    stbi_set_flip_vertically_on_load(true);

    texture.pixels = stbi_load(
        path.c_str(),
        &texture.width,
        &texture.height,
        &texture.channels,
        0
    );

    if (!texture.pixels) {
        throw std::runtime_error("Failed to load texture: " + path);
    }

    GLenum format = GL_RGB;
    if (texture.channels == 4)
        format = GL_RGBA;
    else if (texture.channels == 3)
        format = GL_RGB;
    else if (texture.channels == 1)
        format = GL_RED;

    glGenTextures(1, &texture.id);
    glBindTexture(GL_TEXTURE_2D, texture.id);

    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);

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

    glGenerateMipmap(GL_TEXTURE_2D);

    glBindTexture(GL_TEXTURE_2D, 0);

    return texture;
}

void TextureLoader::free(Texture2D &texture) {
    if (texture.id != 0) {
        glDeleteTextures(1, &texture.id);
        texture.id = 0;
    }

    if (texture.pixels) {
        stbi_image_free(texture.pixels);
        texture.pixels = nullptr;
    }
}
