/**
* OpenGL Texture Manager
* @version: 3-20-2005
* @author Joseph 'Pcjoe' Florencio
*/

#include "../hud.h"
#include "../cl_util.h"
#include "fxsys.h"

CGLTextureManager gGLTextureManager;

// Load Texture
GLuint CGLTexture::loadTexture( std::string strPath, bool bWrap )
{	FILE *pFile = NULL;

	// Set Path
	setTexturePath(strPath);

	// Get full path
	std::string strFullPath = g_ParseMain.getBaseDir() + strPath;

	// Open file
	pFile = fopen(strFullPath.c_str(), "r");
	if(pFile == NULL)
	{	return 0;
	}
	fclose(pFile);

	// Load Texture
	setBMPTextureData(auxDIBImageLoad(strFullPath.c_str()));
	if(getBMPTextureData() == NULL)
	{	return 0;
	}

	// Generate texture
	GLuint iTexture = 0;
	glGenTextures(1, &iTexture);
	setTextureNum(iTexture);

	// Setup mipmaps
	setupMipmaps(bWrap);

	// Return texture num
	return getTextureNum();
}

// Setup Mipmaps
void CGLTexture::setupMipmaps( bool bWrap )
{	// Bind Texture
	glBindTexture(GL_TEXTURE_2D, getTextureNum());

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

	// Wrap texture
	if(bWrap)
	{	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	}

	// Build 2D MipMaps
	gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, getBMPTextureData()->sizeX, getBMPTextureData()->sizeY,
						GL_RGB, GL_UNSIGNED_BYTE, getBMPTextureData()->data);

	// Unbind Texture
	glBindTexture(GL_TEXTURE_2D, 0);
}

// Invert Texture Colors
void CGLTexture::invertTextureColors( void )
{	AUX_RGBImageRec *pData = getBMPTextureData();
	if(pData)
	{	// Bind Texture
		glBindTexture(GL_TEXTURE_2D, getTextureNum());

		// Invert colors
		for ( int i=0; i < (3*pData->sizeX*pData->sizeY); i++ )
			pData->data[i] = 255 - pData->data[i];

		// re-build 2D MipMaps
		gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, pData->sizeX, pData->sizeY,
						GL_RGB, GL_UNSIGNED_BYTE, pData->data);

		// Unbind Texture
		glBindTexture(GL_TEXTURE_2D, 0);
	}
}

// Load BMP
CGLTexture *CGLTextureManager::loadBMP( std::string strPath, bool bWrap, GLuint &iTexture )
{	CGLTexture texture;
	iTexture = texture.loadTexture(strPath, bWrap);
	return addToList(texture);
}
// Load BMP
CGLTexture *CGLTextureManager::loadBMP( std::string strPath, bool bWrap )
{	GLuint iTex;
	return loadBMP(strPath,bWrap,iTex);
}

// Load Empty Texture
GLuint CGLTextureManager::createBlankTexture( int iWidth, int iHeight, GLenum target )
{	GLuint iTexture=0;

	// Generate texture for screen
	glGenTextures(1, &iTexture);

	// Bind Texture
	glBindTexture(target, iTexture);

	// Set mip mapping
	glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

	// Copy blank tex
	glCopyTexImage2D( target, 0, GL_RGBA, 0, 0, iWidth, iHeight, 0 );

	// return texture
	return iTexture;
}

// Find Texture
CGLTexture *CGLTextureManager::findTexture( std::string strPath )
{	std::list<CGLTexture>::iterator iterTex;
	ForEachIn(iterTex, (*getTextureList()))
	{	if(iterTex->getTexturePath() == strPath)
		{	return (&(*iterTex));
		}
	}
	return NULL;
}

// Add to list
CGLTexture *CGLTextureManager::addToList( CGLTexture texture )
{	getTextureList()->push_front(texture);
	return (&(*getTextureList()->begin()));
}