/*
 =======================================================================================
  Name        :IniData.cpp
 
  Author      : VL                          Date :16/07/97
 
  Description :function to get ini data, check this data, write them ...
 =======================================================================================
  Modification -> Author :                  Date :
  Description :
 =======================================================================================
 */

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include "stdafx.h"
#include "winbase.h"
#include "constant.h"
#include "IniData.h"
#include "MajData.h"
#include "Tree_Fct.h"
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

/*
 =======================================================================================
  Globals
 =======================================================================================
 */

COleDateTime	g_oObtainingTime;
tdstIniData		g_stIniData;			// data in ini file
tdstIniData		g_stDefaultData =		// default value for data
				{
					"",					// default temp path (computed)
					"none",				// default local path (computed if none)
					"$\\",				// default Vss path (not computed)
					"",					// default path to vss database (not computed)
					"",					// default user name (computed if empty)
					"INUPDATE.SEM",		// name of semaphore file
					"",					// spec of vss item Inupdate.sem (computed)
					"",					// local filename of InUpdate.Sem (computed)
					"INOBTAIN.SEM",		// name of semaphore file
					"",					// spec of vss item InObtain.sem (computed)
					"",					// local filename of InObtain.Sem (computed)
					"ModifLst.txt",		// name of file with list of modification (never computed)
					NULL,				// pointer to last obtained time (set to g_oObtainingTime)
					/*
					0,					// number of file/project obtained
					NULL,				// list of file/project obtained
					*/
					"",					// array of available configuration (computed)
					{ "ObtainFileList", -1, "NoFileListConfig", "", 0, NULL },	//configuration for obtaining operation
					{ "UpdateFileList", -1, "NoFileListConfig", "", 0, NULL },	// config for updating with config operation
					/*
					0,					// number of files that are to be obtain (computed)
					NULL,				// list of files that are to be obtain.
					*/
				};

char			g_szIniFile[MAX_PATH];
tdstWindowsPref	g_stWinPref;

/*
 =======================================================================================
	Macros 
 =======================================================================================
 */

/*
 * Macro to bound size of a rect
 */
#define M_vCheckRectSize( _p_stRect, _iMinWidth, _iMinHeight )\
{\
	if (_p_stRect->right - _p_stRect->left + 1 < _iMinWidth )\
		_p_stRect->right = _p_stRect->left + _iMinWidth ;\
	if (_p_stRect->bottom - _p_stRect->top + 1 < _iMinHeight )\
		_p_stRect->bottom = _p_stRect->top + _iMinHeight;\
}

/*
 =======================================================================================
  Functions to manage file list
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : return config structure that correspond to given type
 ----------------------------------------------------------------------------------------
 */
tdstFileListConfig *fn_IniD_p_stGetFileListConfig( char _cConfigType )
{
	switch (_cConfigType)
	{
		case C_ConfigType_cObtain:
			return &g_stIniData.stObtainConfig;
		case C_ConfigType_cUpdate:
			return &g_stIniData.stUpdateConfig;
	}
	return NULL;
}
 

/*
 ----------------------------------------------------------------------------------------
  Description   : free fileList in Init Data structure
 ----------------------------------------------------------------------------------------
 */
void fn_IniD_vFreeFileList( tdstFileListConfig *_p_stFileList )
{
	int iFile;

	if ( _p_stFileList == NULL)
		return;
	
	if (_p_stFileList->lNumberOfFiles != 0)
	{
		for (iFile = 0; iFile < _p_stFileList->lNumberOfFiles; iFile++)
			free ( _p_stFileList->d_szFile[iFile] );
		free ( _p_stFileList->d_szFile );
		_p_stFileList->lNumberOfFiles = 0;
	}
}


/*
 ----------------------------------------------------------------------------------------
  Description   : write file list config in ini file
 ----------------------------------------------------------------------------------------
 */
void fn_IniD_vWriteFileList( tdstFileListConfig *_p_stFileList, char *_szIniFile )
{
	int					iOldFileNumber;
	int					iFile;
	char				szString[40];


	if (_p_stFileList == NULL)
		return;

	/* set ini file in RW mode if in ReadOnly mode */
	if ( (_access( _szIniFile, 0) == 0) && (_access( _szIniFile, 2) == -1) )
		_chmod ( _szIniFile, _S_IWRITE );

	iOldFileNumber = GetPrivateProfileInt( _p_stFileList->szId, "Number", 0, _szIniFile );

	if (_szIniFile == g_szIniFile )
	{
		g_stIniData.a_cAvailableConfig[ _p_stFileList->cIndex ] = 1;
		WritePrivateProfileString( "Vss", _p_stFileList->szKey, _p_stFileList->szId, g_szIniFile );
	}

	WritePrivateProfileString( _p_stFileList->szId, "Name", _p_stFileList->szName, _szIniFile );
	WritePrivateProfileString( _p_stFileList->szId, "Number", itoa( _p_stFileList->lNumberOfFiles, szString, 10 ), _szIniFile );

	for ( iFile = 0; iFile < _p_stFileList->lNumberOfFiles; iFile ++)
	{
		sprintf( szString, "File%04d", iFile );
		WritePrivateProfileString( _p_stFileList->szId, szString, _p_stFileList->d_szFile[iFile], _szIniFile );
	}
	for ( ;iFile < iOldFileNumber; iFile ++)
	{
		sprintf( szString, "File%04d", iFile );
		WritePrivateProfileString( _p_stFileList->szId, szString, NULL, _szIniFile );
	}
}

