#ifdef LINUX
#include <GL/gl.h>
#endif
#ifdef WIN32
#include "glew.h"
#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();

}
