#ifndef FILE_LOADER_CODE_H
#define FILE_LOADER_CODE_H

#include "factory.h"

namespace cbk
{
	template<class itemType, class paramType, class nameType, bool removeAutomatically>
	inline Factory<itemType, paramType, nameType, removeAutomatically>::Factory(void)
	{
	}

	template<class itemType, class paramType, class nameType, bool removeAutomatically>
	inline Factory<itemType, paramType, nameType, removeAutomatically>::~Factory(void)
	{
		for (stdext::hash_map<nameType, storageClass*>::iterator x = _items.begin(); x != _items.end(); x++)
		{
			delete (x->second);
		}
	}

	template<class itemType, class paramType, class nameType, bool removeAutomatically>
	itemType* Factory<itemType, paramType, nameType, removeAutomatically>::load(const nameType& name, paramType& param)
	{
		stdext::hash_map<nameType, storageClass*>::iterator found = _items.find(name);
		if (found != _items.end())
		{
			(*found->second)++;
			return *(found->second);
		} //else, but the other condition returns

		storageClass *newItem = new storageClass(name, param);
		(*newItem)++;
		itemStoragePair tItem(name, newItem);
		_items.insert(tItem);

		return *newItem;
	}

	template<class itemType, class paramType, class nameType, bool removeAutomatically>
	inline void Factory<itemType, paramType, nameType, removeAutomatically>::unload(const itemType* object)
	{
		unload(object->getName());
	}

	template<class itemType, class paramType, class nameType, bool removeAutomatically>
	void Factory<itemType, paramType, nameType, removeAutomatically>::unload(const nameType& name)
	{
		stdext::hash_map<std::string, storageClass*>::iterator found = _items.find(name);
		if (found == _items.end())
		{
			return;
		} //else, but the other condition returns

		storageClass& tItem = *(found->second);
		tItem--;

		if (removeAutomatically)
			if (tItem == 0)
			{
				delete (found->second);
				found->second = 0;
				_items.erase(found);
			}
	}
	
	template<class itemType, class paramType, class nameType, bool removeAutomatically>
	inline void Factory<itemType, paramType, nameType, removeAutomatically>::deleteItem(const itemType* object)
	{
		deleteItem(object->getName());
	}
	
	template<class itemType, class paramType, class nameType, bool removeAutomatically>
	void Factory<itemType, paramType, nameType, removeAutomatically>::deleteItem(const nameType& name)
	{
		stdext::hash_map<std::string, storageClass*>::iterator found = _items.find(name);
		if (found == _items.end())
		{
			return;
		} //else, but the other condition returns

		delete (found->second);
		found->second = 0;
		_items.erase(found);
	}
	
	template<class itemType, class paramType, class nameType, bool removeAutomatically>
	inline int Factory<itemType, paramType, nameType, removeAutomatically>::getUsage(const itemType* object)
	{
		return getUsage(object->getName());
	}
	
	template<class itemType, class paramType, class nameType, bool removeAutomatically>
	int Factory<itemType, paramType, nameType, removeAutomatically>::getUsage(const nameType& name)
	{
		stdext::hash_map<std::string, storageClass*>::iterator found = _items.find(name);
		if (found == _items.end())
		{
			return 0;
		} //else, but the other condition returns

		storageClass& tItem = *(found->second);

		return tItem;
	}
}

#endif //FILE_LOADER_CODE_H