/*
 ----------------------------------------------------------------------------------------
  Description   : Delete a file list config in ini file
 ----------------------------------------------------------------------------------------
 */
void fn_IniD_vDeleteFileList( char _cConfig, char *_szIniFile )
{
	char szId[20];

	sprintf( szId, "FileList-Config%02d", _cConfig );
	WritePrivateProfileString( szId, NULL, NULL, _szIniFile );
	if (_szIniFile == g_szIniFile )
	{
		g_stIniData.a_cAvailableConfig[ _cConfig ] = 0;
	}
}

/*
 ----------------------------------------------------------------------------------------
  Description   : rename a file list config in ini file
 ----------------------------------------------------------------------------------------
 */
void fn_IniD_vRenameFileList( char _cConfig, char *_szNewName, char *_szIniFile )
{
	char	szId[20];
	UINT	uiNumber;

	if (g_stIniData.a_cAvailableConfig[ _cConfig ])
	{
		sprintf( szId, "FileList-Config%02d", _cConfig );
		uiNumber = GetPrivateProfileInt( szId, "Number", 0, _szIniFile );
		if ( uiNumber == 0)
		{
			fn_IniD_vDeleteFileList( _cConfig, _szIniFile );
			return;
		}
		WritePrivateProfileString( szId, "Name", _szNewName, _szIniFile );
	}
}


/*
 ----------------------------------------------------------------------------------------
  Description   : get file list config from ini file
 ----------------------------------------------------------------------------------------
 */
BOOL fn_IniD_bGetFileList( tdstFileListConfig *_p_stFileList, char _cConfig, char *_szIniFile )
{
	int					iFile;
	char				szKey[10];
	tdstFileListConfig	stFL;

	if (_p_stFileList == NULL)
		return FALSE;

	/*
	if ( (_cConfig < 0) || (_cConfig >= g_stIniData.cNumberOfConfigs) )
		return FALSE;
	*/

	//sprintf( _p_stFileList->szId, "FileList-Config%02d", _cConfig );
	sprintf( stFL.szId, "FileList-Config%02d", _cConfig );

	/* get config name */
	GetPrivateProfileString( stFL.szId, "Name", "No name", stFL.szName, 40, _szIniFile);
	/* get number of file */
	stFL.lNumberOfFiles = GetPrivateProfileInt( stFL.szId, "Number", 0, _szIniFile);
	if (stFL.lNumberOfFiles == 0)
		return FALSE;

	/* allocate memory for pointer to file names */
	stFL.d_szFile = (char **) malloc ( stFL.lNumberOfFiles * sizeof( char *) );
	/* get each file name */
	for (iFile = 0; iFile < stFL.lNumberOfFiles; iFile ++)
	{
		stFL.d_szFile[iFile] = (char *) malloc( _MAX_PATH );
		sprintf( szKey, "File%04d", iFile );
		GetPrivateProfileString( stFL.szId, szKey, "Error", stFL.d_szFile[iFile], MAX_PATH, _szIniFile );
		if (strcmp( stFL.d_szFile[iFile], "Error") == 0)
		{
			stFL.lNumberOfFiles = iFile + 1;
			fn_IniD_vFreeFileList( &stFL );
			return FALSE;
		}
	}
	
	/* update ini data */
	fn_IniD_vFreeFileList( _p_stFileList );
	_p_stFileList->cIndex = _cConfig;
	strcpy( _p_stFileList->szId, stFL.szId );
	strcpy( _p_stFileList->szName, stFL.szName );
	_p_stFileList->lNumberOfFiles = stFL.lNumberOfFiles;
	_p_stFileList->d_szFile = stFL.d_szFile;

	return TRUE;
}

/*
 ----------------------------------------------------------------------------------------
  Set file list to default value
 ----------------------------------------------------------------------------------------
 */
void fn_IniD_vSetSingleFileList( tdstFileListConfig *_p_stFileList, char *_szFileName )
{
	if ( _p_stFileList == NULL )
		return;

	fn_IniD_vFreeFileList( _p_stFileList );
	_p_stFileList->lNumberOfFiles = 1;
	_p_stFileList->d_szFile = (char **) malloc( sizeof( char *) );
	_p_stFileList->d_szFile[0] = (char *) malloc( MAX_PATH );
	sprintf( _p_stFileList->d_szFile[0], "-R %s", _szFileName );
}



/*
 ----------------------------------------------------------------------------------------
  Description   : get index of a config from id of the config
  _szId               -> string id of config
  Returns (char ) index of config (-1 if not a valid string id
 ----------------------------------------------------------------------------------------
 */
char fn_IniD_cGetIndexFromId( char *_szId )
{
	if ( strlen( _szId ) != 17 )
		return -1;

	if ( strncmp( _szId, "FileList-Config", 15 ) != 0)
		return -1;

	if ( !isdigit( _szId[15] ) || !isdigit( _szId[16] ) )
		return -1;

	return (_szId[15] - '0') * 10 + (_szId[16] - '0');
}

/*
 ----------------------------------------------------------------------------------------
  get number of file list config
 ----------------------------------------------------------------------------------------
 */
