/*
    DBImages.cpp -- Loads and stores images
    Copyright (C) 2011 Marcos Alba Soler (marcos dot alba at estudiants dot urv dot cat)

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/

#include "Implementation.h"
#include "mod_sdl/sdlsurfacetype.h"

#include <Poco/Exception.h>

#include <SDL_rotozoom.h>

#include <SDL_image.h>
#include <SDL_main.h>

using std::string;
using mod_sdl::CTypeSDLSurface;
using boost::shared_ptr;
using Poco::FileNotFoundException;
using namespace std;

namespace XMLImplementation{
	
	/*
	 * Returns true if the first string is smaller than the second, false in other case.
	 */
	bool Classcomp::operator()(string s1, string s2) const{
		return (s1.compare(s2)<0);
	}
	/*
	 * Destructor from class DBImages
	 */
	DBImages::DBImages(){}
	/*
	 * Static method to create an instance to this class
	 */
	shared_ptr<DBImages> DBImages::create(){return shared_ptr<DBImages>(new DBImages);}
	/*
	 * destructor from class DBImages, clears the map
	 */
	DBImages::~DBImages(){
		m_images.clear();
	}
	/*
	 * Returns a Surface from the map if exist given its path. If not exists, loads the surface and it's added to the map.
	 * If the second parameter is given (not equal to zero) the image is rotated those degrees.
	 * Warning: If there's an error loading the image, method returns NULL.
	 */
	SmartPtr<CTypeSDLSurface> DBImages::getImage(string src, int degRot)
	{
		map<string,SmartPtr<CTypeSDLSurface>,Classcomp>::iterator it;
		//Degrees always in this interval (0,359)
		if(degRot<0)degRot=(degRot%(360))+360;
		else if(degRot>359)degRot=degRot%360;
		if(degRot==360)degRot=0;
		//if image is rotated, it's added a string to its path to identify it in the map.
		//the string added is the number of degrees.
		char rot[4];
		sprintf(rot,"%d",degRot);
		string rots;
		rots.assign(rot);
		string srcRot = src + rots;
		if(degRot!=0)
			it = m_images.find(srcRot);
		else 
			it = m_images.find(src);
		// REMOVE THESE COMMENTS; aquest linia feia petar el programa pq. derefenciava un punter invālid
		// cout << "surface: " << it->second << endl;
		SmartPtr<CTypeSDLSurface> surf = CTypeSDLSurface::CreateInstance();
		SDL_Surface* s;
		if(it == m_images.end()){
			//cout << "hola" << endl;
			s = IMG_Load(src.c_str());
			
			if(s!=NULL){
				surf->setSurface(s);
				if(degRot!=0){
					//the rotated image
					s=rotozoomSurface(s, degRot, 1, 0);
					surf->setSurface(s);
					m_images.insert(pair<string,SmartPtr<CTypeSDLSurface> >(srcRot,surf));
				}
				else{
					m_images.insert(pair<string,SmartPtr<CTypeSDLSurface> >(src,surf));
				}
			}
			else return NULL;
		}
		else  surf = it->second;
		return surf;
	}
}