#include "texture.h"

texture::texture(){
    raw = 0;

    flagsa = 0;
}
bool texture::load( const char* fname, bool ulctrans, bool correct ){
    #if SDL_BYTEORDER == SDL_LIL_ENDIAN
       static const Uint32 rmask = 0x000000FF;
       static const Uint32 bmask = 0x0000FF00;
       static const Uint32 gmask = 0x00FF0000;
       static const Uint32 amask = 0xFF000000;
    #else
       static const Uint32 rmask = 0xFF000000;
       static const Uint32 bmask = 0x00FF0000;
       static const Uint32 gmask = 0x0000FF00;
       static const Uint32 amask = 0x000000FF;
    #endif
    //correct = true;
    SDL_Surface* surface = IMG_Load( fname );

    SDL_DisplayFormat( surface );
    SDL_Surface* newSurface = surface;

    //if( correct ){
        SDL_PixelFormat *format = surface->format;
        Uint32 width = surface->w;
        Uint32 height = surface->h;
        Uint32 widthPow = (unsigned) pow( 2, ceil( log( width ) / log( 2 ) ) );
        Uint32 heightPow = (unsigned) pow( 2, ceil( log( height ) / log( 2 ) ) );

        newSurface = SDL_CreateRGBSurface( SDL_SRCALPHA, widthPow, heightPow, 32, rmask, bmask, gmask, amask );
        SDL_DisplayFormat( newSurface );

        Uint32 alpha = 0;
        alpha = SDL_MapRGBA( format, 0, 0, 0, amask );
        SDL_Rect rect;
        rect.x = 0;
        rect.y = 0;
        rect.h = heightPow;
        rect.w = widthPow;
        int ret = SDL_FillRect( newSurface, &rect, alpha);
        surface->flags &= !SDL_SRCALPHA;

        SDL_SetAlpha( newSurface, SDL_SRCALPHA, SDL_ALPHA_TRANSPARENT );

        if( ulctrans ){
        SDL_SetColorKey( surface, SDL_SRCCOLORKEY, SDL_MapRGB(surface->format, 255, 0, 255)  );
        }
        ret = SDL_BlitSurface( surface, 0, newSurface, 0 );
    //}
    glEnable( GL_TEXTURE_2D );
 raw = (void*) newSurface;
            glGenTextures( 1, &texid );
        glBindTexture( GL_TEXTURE_2D, texid );
        gluBuild2DMipmaps( GL_TEXTURE_2D, 4, surface->w, surface->h, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels );

    if( correct )
        SDL_FreeSurface( surface );
    //raw = (void*) newSurface;

    return texid;
}
void texture::bilinear( bool a ){
    if( a ) flagsa = 1;
    else flagsa = 0;
}
bool texture::isvalid(){
    if( raw == 0 ) return false;
    return glIsTexture( texid );
}
void texture::bind(){
    if( raw == 0 ) return;
    glEnable( GL_TEXTURE_2D );
    if( !isvalid() ){
        glGenTextures( 1, &texid );
        glBindTexture( GL_TEXTURE_2D, texid );
        gluBuild2DMipmaps( GL_TEXTURE_2D, 4, ((SDL_Surface*)raw)->w, ((SDL_Surface*)raw)->h, GL_RGBA, GL_UNSIGNED_BYTE, ((SDL_Surface*)raw)->pixels );
    }
    glBindTexture( GL_TEXTURE_2D, texid );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
                 !flagsa ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR_MIPMAP_LINEAR );
    // when texture area is large, bilinear filter the original
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, !flagsa ? GL_NEAREST : GL_LINEAR );

        // the texture wraps over at the edges (repeat)
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
    glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
}
void texture::unload(){

}
texture::~texture(){
    SDL_FreeSurface( ((SDL_Surface*)raw) );
}