char fn_IniD_cGetNumberOfConfig( void )
{
	char cConfig, cNbConfig = 0;
	for (cConfig = 0; cConfig < 100; cConfig ++ )
	{
		if (g_stIniData.a_cAvailableConfig[ cConfig ] )
			cNbConfig ++;
	}
	return cNbConfig;
	//return g_stIniData.cNumberOfConfigs;
}

/*
 ----------------------------------------------------------------------------------------
  get name of a config
 ----------------------------------------------------------------------------------------
 */
void fn_IniD_vGetConfigName( char _cConfig, char *_szName )
{
	char szConfigId[20];
	sprintf( szConfigId, "FileList-Config%02d", _cConfig );
	GetPrivateProfileString( szConfigId, "Name", "Error", _szName, 40, g_szIniFile );
}

/*
 ----------------------------------------------------------------------------------------
  get name of a config
 ----------------------------------------------------------------------------------------
 */
char fn_IniD_cGetConfigType( char _cConfig )
{
	char szConfigId[20];
	char szFile[ MAX_PATH ];

	sprintf( szConfigId, "FileList-Config%02d", _cConfig );
	GetPrivateProfileString( szConfigId, "File0000", "Error", szFile, MAX_PATH, g_szIniFile );

	if (strchr( szFile, '$' ) != NULL )
		return C_ConfigType_cObtain;
	
	return C_ConfigType_cUpdate;
}


/*
 ----------------------------------------------------------------------------------------
  return index of an unused config. -1 if none
 ----------------------------------------------------------------------------------------
 */
char fn_IniD_cGetAvailableConfig( void )
{
	char cConfig;

	for (cConfig = 0; cConfig < 100; cConfig ++ )
	{
		if (g_stIniData.a_cAvailableConfig[ cConfig ] == 0)
			return cConfig;
	}
	return -1;
}


/*
 =======================================================================================
  function to get/set single initial data
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  set local path in ini file
 ----------------------------------------------------------------------------------------
 */
void fn_IniD_vSetLocalPath( char *_szPath )
{
	/* set ini file in RW mode if in ReadOnly mode */
	if (_access( g_szIniFile, 2) == -1)
		_chmod ( g_szIniFile, _S_IWRITE );

	WritePrivateProfileString( "TargetPath", "DirName", _szPath, g_szIniFile );
}

/*
 ----------------------------------------------------------------------------------------
  set vss database
 ----------------------------------------------------------------------------------------
 */
void fn_IniD_vSetVssDatabase( char *_szSourceSafeIni )
{
	/* set ini file in RW mode if in ReadOnly mode */
	if (_access( g_szIniFile, 2) == -1)
		_chmod ( g_szIniFile, _S_IWRITE );

	WritePrivateProfileString( "Vss", "DataBase", _szSourceSafeIni, g_szIniFile );
}

/*
 ----------------------------------------------------------------------------------------
  set vss username
 ----------------------------------------------------------------------------------------
 */
void fn_IniD_vSetVssUserName( char *_szUserName )
{
	/* set ini file in RW mode if in ReadOnly mode */
	if (_access( g_szIniFile, 2) == -1)
		_chmod ( g_szIniFile, _S_IWRITE );

	WritePrivateProfileString( "Vss", "UserName", _szUserName, g_szIniFile );
}

/*
 ----------------------------------------------------------------------------------------
  set vss username
 ----------------------------------------------------------------------------------------
 */
void fn_IniD_vSetModifListFile( char *_szFileName )
{
	/* set ini file in RW mode if in ReadOnly mode */
	if (_access( g_szIniFile, 2) == -1)
		_chmod ( g_szIniFile, _S_IWRITE );

	WritePrivateProfileString( "Modif", "FileName", _szFileName, g_szIniFile );
}

/*
 ----------------------------------------------------------------------------------------
  Description   : set value for an update flag
  _lFlag              -> flag to set
  _bValue             -> value that flag's take
 ----------------------------------------------------------------------------------------
 */
void fn_IniD_vSetUpdateFlag( long _lFlag, BOOL _bValue )
{
	if (_bValue)
		g_stWinPref.lUpdateFlags |= _lFlag;
	else
		g_stWinPref.lUpdateFlags &= ~_lFlag;
}



/*
 ----------------------------------------------------------------------------------------
  Analyse string that describe a rect
 ----------------------------------------------------------------------------------------
 */
void fn_IniD_vAnalyseRectData( char *_szString, RECT *_p_stRect )
{
	char *p_szValue[5],  *p_szEnd;
	char cVal;

	memset( _p_stRect, 0, sizeof( RECT ) );

	if ( (p_szValue[0] = strchr(_szString, '(' )) == NULL)
		return;

	if ( (p_szValue[1] = strchr (++p_szValue[0], ',')) == NULL)
		return;
	if ( (p_szValue[2] = strchr (++p_szValue[1], ',')) == NULL)
		return;
	if ( (p_szValue[3] = strchr (++p_szValue[2], ',')) == NULL)
		return;
	p_szValue[3] ++;

	p_szValue[4] = _szString + strlen( _szString );

	for (cVal = 0; cVal < 4; cVal ++)
	{
		while ( !isdigit(*p_szValue[cVal]) )
		{
			if (p_szValue[cVal] == p_szValue[cVal+1])
				return;
			p_szValue[cVal]++;
		}
		p_szEnd = p_szValue[cVal] + 1;
		while ( isdigit(*p_szEnd))
		{
			if (p_szEnd == p_szValue[cVal+1])
				return;
			p_szEnd++;
		}
		*p_szEnd = 0;
	}

	_p_stRect->left   = atoi( p_szValue[0] );
	_p_stRect->top    = atoi( p_szValue[1] );
	_p_stRect->right  = atoi( p_szValue[2] );
	_p_stRect->bottom = atoi( p_szValue[3] );
}


