/*Copyright (C) 2010-2012 Duncan Deveaux

This file is part of Hikou no mizu.

Hikou no mizu is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Hikou no mizu is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Hikou no mizu.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "Texture.hpp"

Texture::Texture() : m_width(0), m_height(0)
{
    
}

Texture::~Texture()
{
    glDeleteTextures(1, &m_glTexture);
}

void Texture::draw(float x1, float y1, float x2, float y2) const
{
    //Enable needed modules
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
    glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, m_glTexture);
    
    //Draw
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    
    float width = (x2 - x1) * m_width;
    if (width < 0) width *= -1;
    
    float height = (y2 - y1) * m_height;
    if (height < 0) height *= -1;
    
    float vertices[8] = {0,0, width,0, width,height, 0,height};
    float textCoords[8] = {x1,y1, x2,y1, x2,y2, x1,y2};
    
    glVertexPointer(2, GL_FLOAT, 0, vertices);
    glTexCoordPointer(2, GL_FLOAT, 0, textCoords);
    
    glDrawArrays(GL_QUADS, 0, 4);
    
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_VERTEX_ARRAY);
    
    //Disable loaded modules
    glDisable(GL_TEXTURE_2D);
    glDisable(GL_BLEND);
}

//Get and set methods
GLsizei Texture::getWidth() const
{
    return m_width;
}

GLsizei Texture::getHeight() const
{
    return m_height;
}

//Load methods
void Texture::loadFromFile(const std::string &path)
{
    SDL_Surface *surface = IMG_Load( path.c_str() );
    
    GLint format = GL_RGB;
    if (surface->format->BytesPerPixel == 4) format = GL_RGBA;
    
    loadFromMemory(surface->pixels, format, format, surface->w, surface->h);
    
    SDL_FreeSurface(surface);
}

void Texture::loadFromMemory(const GLvoid *pixels, GLint format, GLenum dataFormat, GLsizei width, GLsizei height)
{
    //Delete previous resources
    glDeleteTextures(1, &m_glTexture);
    
    glGenTextures(1, &m_glTexture);
    glBindTexture(GL_TEXTURE_2D, m_glTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, dataFormat, GL_UNSIGNED_BYTE, pixels);
    
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    
    m_width = width;
    m_height = height;
}

int Texture::nextPow2(int number)
{
    int buffer = 1;
    while (buffer < number)
        buffer <<= 1;
    
    return buffer;
}
