#include "SimpleTextureLoader.h"
#include <fstream>
#include <iostream>
#include <vector>

GLuint SimpleTextureLoader::LoadBMP(const std::string& filepath) {
    std::ifstream file(filepath, std::ios::binary);
    if (!file.is_open()) {
        std::cerr << "Failed to open BMP file: " << filepath << std::endl;
        return 0;
    }
    
    BMPHeader header;
    file.read(reinterpret_cast<char*>(&header), sizeof(BMPHeader));
    
    // Check BMP signature
    if (header.signature[0] != 'B' || header.signature[1] != 'M') {
        std::cerr << "Not a valid BMP file: " << filepath << std::endl;
        return 0;
    }
    
    // Only support 24-bit BMP for simplicity
    if (header.bitsPerPixel != 24) {
        std::cerr << "Only 24-bit BMP files supported: " << filepath << std::endl;
        return 0;
    }
    
    // Calculate image size
    int imageSize = header.width * header.height * 3;
    std::vector<unsigned char> imageData(imageSize);
    
    // Seek to image data
    file.seekg(header.dataOffset);
    file.read(reinterpret_cast<char*>(imageData.data()), imageSize);
    file.close();
    
    // BMP stores BGR, convert to RGB
    for (int i = 0; i < imageSize; i += 3) {
        std::swap(imageData[i], imageData[i + 2]);
    }
    
    // Create OpenGL texture
    GLuint textureID;
    glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_2D, textureID);
    
    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);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, header.width, header.height, 
                 0, GL_RGB, GL_UNSIGNED_BYTE, imageData.data());
    glGenerateMipmap(GL_TEXTURE_2D);
    
    glBindTexture(GL_TEXTURE_2D, 0);
    return textureID;
}

GLuint SimpleTextureLoader::LoadTGA(const std::string& filepath) {
    std::ifstream file(filepath, std::ios::binary);
    if (!file.is_open()) {
        std::cerr << "Failed to open TGA file: " << filepath << std::endl;
        return 0;
    }
    
    TGAHeader header;
    file.read(reinterpret_cast<char*>(&header), sizeof(TGAHeader));
    
    // Skip image ID if present
    if (header.idLength > 0) {
        file.seekg(header.idLength, std::ios::cur);
    }
    
    // Only support uncompressed RGB/RGBA TGA
    if (header.imageType != 2) {
        std::cerr << "Only uncompressed TGA files supported: " << filepath << std::endl;
        return 0;
    }
    
    int bytesPerPixel = header.bitsPerPixel / 8;
    int imageSize = header.width * header.height * bytesPerPixel;
    std::vector<unsigned char> imageData(imageSize);
    
    file.read(reinterpret_cast<char*>(imageData.data()), imageSize);
    file.close();
    
    // TGA stores BGR(A), convert to RGB(A)
    for (int i = 0; i < imageSize; i += bytesPerPixel) {
        std::swap(imageData[i], imageData[i + 2]);
    }
    
    // Create OpenGL texture
    GLuint textureID;
    glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_2D, textureID);
    
    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);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    
    GLenum format = (bytesPerPixel == 4) ? GL_RGBA : GL_RGB;
    glTexImage2D(GL_TEXTURE_2D, 0, format, header.width, header.height, 
                 0, format, GL_UNSIGNED_BYTE, imageData.data());
    glGenerateMipmap(GL_TEXTURE_2D);
    
    glBindTexture(GL_TEXTURE_2D, 0);
    return textureID;
}