/*
 =======================================================================================
  function for obtaining data information
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  saving obtaining time in ini file
 ----------------------------------------------------------------------------------------
 */
void fn_IniD_vSaveObtainingDate( void )
{
	time_t		xTimer;
	struct tm	*p_stTime;
	char		szDateString[50];

	/* 
	 * set ini file in RW mode if in ReadOnly mode 
	 */
	if (_access( g_szIniFile, 2) == -1)
		_chmod ( g_szIniFile, _S_IWRITE );

	/*
	 * Save obtaining date
	 */
	time ( &xTimer );
	p_stTime = localtime( &xTimer );
	sprintf
		( 
			szDateString, 
			"%02d/%02d/%04d %02d:%02d", 
			p_stTime->tm_mday, 
			p_stTime->tm_mon + 1, 
			p_stTime->tm_year + 1900, 
			p_stTime->tm_hour, 
			p_stTime->tm_min 
		);
	WritePrivateProfileString( "Obtaining", "Date", szDateString, g_szIniFile );
}

/*
 ----------------------------------------------------------------------------------------
  saving obtaining information in ini file
 ----------------------------------------------------------------------------------------
 */
void fn_IniD_vSaveObtainingInfo( void )
{
	//char		szValue[5];
	//long		lOldNbFiles;
	//long		lFile;
	//char		szFileKey[10];

	/* 
	 * set ini file in RW mode if in ReadOnly mode 
	 */
	if (_access( g_szIniFile, 2) == -1)
		_chmod ( g_szIniFile, _S_IWRITE );

	/*
	 * Save obtaining date
	 */
	fn_IniD_vSaveObtainingDate();
	
	/*
	 * number of files obtained
	 */
	/*
	lOldNbFiles = GetPrivateProfileInt( "Obtaining", "Number", 0, g_szIniFile);
	WritePrivateProfileString( "Obtaining", "Number", itoa(g_stIniData.stObtainConfig.lNumberOfFiles, szValue, 10 ), g_szIniFile );
	*/

	/*
	 * write obtained files
	 */
	/*
	for ( lFile = 0; lFile < g_stIniData.stObtainConfig.lNumberOfFiles; lFile ++)
	{
		sprintf( szFileKey, "File%04d", lFile);
		WritePrivateProfileString( "Obtaining", szFileKey, g_stIniData.stObtainConfig.d_szFile[lFile], g_szIniFile );
	}
	*/

	/*
	 * delete other file entry
	 */
	/*
	for ( ;lFile < lOldNbFiles; lFile ++)
	{
		sprintf( szFileKey, "File%04d", lFile );
		WritePrivateProfileString( "Obtaining", szFileKey, NULL, g_szIniFile );
	}
	*/
}

/*
 ----------------------------------------------------------------------------------------
  Free list of obtained files
 ----------------------------------------------------------------------------------------
 */
/*
void fn_IniD_vFreeObtainedFileList( void )
{
	int iFile;
	if (g_stIniData.lNumberOfObtainedFiles != 0)
	{
		for (iFile = 0; iFile < g_stIniData.lNumberOfObtainedFiles; iFile++)
			free (g_stIniData.d_szObtainedFile[iFile] );
		free ( g_stIniData.d_szObtainedFile );
		g_stIniData.lNumberOfObtainedFiles = 0;
	}
}
*/
/*
 ----------------------------------------------------------------------------------------
  Get obtaining information
 ----------------------------------------------------------------------------------------
 */
void fn_IniD_vGetObtainingInfo( void )
{
	struct tm	stTime;
	//int			iFile;
	char		szKey[50];

	/*
	 * Get last obtaining time
	 */
	GetPrivateProfileString( "Obtaining", "Date", "01/01/0100 00:00", szKey, 50, g_szIniFile );
	if (!fn_bReadDate( szKey, &stTime))
		g_oObtainingTime.SetDateTime( 100, 1, 1, 0, 0, 0);
	else
		g_oObtainingTime.SetDateTime( stTime.tm_year + 1900, stTime.tm_mon, stTime.tm_mday, stTime.tm_hour, stTime.tm_min, stTime.tm_sec );

	/*
	fn_IniD_vFreeObtainedFileList();
	g_stIniData.lNumberOfObtainedFiles = GetPrivateProfileInt( "Obtaining", "Number"  , 0, g_szIniFile );

	if (g_stIniData.lNumberOfObtainedFiles != 0)
	{
		/* allocate memory for pointer to file names */
	/*	g_stIniData.d_szObtainedFile = (char **) malloc ( g_stIniData.lNumberOfObtainedFiles * sizeof( char *) );
		/* get each file name */
	/*	for (iFile = 0; iFile < g_stIniData.lNumberOfObtainedFiles; iFile ++)
		{
			g_stIniData.d_szObtainedFile[ iFile ] = (char *) malloc (MAX_PATH);
			sprintf( szKey, "File%04d", iFile );
			GetPrivateProfileString( "Obtaining", szKey, "Error", g_stIniData.d_szObtainedFile[iFile], MAX_PATH, g_szIniFile );
			if (strcmp( g_stIniData.d_szObtainedFile[iFile], "Error") == 0)
			{
				g_stIniData.lNumberOfObtainedFiles = iFile + 1;
				fn_IniD_vFreeObtainedFileList();
				g_oObtainingTime.SetDate( 100, 1, 1 );
				MessageBox (NULL, "An error occurs while analysing last obtaining data\r\nYou must obtain again", "Error", MB_ICONASTERISK );
				return;
			}
		}
	}
	*/
}

