#pragma once

#define FILE_NOT_EXISTING        "The file you tried to open doesn't exist"
#define FILENAME_NOT_DEFINED    "You didn't declare a file name"
#define NO_FILE_NAME            "<no File Name>"

class ConfigFileException
{
public:
	std::string errMessage;
	std::string fileName;

	ConfigFileException( std::string tmpErrMessage, std::string tmpFileName )
	{
		fileName = tmpFileName;
		errMessage = tmpErrMessage;
	}
};

class ConfigFile
{
std::string FileName;

public:
	////////////////////////////////////
	ConfigFile( std::string strFile ) {
		this->FileName = strFile;

		if(!FileExists())
		{
		ConfigFileException e(FILE_NOT_EXISTING, this->FileName);

		throw e;
		}
	}

	ConfigFile( ) {
	}

	~ConfigFile( ) {
	}
	////////////////////////////////////


	////////////////////////////////////
	void SetFileName( std::string newFileName )
	{
		this->FileName = newFileName;

		if(!FileExists())
		{
			ConfigFileException e(FILE_NOT_EXISTING, this->FileName);

			throw e;
		}
	}

	std::string GetFileName()
	{
		if(this->FileName.size() < 1 )
		{
			ConfigFileException e(FILENAME_NOT_DEFINED, NO_FILE_NAME);

			throw e;    

			return false;
		}

		return this->FileName;
	}

	bool FileExists() //If no file specified, just check if the FileName file exists
	{
		if(this->FileName.size() < 1 )
		{
			ConfigFileException e(FILENAME_NOT_DEFINED, NO_FILE_NAME);

			throw e;    

			return false;
		}

		bool retVal = false;
		std::fstream tmpFile;

		tmpFile.open(this->FileName.c_str(), std::ios::in);

		if( tmpFile.is_open() )
			retVal = true;

		tmpFile.close();

		return retVal;
	}

	bool FileExists( std::string fileName )
	{
		bool retVal = false;
		std::fstream tmpFile;

		tmpFile.open(fileName.c_str(), std::ios::in);

		if( tmpFile.is_open() )
			retVal = true;

		tmpFile.close();

		return retVal;
	}

	int ReadIntValue( std::string section, std::string option )
	{
		if(!FileExists())
		{
			ConfigFileException e(FILE_NOT_EXISTING, this->FileName);

			throw e; //Have fun
		}

		return GetPrivateProfileIntA(section.c_str(), option.c_str(), -1, this->FileName.c_str());
	}

	float ReadFloatValue( std::string section, std::string option )
	{
		if(!FileExists())
		{
			ConfigFileException e(FILE_NOT_EXISTING, this->FileName);

			throw e; //Have fun
		}

		char tmpStr[16] = {'\0'};

		GetPrivateProfileStringA(section.c_str(), option.c_str(), NULL, tmpStr, 15, this->FileName.c_str());

		return (float)atof(tmpStr);
	}

	std::string ReadStringValue( std::string section, std::string option )
	{
		if(!FileExists())
		{
			ConfigFileException e(FILE_NOT_EXISTING, this->FileName);

			throw e;
		}

		char tmpStr[256] = {'\0'};

		GetPrivateProfileStringA(section.c_str(), option.c_str(), NULL, tmpStr, 255, this->FileName.c_str());

		return std::string(tmpStr);
	}

	void WriteValue( std::string section, std::string option, std::string val )
	{
		if(this->FileName.size() < 1 )
		{
			ConfigFileException e(FILENAME_NOT_DEFINED, NO_FILE_NAME);

			throw e;
		}

		WritePrivateProfileStringA(section.c_str(), option.c_str(), val.c_str(), this->FileName.c_str());
	}

	void WriteValue( std::string section, std::string option, int val )
	{
		if(this->FileName.size() < 1 )
		{
			ConfigFileException e(FILENAME_NOT_DEFINED, NO_FILE_NAME);

			throw e;    
		}

		char tmpResult[10] = {'\0'};
		_itoa_s (val, tmpResult, 9, 10);
		WritePrivateProfileStringA(section.c_str(), option.c_str(), tmpResult, this->FileName.c_str());
	}

	void WriteValue( std::string section, std::string option, float val )
	{
		if(this->FileName.size() < 1 )
		{
			ConfigFileException e(FILENAME_NOT_DEFINED, NO_FILE_NAME);

			throw e;    
		}

		char tmpResult[16] = {'\0'};
		sprintf(tmpResult, "%f", val);
		WritePrivateProfileStringA(section.c_str(), option.c_str(), tmpResult, this->FileName.c_str());
	}
};
