#ifndef FILE_LOADER_H
#define FILE_LOADER_H

#include <string>
#pragma warning(push)
#pragma warning(disable:4181)
#include <hash_map>
#pragma warning(pop)

#include "factory_storage.h"

namespace cbk
{
	/*Factory includes various functionality to load and unload
	files of various types, while maintaining only one copy in memory.

	itemType should be a type which implements a load function which
	takes a file name as a std::string& which loads the file in, dealing
	with any errors which might occur.

	Calls to loadFile will call itemType's load function if, and only if,
	the file has not already been loaded.

	If unloadAutomatically is true, the class will automatically delete
	and clean-up the loaded file when the last instance is unloaded. In
	any case, when the Factory object is unloaded, it will unload all
	files loaded by deleting their pointers.

	As such, itemType should also include a deconstructor to unload the
	data it loads.
	*/
	template<class itemType, class paramType, class nameType = std::string, bool removeAutomatically = true>
	class Factory
	{
	private:
		typedef factory::_Storage<itemType, paramType, nameType> storageClass;

	public:
		inline Factory(void);
		inline ~Factory(void);

		itemType* load(const nameType& name, paramType& param);

		inline void unload(const itemType* object);
		void unload(const nameType& name);

		inline int getUsage(const itemType* object);
		int getUsage(const nameType& name);

		/*Delete item should only ever be called if
		removeAutomatically is false, and then only
		when there are no open copies of the item.
		The function does not check to see if the item
		is still in use before deleting.*/
		inline void deleteItem(const itemType* object);
		void deleteItem(const nameType& name);
	protected:

	private:
		typedef stdext::hash_map<nameType, storageClass*> itemStorage;
		typedef std::pair<nameType, storageClass*> itemStoragePair;
		itemStorage _items;
	};
}

#include "factory_code.h"

#endif //FILE_LOADER_H