/*
 *  Copyright (C) 2008 Hannu Saransaari, Kristian Kristola
 *
 *  This program is distributed under the terms of the
 *  GNU General Public License.
 *
 *  This file is part of Dave the Ordinary Spaceman.
 *
 *  Dave the Ordinary Spaceman 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.
 *
 *  Dave the Ordinary Spaceman 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 Dave the Ordinary Spaceman. If not, see
 *  <http://www.gnu.org/licenses/>.
 *
 */

#include "image.h"
#include "opengl.h"

#if defined(__MACOS__) || defined(__APPLE__)
#include <SDL_image/SDL_image.h>
#else
#include <SDL/SDL_image.h>
#endif

#include <cassert>
#include <iostream>

//DEBUG
#include <fstream>

using namespace std;

LibraryEntry::LibraryEntry()
{
}

LibraryEntry::~LibraryEntry()
{
}

Image::Image()
{
  texture = 0;
}

Image::Image(const string &filename, bool mipmaps)
{
  load(filename);
}

Image::~Image()
{
}

bool Image::load(const string &filename, bool mipmaps)
{
  unload();
  glGenTextures(1, &texture);
  bind();
  bool s = load_texture(filename.c_str(), mipmaps);
  if (!s)
    unload();
  return s;
}

void Image::bind() const
{
  assert(texture);
  glEnable(GL_TEXTURE_2D);
  glBindTexture(GL_TEXTURE_2D, texture);
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}

void Image::unload()
{
  if (texture)
    glDeleteTextures(1, &texture);
  texture = 0;
}

// Function By Hipo
bool Image::load_texture(const char* filename, bool buildMipmaps)
{
  ifstream asdf(filename);
  cerr << "good: " << asdf.good() << endl;
  asdf.close();

  SDL_Surface *surface = IMG_Load(filename);

  if (!surface) {
    cerr << "SDL_Image ei kykene lataamaan: " << filename << endl;
    return false;
  }

  /* Image size must be in power of two. */

  if ((surface->w & (surface->w - 1)) != 0 ||
      (surface->h & (surface->h - 1)) != 0) {
    SDL_FreeSurface(surface);
    return false;
  }

  width  = surface->w;
  height = surface->h;

  /* Select texture format. */

  GLenum format;

  if (surface->format->BytesPerPixel == 4)
    format = GL_RGBA;
  else if (surface->format->BytesPerPixel == 3)
    format = GL_RGB;
  else if (surface->format->BytesPerPixel == 1)
    format = GL_LUMINANCE;
  else {
    SDL_FreeSurface(surface);
    return false;
  }

  /* Put image to texture. */

  if (buildMipmaps) {
    gluBuild2DMipmaps(GL_TEXTURE_2D,
		      format,
		      surface->w,
		      surface->h,
		      format,
		      GL_UNSIGNED_BYTE,
		      surface->pixels);
    }
  else {
    glTexImage2D(GL_TEXTURE_2D,
		 0,
		 format,
		 surface->w,
		 surface->h,
		 0,
		 format,
		 GL_UNSIGNED_BYTE,
		 surface->pixels);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  }

  SDL_FreeSurface(surface);

  return true;
}

void Image::nearest()
{
  bind();
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}

int Image::get_width() const
{
  return width;
}

int Image::get_height() const
{
  return height;
}

void TextureProxy::bind() const
{
  tex->bind(0);
  glEnable(GL_TEXTURE_2D);
}
