#include "CfgParser.h"
#include "StringUtilities.h"

#include <fstream>

using namespace std;

namespace BlueCore
{

void CfgParser::parseFile(const std::string& filename)
{
	ifstream file(filename.c_str(), ios::in);
	std::string line;

	while (file.good())
	{
		getline(file, line);
		parseLine(line);
	}
}

void CfgParser::parseLine(const std::string& line)
{
	std::string::size_type i(line.find_first_of('='));

	if (i == std::string::npos)
		return;

	std::string key = trim(string(line, 0, i-1));
	std::string value = trim(string(line, i+1));

	_Pairs[key] = value;
}

void CfgParser::parse(const char* buffer, unsigned int length)
{
	const char* ptr = buffer;
	const char* end = buffer + length;
	unsigned int l = 0;

	while (ptr < end)
	{
		// find end of line
		while (ptr[l] != '\n')
		{
			l++;
			if (ptr + l >= end)
				break;
		}

		parseLine(string(ptr, l));
		ptr += l+1;
		l = 0;
	}
}

double CfgParser::get(const std::string& key, double defaultValue)
{
	double value;

	if (getDouble(key, value) == false)
		return defaultValue;
	else
		return value;
}

bool CfgParser::getDouble(const std::string& key, double& value)
{
	std::map<std::string, std::string>::const_iterator result;
	result = _Pairs.find(key);

	if (result != _Pairs.end())
	{
		value = atof(result->second.c_str());
		return true;
	}
	else
		return false;
}

int CfgParser::get(const std::string& key, int defaultValue)
{
	int value;

	if (getInteger(key, value) == false)
		return defaultValue;
	else
		return value;
}

bool CfgParser::getInteger(const std::string& key, int& value)
{
	std::map<std::string, std::string>::const_iterator result;
	result = _Pairs.find(key);

	if (result != _Pairs.end())
	{
		value = atoi(result->second.c_str());
		return true;
	}
	else
		return false;
}

bool CfgParser::get(const std::string& key, bool defaultValue)
{
	bool value;

	if (getBoolean(key, value) == false)
		return defaultValue;
	else
		return value;
}

bool CfgParser::getBoolean(const std::string& key, bool& value)
{
	std::map<std::string, std::string>::const_iterator result;
	result = _Pairs.find(key);

	if (result != _Pairs.end())
	{
		value = false;

		if (result->second == "true")
			value = true;
		else if (result->second == "1")
			value = true;
		else if (result->second == "yes")
			value = true;

		return true;
	}
	else
		return false;
}

std::string CfgParser::get(const std::string& key, std::string defaultValue)
{
	std::string value;

	if (getString(key, value) == false)
		return defaultValue;
	else
		return value;
}

bool CfgParser::getString(const std::string& key, std::string& value)
{
	std::map<std::string, std::string>::const_iterator result;
	result = _Pairs.find(key);

	if (result != _Pairs.end())
	{
		value = result->second;
		return true;
	}
	else
		return false;
}

bool CfgParser::getStrings(const std::string& key, std::vector<string>& strings)
{
	std::map<std::string, std::string>::const_iterator result;
	result = _Pairs.find(key);

	if (result != _Pairs.end())
	{
		explode(result->second, strings, true, ",");
		return true;
	}
	else
		return false;
}

bool CfgParser::getDoubles(const std::string& key, std::vector<double>& doubles)
{
	std::map<std::string, std::string>::const_iterator result;
	result = _Pairs.find(key);

	if (result != _Pairs.end())
	{
		std::vector<std::string> strings;
		explode(result->second, strings, true, ",");
		std::vector<std::string>::iterator i;
		for (i = strings.begin(); i != strings.end(); i++)
			doubles.push_back(atof((*i).c_str()));
		return true;
	}
	else
		return false;
}

} // namespace BlueCore