/*
 ----------------------------------------------------------------------------------------
	free list of file that are to be obtained
 ----------------------------------------------------------------------------------------
 */
/*
void fn_IniD_vFreeFileListToObtain( void )
{
	int iFile;
	if (g_stIniData.lNumberOfFilesToObtain != 0)
	{
		for (iFile = 0; iFile < g_stIniData.lNumberOfFilesToObtain; iFile++)
			free (g_stIniData.d_szFileToObtain[iFile] );
		free ( g_stIniData.d_szFileToObtain );
		g_stIniData.lNumberOfFilesToObtain = 0;
	}
}
*/

/*
 =======================================================================================
	function for windows preference data 
 =======================================================================================
 */
void fn_IniD_vAnalyseBatchObtainString( char *szString )
{
	char *p_cCur = szString;
	
	g_stWinPref.lElapseTime		= 60;
	g_stWinPref.bUseTimer		= FALSE;
	g_stWinPref.cRelativeDay	= 0;
	g_stWinPref.cHour			= 22;
	g_stWinPref.cMinute			= 0;	
	g_stWinPref.bWaitToBeAlone	= TRUE;

	/*
	 * reading elapsed time
	 */
	while ( !isdigit( *p_cCur ) && (*p_cCur != 0) )
		p_cCur++;
	if (*p_cCur == 0) return;
	g_stWinPref.lElapseTime = 0;
	while ( isdigit( *p_cCur ) )
		g_stWinPref.lElapseTime = g_stWinPref.lElapseTime * 10 + (*p_cCur++ - '0');
	if (g_stWinPref.lElapseTime > 600) g_stWinPref.lElapseTime = 600;
	/*
	 * Reading timer
	 */
	while ( !isalpha( *p_cCur ) && (*p_cCur != 0) )
		p_cCur++;
	if (*p_cCur == 0) return;
	if (strnicmp( p_cCur, "TRUE", 4) == 0)
		g_stWinPref.bUseTimer = TRUE;
	/*
	 * reading relative day
	 */
	while ( !isdigit( *p_cCur ) && (*p_cCur != 0) )
		p_cCur++;
	if (*p_cCur == 0) return;
	g_stWinPref.cRelativeDay = *p_cCur++ - '0';
	if ( g_stWinPref.cRelativeDay > 2 )
		g_stWinPref.cRelativeDay = 0;
	/*
	 * reading hour
	 */
	while ( !isdigit( *p_cCur ) && (*p_cCur != 0) )
		p_cCur++;
	if (*p_cCur == 0) return;
	g_stWinPref.cHour = 0;
	while ( isdigit( *p_cCur ) )
		g_stWinPref.cHour = g_stWinPref.cHour * 10 + (*p_cCur++ - '0');
	if (g_stWinPref.cHour > 23) g_stWinPref.cHour = 23;
	/*
	 * reading minute
	 */
	while ( !isdigit( *p_cCur ) && (*p_cCur != 0) )
		p_cCur++;
	if (*p_cCur == 0) return;
	g_stWinPref.cMinute = 0;
	while ( isdigit( *p_cCur ) )
		g_stWinPref.cMinute = g_stWinPref.cMinute * 10 + (*p_cCur++ - '0');
	if (g_stWinPref.cMinute > 59) g_stWinPref.cMinute = 59;
	/*
	 * reading bWaitToBeAlone flag
	 */
	while ( !isalpha( *p_cCur ) && (*p_cCur != 0) )
		p_cCur++;
	if (*p_cCur == 0) return;
	if (strnicmp( p_cCur, "FALSE", 5) == 0)
		g_stWinPref.bWaitToBeAlone = FALSE;
}

/*
 ----------------------------------------------------------------------------------------
  Description   : get position and size of windows
 ----------------------------------------------------------------------------------------
 */
