/*
 * ParameterDB.cpp
 *
 *  Created on: Jul 23, 2015
 *      Author: jjpalacios
 */

#include "ParameterDB.h"

namespace clbDEB {


//=============================================================================
//		CONSTRUCTORS / INITIALIZERS
//=============================================================================
//-----  Default constructor  -------------------------------------------------
ParameterDB::ParameterDB() { }


//-----  Main constructor  ----------------------------------------------------
ParameterDB::ParameterDB(const char * fileName) {
	std::ifstream fileReader;

	fileReader.open(fileName);

	if(!fileReader.is_open()) {
		std::string error = "Configuration file ";
		error += fileName;
		error += " not found.";
		throw ClbException(error);
	}

	std::string label, value;
	while (nextParameter(fileReader, label, value)) {
		this->setParameter(label, value);
	}
	fileReader.close();
}




//=============================================================================
//		METHODS
//=============================================================================
//-----  setParamneter  -------------------------------------------------------
void ParameterDB::setParameter(std::string parameter, std::string value) {
	// Insert the new parameter in the database
	std::pair<std::map<std::string, std::string>::iterator,bool> iter =
			parameters.insert(std::pair<std::string,std::string>
				(toUpper(parameter), value));

	// If it already exists, overwrite the value
	if(!iter.second) {
		iter.first->second = value;
	}
}


//-----  getString  -----------------------------------------------------------
std::string ParameterDB::getString(std::string parameter) {
	std::map<std::string, std::string>::iterator entry;
	entry = this->parameters.find(toUpper(parameter));

	// If the parameter does not exist
	if(entry == parameters.end())
		return "";
	return entry->second;
}


//-----  getStringUpper  ------------------------------------------------------
std::string ParameterDB::getStringUpper(std::string parameter) {
	std::map<std::string, std::string>::iterator entry;
	entry = this->parameters.find(toUpper(parameter));

	// If the parameter does not exist
	if(entry == parameters.end())
		return "";
	return toUpper(entry->second);
}


//-----  getDouble  -----------------------------------------------------------
double ParameterDB::getDouble(std::string parameter, double defaultValue) {
	std::string value = this->getString(parameter);
	if(value == "")
		return defaultValue;
	return atof(value.c_str());
}


//-----  getInteger  ----------------------------------------------------------
int ParameterDB::getInteger(std::string parameter, int defaultValue) {
	std::string value = this->getString(parameter);
	if(value == "")
		return defaultValue;
	return atoi(value.c_str());
}


//-----  getBoolean  -----------------------------------------------------------
bool ParameterDB::getBoolean(std::string parameter, bool defaultValue) {
	std::string value = this->getString(parameter);
	if(value == "")
		return defaultValue;
	else if(toupper(value[0]) == 'T')
		return true;
	else if(toupper(value[0]) == 'F')
		return false;
	return defaultValue;
}


//-----  readConfigLine  ------------------------------------------------------
bool ParameterDB::nextParameter(std::ifstream & inputFile,
		std::string & label, std::string & value) {

	label.clear();
	value.clear();

	std::string line;
	bool lineFound = false;
	while(!lineFound) {
		if (!inputFile.eof())
			getline(inputFile, line);
		else
			return false;

		int pos=0;
		while(pos < (int)line.size() &&
				(line[pos] == ' ' || line[pos] == '\t' || line[pos] == '\r'))
			pos++;

		if(pos < (int)line.size() && line[pos] != '#') {
			lineFound = true;
		}
	}


	bool val = false;
	for(int i=0; i < (int)line.size(); i++) {
		if(line[i] == '=') {
			val = true;
			continue;
		}
		if (line[i] == ' ' || line[i] == '\t' || line[i] == '\r')
			continue;
		if(!val)
			label.push_back(line[i]);
		else
			value.push_back(line[i]);
	}

	return true;
}


}

