#pragma once

#include <map>
#include "halleystring.h"
#include "exception.h"

namespace Halley {

	template <typename T>
	class ResourceManager {
	public:
		static void setManager(shared_ptr<ResourceManager<T>> m) { manager = m; }
		static shared_ptr<T> get(String name) { return manager->doGet(name); }
		static void clear() { return manager->doClear(); }

		ResourceManager(String _basePath="")
			: basePath(_basePath)
		{}

	protected:
		virtual shared_ptr<T> load(String name) {
			return shared_ptr<T>();
		}

		virtual String resolveName(String name) {
			return basePath + name;
		}

	private:
		shared_ptr<T> doGet(String _name) {
			String name = resolveName(_name);

			auto res = resources.find(name);
			if (res != resources.end()) return res->second;

			//std::cout << "Loading resource: " << name << std::endl;
			auto newRes = load(name);
			if (!newRes) throw Exception("Unable to find resource: "+name);
			resources[name] = newRes;
			return newRes;
		}

		void doClear() {
			resources.clear();
		}

		std::map<String, shared_ptr<T>> resources;
		String basePath;

		static shared_ptr<ResourceManager<T>> manager;
	};
}
