#include "INI_Section.h"
#ifdef DEBUG
#define ASSERT(test) if (!test) fail();
#else
#define ASSERT(test) 
#endif

// ajout/modification d'une clef et d'une valeur
/*!
	\param strKey : le libellé de la clef
	\param strValue : la valeur à associer à la clef (sous forme de chaine)
*/
void CINI_Section::SetKey(const std::string& strKey, const std::string& strValue)
{
	int nIndex = GetKeyIndex(strKey);

	if(nIndex < 0)
		m_arKeys.push_back(strKey);

	m_mapKeysValues[strKey] = strValue;
}

// recherche d'une clef et récupération de la valeur associée
/*!
	\param strKey : le libellé de la clef à rechercher
	\param strValue : le stockage de la clef de type std::string
	\return renvoie un booléen indiquant si la clef a été trouvée (true) ou non (false)
*/
bool CINI_Section::LookupKey(const std::string& strKey, std::string& strValue)
{
	StdMapStringToString::iterator itMap = m_mapKeysValues.find(strKey);

	if(itMap == m_mapKeysValues.end())
		return false;

	strValue = itMap->second;

	return true;
}

// récupère une clef
/*!
	\param nIndex : l'index de la clef dans la liste ordonnée des clefs
	\return retourne le libellé de la clef située à l'index passé en paramètre
*/
const std::string& CINI_Section::GetKeyAt(const int nIndex) const
{
	ASSERT(nIndex >= 0);
	ASSERT(nIndex < GetKeysCount());

	return m_arKeys[nIndex];
}

// récupère l'index d'une clef
/*!
	\param strKey : le libellé de la clef à chercher
	\return renvoie l'index positif ou nul où se situe la clef, -1 si non trouvée
*/
int CINI_Section::GetKeyIndex(const std::string& strKey)
{
	for(int nKeyNb=0; nKeyNb < GetKeysCount(); nKeyNb++)
		if(strKey.compare( m_arKeys[nKeyNb] ) == 0)
			return nKeyNb;

	return -1;
}

// écrit une clef et sa valeur dans un fichier
/*!
	\param strKey : le libellé de la clef à écrire
	\param ficOut : l'instance vers un std::ofstream où écrire l'information (doit être ouvert)
*/
void CINI_Section::WriteKey(const std::string& strKey, std::ofstream& ficOut)
{
	std::string strValue;

	if(LookupKey(strKey, strValue))
		ficOut << strKey << " = " << strValue << "\r\n";
}

// écrit une clef et sa valeur dans un fichier
/*!
	\param nIndex : l'index de la clef qu'il faut écrire
	\param ficOut : l'instance vers un std::ofstream où écrire l'information (doit être ouvert)
*/
void CINI_Section::WriteKeyAt(const int nIndex, std::ofstream& ficOut)
{
	ASSERT(nIndex >= 0);
	ASSERT(nIndex < GetKeysCount());

	WriteKey(GetKeyAt(nIndex), ficOut);
}

// écrit les clefs et leur valeur dans un fichier
/*!
	\param ficOut : l'instance vers un std::ofstream où écrire l'information (doit être ouvert)
*/
void CINI_Section::WriteKeys(std::ofstream& ficOut)
{
	for(int nKeyNb=0; nKeyNb < GetKeysCount(); nKeyNb++)
		WriteKeyAt(nKeyNb, ficOut);
}

// supprime une clef et la valeur qui lui est associée
/*!
	\param strKey : le libellé de la clef à supprimer
*/
void CINI_Section::RemoveKey(const std::string& strKey)
{
	RemoveKeyAt( GetKeyIndex(strKey) );
}

// supprime une clef et la valeur qui lui est associée
/*!
	\param nIndex : l'index de l'emplacement où se trouve la clef à supprimer
*/
void CINI_Section::RemoveKeyAt(const int nIndex)
{
	ASSERT(nIndex >= 0);
	ASSERT(nIndex < GetKeysCount());

	m_mapKeysValues.erase( m_arKeys[nIndex] );
	m_arKeys.erase(m_arKeys.begin() + nIndex);
}

// supprime toutes les clefs et la valeur qui leur est associée
void CINI_Section::RemoveAll(void)
{
	m_mapKeysValues.clear();
	m_arKeys.clear();
}
