// CSurface.h
//------------

#ifndef C_SURFACE
#define C_SURFACE

#include <SDL.h>
#include <iostream>
#include <string>
#include <map>
#include "../Main.h"

using namespace std;

extern GlobalState g_applicationState;

class CSurface
{
public:
	CSurface(void);

	static bool LoadImage(string name, string file);
	static void FreeImage(string name);
	static void Unload();

	static bool DrawImage(string name, int x, int y);
	static bool DrawImage(string name, int x, int y, int x2, int y2, int w, int h);

private:
	static bool Draw(SDL_Surface* dest, SDL_Surface* src, int x, int y, SDL_Rect* rect);
	static map<string, SDL_Surface*> loadedSurfaces;
};

#endif

// --------------------
// CSurface.cpp
//---------------------

#include <SDL_image.h>
#include "CSurface.h"

CSurface::CSurface()
{

}

bool CSurface::LoadImage(string name, string file) {

	if(loadedSurfaces.find(name) == loadedSurfaces.end())
	{
		fprintf(stderr, "Attempt to load resource '%s' but is already in resources (file '%s')", name, file);
		return false;
	}

	SDL_Surface* temp = NULL;
	SDL_Surface* result = NULL;

	temp = IMG_Load(file.c_str());
	if(temp == NULL)
	{
		fprintf(stderr, "There was an error loading the temp surface for %s\n", file);
		return false;
	}

	result = SDL_DisplayFormatAlpha(temp);
	SDL_FreeSurface(temp);

	fprintf(stdout, "Loaded Image '%s' as '%s'\n", file, name);

	loadedSurfaces[name] = result;

	return true;
}

void CSurface::FreeImage(string name)
{
	if(loadedSurfaces.find(name) == loadedSurfaces.end())
	{
		fprintf(stderr, "Cannot find '%s' to free it", name);
		return;
	}

	SDL_Surface* surf = loadedSurfaces[name];
	SDL_FreeSurface(surf);
	loadedSurfaces.erase(name);
	fprintf(stdout, "Unloaded Image '%s'\n", name);
}

void CSurface::Unload()
{
	if(loadedSurfaces.size() == 0)
		return;

	for(map<string, SDL_Surface*>::iterator ii = loadedSurfaces.begin(); ii != loadedSurfaces.end(); ii++)
	{
		FreeImage(ii->first);
	}
}

bool CSurface::DrawImage(string name, int x, int y) {

	return Draw(g_applicationState.screen, loadedSurfaces[name], x, y, NULL);
}

bool CSurface::DrawImage(string name, int x, int y, int x2, int y2, int w, int h)
{
	SDL_Rect sourceRect;

	sourceRect.x = x2;
	sourceRect.y = y2;
	sourceRect.w = w;
	sourceRect.h = h;

	return Draw(g_applicationState.screen, loadedSurfaces[name], x, y, &sourceRect);
}

bool CSurface::Draw(SDL_Surface* dest, SDL_Surface* src, int x, int y, SDL_Rect* rect)
{
	if(dest == NULL || src == NULL) {
		return false;
	}

	SDL_Rect destinationRect;

	destinationRect.x = x;
	destinationRect.y = y;

	SDL_BlitSurface(src, rect, dest, &destinationRect);

	return true;
}