void fn_IniD_vGetWindowPreference( void )
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	BOOL bValue;
	char szString[100];
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	/* main window */
	GetPrivateProfileString( "WinPref", "Main", "", szString, 100, g_szIniFile );
	fn_IniD_vAnalyseRectData( szString, &g_stWinPref.stMainPos );
	M_vCheckRectSize( (&g_stWinPref.stMainPos), C_iMainMinWidth, C_iMainMinHeight );
	/* file list window */
	GetPrivateProfileString( "WinPref", "File", "", szString, 100, g_szIniFile );
	fn_IniD_vAnalyseRectData( szString, &g_stWinPref.stFilePos );
	M_vCheckRectSize( (&g_stWinPref.stFilePos), C_iFileMinWidth, C_iFileMinHeight );
	/* modif list window */
	GetPrivateProfileString( "WinPref", "Modif", "", szString, 100, g_szIniFile );
	fn_IniD_vAnalyseRectData( szString, &g_stWinPref.stModifPos );
	M_vCheckRectSize( (&g_stWinPref.stModifPos), C_iModifMinWidth, C_iModifMinHeight );
	/* conflict window */
	GetPrivateProfileString( "WinPref", "Conflict", "", szString, 100, g_szIniFile );
	fn_IniD_vAnalyseRectData( szString, &g_stWinPref.stConflictPos );
	M_vCheckRectSize( (&g_stWinPref.stConflictPos), C_iConflictMinWidth, C_iConflictMinHeight );
	/* Update with config window */
	GetPrivateProfileString( "WinPref", "Conflict", "", szString, 100, g_szIniFile );
	fn_IniD_vAnalyseRectData( szString, &g_stWinPref.stUpdateWithConfigPos);
	M_vCheckRectSize( (&g_stWinPref.stUpdateWithConfigPos), C_iUpdateWithConfigMinWidth, C_iUpdateWithConfigMinHeight );

	/* update options */
	bValue = (GetPrivateProfileInt( "WinPref", "ObtainAfterUpdate", 1, g_szIniFile ) != 0);
	fn_IniD_vSetUpdateFlag( C_UpdateOption_lObtainAfter, bValue );
	bValue = (GetPrivateProfileInt( "WinPref", "ConfirmObtainAfterUpdate", 1, g_szIniFile ) != 0);
	fn_IniD_vSetUpdateFlag( C_UpdateOption_lConfirmObtainAfter, bValue );
	bValue = (GetPrivateProfileInt( "WinPref", "ForceUpdate", 0, g_szIniFile ) != 0);
	fn_IniD_vSetUpdateFlag( C_UpdateOption_lForce, bValue);
	bValue = (GetPrivateProfileInt( "WinPref", "ConfirmForceUpdate", 1, g_szIniFile ) != 0);
	fn_IniD_vSetUpdateFlag( C_UpdateOption_lConfirmForce, bValue);
	bValue = (GetPrivateProfileInt( "WinPref", "ShowDifferences", 0, g_szIniFile ) != 0);
	fn_IniD_vSetUpdateFlag( C_UpdateOption_lShowDifferences, bValue);

	/* batch obtain option */
	GetPrivateProfileString( "WinPref", "BatchObtain", "", szString, 100, g_szIniFile );
	fn_IniD_vAnalyseBatchObtainString( szString );
}

/*
 ----------------------------------------------------------------------------------------
  Description   : write position and size of windows
 ----------------------------------------------------------------------------------------
 */
void fn_IniD_vWriteWindowPreference( void )
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	char szValue[50];
	BOOL bValue;
	RECT *p_stRect;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	/* set ini file in RW mode if in ReadOnly mode */
	if (_access( g_szIniFile, 2) == -1)
		_chmod ( g_szIniFile, _S_IWRITE );

	/* main window */
	p_stRect = &g_stWinPref.stMainPos;
	sprintf( szValue, "(%4d,%4d,%4d,%4d)", p_stRect->left, p_stRect->top, p_stRect->right, p_stRect->bottom );
	WritePrivateProfileString( "WinPref", "Main    ", szValue, g_szIniFile );
	/* file list window */
	p_stRect = &g_stWinPref.stFilePos;
	sprintf( szValue, "(%4d,%4d,%4d,%4d)", p_stRect->left, p_stRect->top, p_stRect->right, p_stRect->bottom );
	WritePrivateProfileString( "WinPref", "File    ", szValue, g_szIniFile );	
	/* modif list window */
	p_stRect = &g_stWinPref.stModifPos;
	sprintf( szValue, "(%4d,%4d,%4d,%4d)", p_stRect->left, p_stRect->top, p_stRect->right, p_stRect->bottom );
	WritePrivateProfileString( "WinPref", "Modif   ", szValue, g_szIniFile );
	/* conflict window */
	p_stRect = &g_stWinPref.stConflictPos;
	sprintf( szValue, "(%4d,%4d,%4d,%4d)", p_stRect->left, p_stRect->top, p_stRect->right, p_stRect->bottom );
	WritePrivateProfileString( "WinPref", "Conflict", szValue, g_szIniFile );
	/* Update with config window */
	p_stRect = &g_stWinPref.stUpdateWithConfigPos;
	sprintf( szValue, "(%4d,%4d,%4d,%4d)", p_stRect->left, p_stRect->top, p_stRect->right, p_stRect->bottom );
	WritePrivateProfileString( "WinPref", "Conflict", szValue, g_szIniFile );

	/* update options */
	bValue = g_stWinPref.lUpdateFlags & C_UpdateOption_lObtainAfter;
	WritePrivateProfileString( "WinPref", "ObtainAfterUpdate", bValue ? "1" : "0", g_szIniFile );
	bValue = g_stWinPref.lUpdateFlags & C_UpdateOption_lConfirmObtainAfter;
	WritePrivateProfileString( "WinPref", "ConfirmObtainAfterUpdate", bValue ? "1" : "0", g_szIniFile );
	bValue = g_stWinPref.lUpdateFlags & C_UpdateOption_lForce;
	WritePrivateProfileString( "WinPref", "ForceUpdate", bValue ? "1" : "0", g_szIniFile );
	bValue = g_stWinPref.lUpdateFlags & C_UpdateOption_lConfirmForce;
	WritePrivateProfileString( "WinPref", "ConfirmForceUpdate", bValue ? "1" : "0", g_szIniFile );
	bValue = g_stWinPref.lUpdateFlags & C_UpdateOption_lShowDifferences;
	WritePrivateProfileString( "WinPref", "ShowDifferences", bValue ? "1" : "0", g_szIniFile );

	/* batch obtain options */
	sprintf
		( 
			szValue, 
			"(%d,%s,%d,%02d:%02d, %s)", 
			g_stWinPref.lElapseTime,
			g_stWinPref.bUseTimer ? "TRUE" : "FALSE",
			g_stWinPref.cRelativeDay,
			g_stWinPref.cHour, 
			g_stWinPref.cMinute,
			g_stWinPref.bWaitToBeAlone ? "TRUE" : "FALSE"
		);
	WritePrivateProfileString( "WinPref", "BatchObtain", szValue, g_szIniFile );
}



