#include "ConfigFile.h"

#include <sstream>
#include <fstream>

std::string trim(std::string const& source, char const* delims = " \t\r\n") {
  std::string result(source);
  std::string::size_type index = result.find_last_not_of(delims);
  if(index != std::string::npos)
    result.erase(++index);

  index = result.find_first_not_of(delims);
  if(index != std::string::npos)
    result.erase(0, index);
  else
    result.erase();
  return result;
}

ConfigFile::ConfigFile(std::string configFile) 
{
	std::ifstream file;
	file.open(configFile.c_str());
	
	if( !file.is_open() )
	{
		fileFound = false;
	}
	else
	{
		fileFound = true;

		std::string line = "";
		std::string name = "";
		std::string value = "";
		std::string inSection = "";
		int posEqual;

		while (std::getline(file,line)) 
		{
			if (!line.length()) continue;
			if (line[0] == '#') continue;
			if (line[0] == ';') continue;

			if (line[0] == '[') {
				inSection=trim(line.substr(1,line.find(']')-1));
				continue;
			}

			posEqual=line.find('=');
			name  = trim(line.substr(0,posEqual));
			value = trim(line.substr(posEqual+1));

			content_[inSection+'/'+name]= value;
		}
	}
}

std::string ConfigFile::Value(std::string const& section, std::string const& entry, std::string const& default) const
{
	std::map<std::string, std::string>::const_iterator ci = content_.find(section + '/' + entry);
	if (ci == content_.end())
		return default;

	return ci->second;
}

int ConfigFile::Value(std::string const& section, std::string const& entry, int const default) const
{
	std::map<std::string, std::string>::const_iterator ci = content_.find(section + '/' + entry);
	if (ci == content_.end())
		return default;

	std::istringstream converter( ci->second );
	int value;
	converter >> value;

	return value;
}

double ConfigFile::Value(std::string const& section, std::string const& entry, double const default) const
{
	std::map<std::string, std::string>::const_iterator ci = content_.find(section + '/' + entry);
	if (ci == content_.end())
		return default;

	std::istringstream converter( ci->second );
	double value;
	converter >> value;

	return value;
}