//Copyright (C) 2007 SiegeLord
//See ReadMe.txt and License.txt for copying information

#include "../include/engine/bitmap.h"
#include "../include/engine/error.h"
#include "../include/engine/fileio.h"
#include <jpgalleg.h>

map<string, SBitmap*> g_mBitmaps;

/**
	Finds the bitmap in the data object.
	This function first tries to find the alredy loaded bitmap in the data object,
	failing that, it loads a new bitmap and sticks it into the data object.
	\param filename Name of the file to load.
	\param data The data object.
	\return The newly loaded/found bitmap
*/
SBitmap* FindBitmap(const char* filename)
{
	map<string, SBitmap*>::iterator it;
	it = g_mBitmaps.find(string(filename));

	if(it == g_mBitmaps.end())//can't find it, so load a new one
	{
		SBitmap* ret = ForceLoadBitmap(filename);

		g_mBitmaps.insert(pair<string, SBitmap*>(string(filename), ret));

		return ret;
	}
	else//return the existing one
	{
		return it->second;
	}
}

/**
	Loads a new bitmap.
	This function loads a bitmap, but does not stick it into any data objects.
	\param filename Name of the file to load.
	\return The newly loaded bitmap
*/
SBitmap* ForceLoadBitmap(const char* filename)
{
	BITMAP* ret = 0;

	ret = LoadAllegBitmap(filename);

	if(ret != 0)
	{
		SBitmap* pBmp = CreateBitmap(ret);
		return pBmp;
	}

	Throw("Could not load bitmap:\n", filename);

	return 0;
}

/**
	Loads a new Allegro bitmap.
	This function loads an Allegro bitmap, this is used when we need to do stuff to the data
	in the bitmap without loading it into
	\param filename Name of the file to load.
	\return The newly loaded bitmap
*/

BITMAP* LoadAllegBitmap(const char* filename, int bits)
{
	BITMAP* ret = 0;

	int old_depth = get_color_depth();

	set_color_depth(bits);

	PACKFILE* file;
	file = LoadFile(filename);
	if(file)
	{
		if(strstr(filename, ".tga") != 0)
            ret = load_tga_pf(file, 0);
		else if(strstr(filename, ".bmp") != 0)
		{
			ret = load_bmp_pf(file, 0);
		}
		else if(strstr(filename, ".jpg") != 0)
		{
			void* buf = 0;
			int size = ReadFile(file, &buf);
			if(buf)
				ret = load_memory_jpg(buf, size, 0);
			free(buf);
		}
		else
			ret = load_pcx_pf(file, 0);
		pack_fclose(file);
	}
	if(!ret)
		Throw("Could not load bitmap:\n", filename);

	set_color_depth(old_depth);
	return ret;
}

/**
	Converts an Allegro bitmap into a open_gl compatible bmp.
	Just as it says.
	\param filename Name of the file to load.
	\return The newly loaded bitmap
*/
SBitmap* CreateBitmap(BITMAP* bmp)
{
	SBitmap* pBmp = new SBitmap;

	if(!allegro_gl_check_texture_ex(AGL_TEXTURE_HAS_ALPHA, bmp, allegro_gl_get_texture_format(bmp)))
		Throw("Problems loading texture!\n", "");
	pBmp->h = bmp->h;
	pBmp->w = bmp->w;
	pBmp->handle = allegro_gl_make_texture_ex(AGL_TEXTURE_HAS_ALPHA, bmp, allegro_gl_get_texture_format(bmp));
	if(!pBmp->handle)
		Throw("Hmm... Something wrong with the texture!\n", "");

	return pBmp;
}

/**
	Converts an Allegro bitmap into a open_gl compatible bmp, sticking it into the data file.
	If it finds that the bitmap was already loaded, it replaces it. It does not delete the bitmap pointer.
	\param filename Name of the file to associate with this bitmap.
	\param data Data Object.
	\return The newly loaded bitmap
*/
SBitmap* CreateBitmap(BITMAP* bmp, const char* filename)
{
	map<string, SBitmap*>::iterator it;
	it = g_mBitmaps.find(string(filename));

	if(it != g_mBitmaps.end())//we have found a preexisting copy, delete it
	{
		g_mBitmaps.erase(it);
	}

	SBitmap* pBmp = CreateBitmap(bmp);

	g_mBitmaps.insert(pair<string, SBitmap*>(string(filename), pBmp));
	return pBmp;
}

void FreeBitmaps()
{
	map<string, SBitmap*>::iterator it = g_mBitmaps.begin();

	while(it != g_mBitmaps.end())
	{
		delete it->second;
		it++;
	}
}
