#ifdef LINUX
#ifdef USE_GLES1
#include <GLES/gl.h>
#else
#include <GL/gl.h>
#endif
#endif
#ifdef __APPLE__
#include <OpenGL/gl.h>
#endif

#ifdef USE_DEVIL
#include <IL/ilut.h>
#else
#include "SOIL/SOIL.h"
#endif

#ifdef WIN32
#include "win32-dirent.h"
#endif

#ifdef LINUX
#include <dirent.h>
#endif

#ifdef MACOS
#include <dirent.h>
#endif
#include "TextureManager.hpp"
#include "Common.hpp"
#include "IdleTextures.hpp"



TextureManager::TextureManager(const std::string _presetURL): presetURL(_presetURL)
{
#ifdef USE_DEVIL
  ilInit();
  iluInit();
  ilutInit();
  ilutRenderer(ILUT_OPENGL);
#endif

  Preload();
  loadTextureDir();
}

TextureManager::~TextureManager()
{
  Clear();
}

void
TextureManager::Preload()
{
#ifdef USE_DEVIL
  ILuint image;

  ilGenImages(1, &image);
  ilBindImage(image);
  ilLoadL(IL_TYPE_UNKNOWN,(ILvoid*) M_data, M_bytes);
  GLuint tex = ilutGLBindTexImage();
#else
  unsigned int tex = SOIL_load_OGL_texture_from_memory (
                       M_data,
                       M_bytes,
                       SOIL_LOAD_AUTO,
                       SOIL_CREATE_NEW_ID,

                       SOIL_FLAG_POWER_OF_TWO
                       |  SOIL_FLAG_MULTIPLY_ALPHA
                       // |  SOIL_FLAG_COMPRESS_TO_DXT
                     );
#endif

  textures["M.tga"]=tex;

#ifdef USE_DEVIL
  ilLoadL(IL_TYPE_UNKNOWN,(ILvoid*) project_data,project_bytes);
  tex = ilutGLBindTexImage();
#else
  tex = SOIL_load_OGL_texture_from_memory (
          project_data,
          project_bytes,
          SOIL_LOAD_AUTO,
          SOIL_CREATE_NEW_ID,

          SOIL_FLAG_POWER_OF_TWO
          |  SOIL_FLAG_MULTIPLY_ALPHA
          //|  SOIL_FLAG_COMPRESS_TO_DXT
        );
#endif

  textures["project.tga"]=tex;

#ifdef USE_DEVIL
  ilLoadL(IL_TYPE_UNKNOWN,(ILvoid*) headphones_data, headphones_bytes);
  tex = ilutGLBindTexImage();
#else
  tex = SOIL_load_OGL_texture_from_memory(
          headphones_data,
          headphones_bytes,
          SOIL_LOAD_AUTO,
          SOIL_CREATE_NEW_ID,

          SOIL_FLAG_POWER_OF_TWO
          |  SOIL_FLAG_MULTIPLY_ALPHA
          // |  SOIL_FLAG_COMPRESS_TO_DXT
        );
#endif

  textures["headphones.tga"]=tex;
}

void
TextureManager::Clear()
{
  for(std::map<std::string, GLuint>::const_iterator iter = textures.begin();
      iter != textures.end();
      iter++)
  {
    glDeleteTextures(1,&iter->second);
  }
  textures.clear();
}

void
TextureManager::setTexture(const std::string name, const unsigned int texId, const int width, const int height)
{
  textures[name] = texId;
  widths[name] = width;
  heights[name] = height;
}

//void
//TextureManager::unloadTextures(const PresetOutputs::cshape_container &shapes)
//{
  /*
  for (PresetOutputs::cshape_container::const_iterator pos = shapes.begin();
       pos != shapes.end();
       ++pos)
  {

    if( (*pos)->enabled==1)
    {
      if ( (*pos)->textured)
      {
        std::string imageUrl = (*pos)->getImageUrl();

        if (imageUrl != "")
        {
          std::string fullUrl = presetURL + "/" + imageUrl;
          ReleaseTexture(LoadTexture(fullUrl.c_str()));
        }
      }
    }
  }
  */
//}

GLuint
TextureManager::getTexture(const std::string filename)
{
  std::string fullURL = presetURL + PATH_SEPARATOR + filename;
  return getTextureFullpath(filename,fullURL);
}

GLuint
TextureManager::getTextureFullpath(const std::string filename, const std::string imageURL)
{
  if (textures.find(filename)!= textures.end())
  {
    return textures[filename];
  }
  else
  {
#ifdef USE_DEVIL
    GLuint tex = ilutGLLoadImage((char *)imageURL.c_str());
#else
    int width, height;

    unsigned int tex = SOIL_load_OGL_texture_size (
                         imageURL.c_str(),
                         SOIL_LOAD_AUTO,
                         SOIL_CREATE_NEW_ID,

                         //SOIL_FLAG_POWER_OF_TWO
                         //  SOIL_FLAG_MIPMAPS
                         SOIL_FLAG_MULTIPLY_ALPHA
                         //|  SOIL_FLAG_COMPRESS_TO_DXT
                         //| SOIL_FLAG_DDS_LOAD_DIRECT
                         ,&width,&height
                       );

#endif
    textures[filename]=tex;
    widths[filename]=width;
    heights[filename]=height;
    return tex;
  }
}

int
TextureManager::getTextureWidth(const std::string imageURL)
{
  return widths[imageURL];
}

int
TextureManager::getTextureHeight(const std::string imageURL)
{
  return heights[imageURL];
}

unsigned int
TextureManager::getTextureMemorySize()
{
  return 0;
}

void
TextureManager::loadTextureDir()
{
  std::string dirname = CMAKE_INSTALL_PREFIX "/share/projectM/textures";

  DIR * m_dir;

  // Allocate a new a stream given the current directory name
  if ((m_dir = opendir(dirname.c_str())) == NULL)
  {
    std::cout<<"No Textures Loaded from "<<dirname<<std::endl;
    return; // no files loaded. m_entries is empty
  }

  struct dirent * dir_entry;

  while ((dir_entry = readdir(m_dir)) != NULL)
  {
    // Convert char * to friendly string
    std::string filename(dir_entry->d_name);

    if (filename.length() > 0 && filename[0] == '.')
      continue;

    // Create full path name
    std::string fullname = dirname + PATH_SEPARATOR + filename;

    unsigned int texId = getTextureFullpath(filename, fullname);
    if(texId != 0)
    {
      user_textures.push_back(texId);
      textures[filename]=texId;
      user_texture_names.push_back(filename);
    }
  }

  if (m_dir)
  {
    closedir(m_dir);
    m_dir = 0;
  }
}

std::string
TextureManager::getRandomTextureName(std::string random_id)
{
  if (user_texture_names.size() > 0)
  {
    std::string random_name = user_texture_names[rand() % user_texture_names.size()];
    random_textures.push_back(random_id);
    textures[random_id] = textures[random_name];
    return random_name;
  }
  else return "";
}

void
TextureManager::clearRandomTextures()
{
  for (std::vector<std::string>::iterator pos = random_textures.begin();
       pos != random_textures.end();
       ++pos)
  {
    textures.erase(*pos);
    widths.erase(*pos);
    heights.erase(*pos);
  }
  random_textures.clear();
}