/*
 *=======================================================================================
 * function for all initial data
 *=======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  transform ini file to keep file compatible
 ----------------------------------------------------------------------------------------
 */
void fn_IniD_vTransformIniFileToBeCompatible( void )
{
	/* erase old section and entry for window position */
	WritePrivateProfileString( "WinPref", "Main-left", NULL, g_szIniFile );
	WritePrivateProfileString( "WinPref", "Main-top", NULL, g_szIniFile );
	WritePrivateProfileString( "WinPref", "Main-right", NULL, g_szIniFile );
	WritePrivateProfileString( "WinPref", "Main-bottom", NULL, g_szIniFile );
	WritePrivateProfileString( "WinPref", "File-left", NULL, g_szIniFile );
	WritePrivateProfileString( "WinPref", "File-top", NULL, g_szIniFile );
	WritePrivateProfileString( "WinPref", "File-right", NULL, g_szIniFile );
	WritePrivateProfileString( "WinPref", "File-bottom", NULL, g_szIniFile );
	WritePrivateProfileString( "WinPref", "Modif-left", NULL, g_szIniFile );
	WritePrivateProfileString( "WinPref", "Modif-top", NULL, g_szIniFile );
	WritePrivateProfileString( "WinPref", "Modif-right", NULL, g_szIniFile );
	WritePrivateProfileString( "WinPref", "Modif-bottom", NULL, g_szIniFile );
	/* erase old obtaining/number and files entries */
	int iNbFiles, iFile;
	iNbFiles = GetPrivateProfileInt( "Obtaining", "Number", 0, g_szIniFile );
	if (iNbFiles)
	{
		char szFile[10];
		WritePrivateProfileString( "Obtaining", "Number", NULL, g_szIniFile );
		for (iFile = 0; iFile < iNbFiles; iFile ++)
		{
			sprintf( szFile, "File%04d", iFile );
			WritePrivateProfileString( "Obtaining", szFile, NULL, g_szIniFile );
		}
	}
	/* get old date */
	int iDay, iMonth, iYear, iHour, iMin, iSec;
	iDay=	GetPrivateProfileInt( "Obtaining", "day"  , 1, g_szIniFile );
	iMonth= GetPrivateProfileInt( "Obtaining", "month", 1, g_szIniFile );
	iYear=	GetPrivateProfileInt( "Obtaining", "year" , 100, g_szIniFile );
	iHour=	GetPrivateProfileInt( "Obtaining", "hour" , 0, g_szIniFile );
	iMin=	GetPrivateProfileInt( "Obtaining", "min"  , 0, g_szIniFile );
	iSec=	GetPrivateProfileInt( "Obtaining", "sec"  , 0, g_szIniFile );
	if (iYear != 100)
	{
		char szDateString[50];
		sprintf( szDateString, "%02d/%02d/%04d %02d:%02d", iDay, iMonth, iYear, iHour, iMin );
		WritePrivateProfileString( "Obtaining", "Date", szDateString, g_szIniFile );
	}
	WritePrivateProfileString( "Obtaining", "day"  , NULL, g_szIniFile );
	WritePrivateProfileString( "Obtaining", "month", NULL, g_szIniFile );
	WritePrivateProfileString( "Obtaining", "year" , NULL, g_szIniFile );
	WritePrivateProfileString( "Obtaining", "hour" , NULL, g_szIniFile );
	WritePrivateProfileString( "Obtaining", "min"  , NULL, g_szIniFile );
	WritePrivateProfileString( "Obtaining", "sec"  , NULL, g_szIniFile );
	/*
	 * transform "FileList" key to "ObtainFileList" key
	 */
	char szId[20];
	GetPrivateProfileString( "Vss", "FileList", "", szId, 20, g_szIniFile );
	if ( *szId != 0)
	{
		WritePrivateProfileString( "Vss", "ObtainFileList", szId, g_szIniFile );
		WritePrivateProfileString( "Vss", "FileList", NULL, g_szIniFile );
	}
}


