#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();

}
