#pragma once

#include <algorithm>
#include <map>
#include <string>
#include <sstream>
#include "resource.h"

struct resource_manager;

struct ini;

struct ini_category {
	friend struct ini;
	template<typename T>
	T get(std::string const& entry) const;
	static ini_category const empty;
private:
	std::string const& get_string(std::string const& entry) const;
	std::map<std::string, std::string> _data;
};

struct ini : resource{
	ini(resource_manager& rm, ini_category const* ini, std::string const& path, std::vector<uint8_t> data);

	template<typename T>
	T get(std::string const& category, std::string const& entry) const;

	ini_category const* get_category(std::string const& name) const;

private:
	std::map<std::string, ini_category> _data;
};

template<typename T>
inline T ini::get(std::string const& category, std::string const& entry) const {
	if(_data.contains(category))
		return _data.at(category).get<T>(entry);
	else
		return ini_category::empty.get<T>("");
}


template<typename T>
inline T ini_category::get(std::string const& entry) const {
	std::stringstream ss;
	T t;
	ss << get_string(entry);
	ss >> t;
	return t;
}

template<>
inline bool ini_category::get(std::string const& entry) const {
	std::vector<std::string> yes{ "true", "yes", "on" };
	auto str = get_string(entry);
	std::transform(str.begin(), str.end(), str.begin(), ::tolower);
	if(std::find(yes.begin(), yes.end(), str) != yes.end())
		return true;
	else
		return false;
}