/*
 ----------------------------------------------------------------------------------------
  Description   : read ini data to fill inidata structure
					and set additional ini data
  _bFirst             -> indicate that it's the first initialisation
 ----------------------------------------------------------------------------------------
 */
void fn_IniD_vGetAllFromIniFile( BOOL _bFirst )
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	char				szConfigId[20];
	char				szConfigName[40];
	tdstFileListConfig	*p_stConfig;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	
	if (_bFirst)
	{
		/*
		 * Build ini file
		 */
		GetCurrentDirectory( MAX_PATH, g_szIniFile );
		if (g_szIniFile[strlen(g_szIniFile) - 1] != '\\')
			strcat( g_szIniFile, "\\");
		strcat( g_szIniFile, C_szIniFile );
		fn_IniD_vTransformIniFileToBeCompatible();

		fn_IniD_vGetWindowPreference();

		/*
		 * set all ini data with default data
		 */
		memcpy( &g_stIniData, &g_stDefaultData, sizeof( tdstIniData ) );
		g_stIniData.p_oObtainingTime = &g_oObtainingTime;

		/* get temp path */
		DWORD dwLength;
		dwLength = GetTempPath( MAX_PATH, g_stIniData.szTempPath);
		if (g_stIniData.szTempPath[ dwLength - 1 ] == '\\' )
			g_stIniData.szTempPath[ dwLength - 1 ] = 0;

		/* retrieve number of config */
		for ( char cConfig = 0; cConfig < 100; cConfig ++)
		{
			sprintf( szConfigId, "FileList-Config%02d", cConfig);
			GetPrivateProfileString( szConfigId, "Name", "Error", szConfigName, 40, g_szIniFile );
			g_stIniData.a_cAvailableConfig[ cConfig ] = strcmp(szConfigName, "Error") == 0 ? 0 : 1;
		}
	}

	GetPrivateProfileString( "TargetPath", "DirName", g_stDefaultData.szLocalPath, g_stIniData.szLocalPath, MAX_PATH, g_szIniFile );
	/*
	 * Get Vss Data
	 */
	GetPrivateProfileString( "Vss", "DataBase", g_stDefaultData.szVssDatabase, g_stIniData.szVssDatabase, MAX_PATH, g_szIniFile );
	GetPrivateProfileString( "Vss", "UserName", g_stDefaultData.szVssUserName, g_stIniData.szVssUserName, MAX_PATH, g_szIniFile );
	GetPrivateProfileString( "Vss", "DataRoot", g_stDefaultData.szVssPath, g_stIniData.szVssPath, MAX_PATH, g_szIniFile );
	GetPrivateProfileString( "Vss", "InUpdate", g_stDefaultData.szInUpdateSem, g_stIniData.szInUpdateSem, MAX_PATH, g_szIniFile );
	GetPrivateProfileString( "Vss", "InObtain", g_stDefaultData.szInObtainSem, g_stIniData.szInObtainSem, MAX_PATH, g_szIniFile );
	/*
	 * get obtain file list Id
	 */
	p_stConfig = &g_stIniData.stObtainConfig;
	GetPrivateProfileString( "Vss", p_stConfig->szKey, g_stDefaultData.stObtainConfig.szId, p_stConfig->szId, 20, g_szIniFile );
	p_stConfig->cIndex = fn_IniD_cGetIndexFromId( p_stConfig->szId );
	if ( (p_stConfig->cIndex == -1) || !fn_IniD_bGetFileList( p_stConfig, p_stConfig->cIndex, g_szIniFile ) )
	{
		p_stConfig->cIndex = -1;
		fn_IniD_vSetSingleFileList( p_stConfig, g_stIniData.szVssPath );
	}


	/*
	 * get update file list Id
	 */
	p_stConfig = &g_stIniData.stUpdateConfig;
	GetPrivateProfileString( "Vss", p_stConfig->szKey, g_stDefaultData.stUpdateConfig.szId, p_stConfig->szId, 20, g_szIniFile );
	p_stConfig->cIndex = fn_IniD_cGetIndexFromId( p_stConfig->szId );
	if (p_stConfig->cIndex != -1)
		fn_IniD_bGetFileList( p_stConfig, p_stConfig->cIndex, g_szIniFile );

	/*
	 * get modif file name
	 */
	GetPrivateProfileString( "Modif", "FileName", g_stDefaultData.szModifFile, g_stIniData.szModifFile, MAX_PATH, g_szIniFile );

	/* set local path */
	if (strcmp( g_stIniData.szLocalPath, g_stDefaultData.szLocalPath) == 0)
		strcpy( g_stIniData.szLocalPath, g_stIniData.szTempPath);

	/* set full name for inupdate/inobtain vss and local file */
	sprintf( g_stIniData.szVssInUpdate, "%s\\%s", g_stIniData.szVssPath, g_stIniData.szInUpdateSem );
	sprintf( g_stIniData.szLocalInUpdate, "%s\\%s", g_stIniData.szTempPath, g_stIniData.szInUpdateSem );
	sprintf( g_stIniData.szVssInObtain, "%s\\%s", g_stIniData.szVssPath, g_stIniData.szInObtainSem );
	sprintf( g_stIniData.szLocalInObtain, "%s\\%s", g_stIniData.szTempPath, g_stIniData.szInObtainSem );

	/* get last obtaining time */
	fn_IniD_vGetObtainingInfo();
}
