#include "CImageTexture.hpp"

CImageTexture::CImageTexture(ETextureType type, std::string filePath) :
    CAbstractTexture(type),
	m_filePath(filePath) {
}

std::string CImageTexture::getFilePath(void) {
    return m_filePath;
}

void CImageTexture::setFilePath(std::string filePath) {
    m_filePath = filePath;
}

void CImageTexture::init(void) {
    // Read the image file.
    SDL_Surface* sdlSurface = IMG_Load(m_filePath.c_str());

    if (sdlSurface == NULL) {
        throw CLibException(std::string("Image file \"") + m_filePath + std::string("\" can not be opened : ") + std::string(SDL_GetError()));
    }

	// Create the id.
    unsigned int id;
	glGenTextures(1, &id);
    setId(id);

    // Image format.
    GLenum internalFormat(0);
    GLenum externalFormat(0);

    if (sdlSurface->format->BytesPerPixel == 3) {
        // We use RGB as internal format.
        internalFormat = GL_RGB;

        // Choose the external format.
        if (sdlSurface->format->Rmask == 0xff)
            externalFormat = GL_RGB;
        else
            externalFormat = GL_BGR;
    }
    else if (sdlSurface->format->BytesPerPixel == 4) {
        // We use RGBA as internal format.
        internalFormat = GL_RGBA;

        // Choose the external format.
        if (sdlSurface->format->Rmask == 0xff)
            externalFormat = GL_RGBA;
        else
            externalFormat = GL_BGRA;
    }
    else {
        SDL_FreeSurface(sdlSurface);
        throw CRuntimeException("Unknow image internal format.");
    }

    // Lock the texture to use it.
    glBindTexture(GL_TEXTURE_2D, getId());

    // Fill the GL texture.
    glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, sdlSurface->w, sdlSurface->h, 0, externalFormat, GL_UNSIGNED_BYTE, sdlSurface->pixels);

    // Set filters : the near texture have a linear filter.
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    // The far texture have a nearest filter, meaning no filter.
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

	// Unlock the texture.
	glBindTexture(GL_TEXTURE_2D, 0);

    // Free the surface.
    SDL_FreeSurface(sdlSurface);
}