/*
 =======================================================================================
  Name        : VssFunct.cpp
 
  Author      : vincent lhullier            Date :27/07/97
 
  Description : Manage vss tree, file of list to obtain
 =======================================================================================
  Modification -> Author :                  Date :
  Description :
 =======================================================================================
 */

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include "stdafx.h"

#include "TimeFunc.h"
#include "Tree_Fct.h"
#include "IniData.h"
#include "vss5_Fct.h"

#include <io.h>
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

/*
 =======================================================================================
	GLOBALS 
 =======================================================================================
 */

char g_szFullName[MAX_PATH];
tdstProject *g_p_stVssRootProject = NULL;
tdstProject *g_p_stLocalRootProject = NULL;
char **gs_d_szFile;
char **gs_d_szProj;


/*
 =======================================================================================
	VSS FUNCTIONS
 =======================================================================================
 */

/*
 ---------------------------------------------------------------------------------------
  fill a tdstProject structure with name and describing an empty project
 ---------------------------------------------------------------------------------------
 */
void fn_Tree_vInitProject( tdstProject *_p_stProj, char *_szName )
{
	_p_stProj->szName = (char *) malloc( strlen(_szName) + 1 );
	strcpy( _p_stProj->szName, _szName );
	_p_stProj->bGet = FALSE;
	_p_stProj->bRecurse = FALSE;
	_p_stProj->lNumberOfSubProjects = 0;
	_p_stProj->d_stSubProject = NULL;
	_p_stProj->lNumberOfFiles = 0;
	_p_stProj->d_stFile = NULL;
}

/*
 ---------------------------------------------------------------------------------------
  fill a tdstProject structure with pointer name and describing an empty project
 ---------------------------------------------------------------------------------------
 */
void fn_Tree_vInitProjectWithPointerName( tdstProject *_p_stProj, char *_szName )
{
	_p_stProj->szName = _szName;
	_p_stProj->bGet = FALSE;
	_p_stProj->bRecurse = FALSE;
	_p_stProj->lNumberOfSubProjects = 0;
	_p_stProj->d_stSubProject = NULL;
	_p_stProj->lNumberOfFiles = 0;
	_p_stProj->d_stFile = NULL;
}

/*
 ---------------------------------------------------------------------------------------
  fill a tdstFile structure with name
 ---------------------------------------------------------------------------------------
 */
void fn_Tree_vInitFile( tdstFile *_p_stFile, char *_szName )
{
	_p_stFile->szName = (char *) malloc( strlen(_szName) + 1 );
	strcpy( _p_stFile->szName, _szName );
	_p_stFile->bGet = FALSE;
}

/*
 ---------------------------------------------------------------------------------------
  fill a tdstFile structure with pointer name
 ---------------------------------------------------------------------------------------
 */
void fn_Tree_vInitFileWithPointerName( tdstFile *_p_stFile, char *_szName )
{
	_p_stFile->szName = _szName;
	_p_stFile->bGet = FALSE;
}

/*
 ---------------------------------------------------------------------------------------
  retrieve a subproject
 ---------------------------------------------------------------------------------------
 */
tdstProject *fn_Tree_p_stGetProject( tdstProject *_p_stInProj, char *_szName )
{
	char			*p_cCur;
	char			*p_cNext;
	tdstProject		*p_stCurProj;
	long			lSubProj;

	if (_p_stInProj == NULL)
		return NULL;

	p_cCur = _szName;
	while (1)
	{
		p_cCur = strchr( p_cCur, '/' );
		if (p_cCur == NULL)
			break;
		*p_cCur = '\\';
	}


	if ( strnicmp( _szName, _p_stInProj->szName, strlen( _p_stInProj->szName )) != 0)
		return NULL;

	p_cCur = _szName + strlen( _p_stInProj->szName );
	p_stCurProj = _p_stInProj;

	while (*p_cCur != 0)
	{
		p_cCur ++;
		p_cNext = strchr(p_cCur, '\\');
		if (p_cNext != NULL) *p_cNext = 0;

		for (lSubProj = 0; lSubProj < p_stCurProj->lNumberOfSubProjects; lSubProj++)
		{
			if (stricmp( p_stCurProj->d_stSubProject[lSubProj].szName, p_cCur) == 0)
				break;
		}
		if (lSubProj == p_stCurProj->lNumberOfSubProjects)
			return NULL;

		p_stCurProj = &p_stCurProj->d_stSubProject[lSubProj];
		
		p_cCur += strlen( p_cCur );
		if (p_cNext != NULL) *p_cNext = '\\';
	}
	return p_stCurProj;
}

/*
 ---------------------------------------------------------------------------------------
  retrieve a file with name
 ---------------------------------------------------------------------------------------
 */
tdstFile *fn_Tree_p_stGetFile( tdstProject *_p_stInProj, char *_szName )
{
	tdstProject	*p_stProj;
	tdstFile	*p_stFile;
	char		*p_szShortName;
	long		lFile = 0;

	p_szShortName = strrchr( _szName, '\\' );
	*p_szShortName++ = 0;
	p_stProj = fn_Tree_p_stGetProject( _p_stInProj, _szName );
	*(p_szShortName - 1) = '\\';

	if ( p_stProj == NULL)
		return NULL;

	for ( p_stFile = p_stProj->d_stFile; lFile < p_stProj->lNumberOfFiles; lFile++, p_stFile ++)
	{
		if (stricmp( p_szShortName, p_stFile->szName) == 0)
			return p_stFile;
	}

	return NULL;
}


/*
 ---------------------------------------------------------------------------------------
  free a project information
 ---------------------------------------------------------------------------------------
 */
void fn_Tree_vFreeProject( tdstProject *_p_stProj, BOOL _bDelete )
{
	long lIndex;
	/* free files */
	if (_p_stProj == NULL)
		return;

	if (_p_stProj->d_stFile)
	{
		for (lIndex = 0; lIndex < _p_stProj->lNumberOfFiles; lIndex ++)
			free ( _p_stProj->d_stFile[lIndex].szName );
		free (_p_stProj->d_stFile );
		_p_stProj->d_stFile = NULL;
		_p_stProj->lNumberOfFiles = 0;
	}

	/* free sub project */
	if (_p_stProj->d_stSubProject )
	{
		for (lIndex = 0; lIndex < _p_stProj->lNumberOfSubProjects; lIndex ++)
			fn_Tree_vFreeProject( &_p_stProj->d_stSubProject[lIndex], TRUE );
		free (_p_stProj->d_stSubProject );
		_p_stProj->d_stSubProject = NULL;
		_p_stProj->lNumberOfSubProjects = 0;
	}

	/* free project */
	if (_bDelete)
		free ( _p_stProj->szName );
}

/*
 ---------------------------------------------------------------------------------------
  free a project information tree
 ---------------------------------------------------------------------------------------
 */
void fn_Tree_vFreeProjectTree( tdstProject *_p_stProj, BOOL _bDelete )
{
	fn_Tree_vFreeProject( _p_stProj, _bDelete );
	if (_bDelete)
	{
		free ( _p_stProj );
		_p_stProj = NULL;
	}
}


/*
 ----------------------------------------------------------------------------------------
  Description   : free list of file in a vss project structure
 ----------------------------------------------------------------------------------------
 */
void fn_Tree_vFreeProjectFileList( tdstProject *_p_stProj )
{
	long lIndex;

	if (_p_stProj->d_stFile)
	{
		for (lIndex = 0; lIndex < _p_stProj->lNumberOfFiles; lIndex ++)
			free ( _p_stProj->d_stFile[lIndex].szName );
		free (_p_stProj->d_stFile );
		_p_stProj->d_stFile = NULL;
		_p_stProj->lNumberOfFiles = 0;
	}
}

/*
 ---------------------------------------------------------------------------------------
  set all vss project to not obtain
 ---------------------------------------------------------------------------------------
 */
void fn_Tree_vGetNothing( tdstProject *_p_stProj)
{
	long			lSubProj;
	long			lFile = 0;
	tdstFile		*p_stFile = _p_stProj->d_stFile;

	/*
	 * dont obtain current project
	 */
	_p_stProj->bGet = FALSE;
	_p_stProj->bRecurse = FALSE;
	/* 
	 * dont obtain files
	 */
	for (; lFile < _p_stProj->lNumberOfFiles; lFile++, p_stFile ++)
	{
		p_stFile->bGet = FALSE;
	}
	/*
	 * dont obtain sub project
	 */
	for (lSubProj = 0; lSubProj < _p_stProj->lNumberOfSubProjects; lSubProj ++)
		fn_Tree_vGetNothing( &_p_stProj->d_stSubProject[lSubProj] );
}

/*
 ---------------------------------------------------------------------------------------
  refresh obtaining state for vss tree
 ---------------------------------------------------------------------------------------
 */
void fn_Tree_vRefreshWithFileList( tdstProject *_p_stProj, tdstFileListConfig *_p_stFileList )
{
	int				iFile;
	char			*szFileName;
	tdstProject		*p_stSubProj;
	tdstFile		*p_stFile;
	BOOL			bRecurse;
	BOOL			bFile;

	fn_Tree_vGetNothing( _p_stProj );

	for (iFile = 0; iFile < _p_stFileList->lNumberOfFiles; iFile ++)
	{
		szFileName = _p_stFileList->d_szFile[iFile];
		
		if (*szFileName == '-')
		{
			switch( *(szFileName + 1) )
			{
				case 'R':
					bRecurse = TRUE;
					bFile = FALSE;
					break;
				case 'F':
					bRecurse = FALSE;
					bFile = TRUE;
					break;
				default:
					bRecurse = FALSE;
					bFile = FALSE;
			}
			szFileName += 3;
		}
		else
		{
			bRecurse = FALSE;
			bFile = FALSE;
		}

		if (bFile)
		{
			if ( (p_stFile = fn_Tree_p_stGetFile( _p_stProj, szFileName ) ) != NULL)
				p_stFile->bGet = TRUE;
		}
		else
		{
			if ( (p_stSubProj = fn_Tree_p_stGetProject( _p_stProj, szFileName ) ) != NULL)
			{
				p_stSubProj->bGet = TRUE;
				p_stSubProj->bRecurse = bRecurse;
			}
		}
	}
}

/*
 ---------------------------------------------------------------------------------------
  count recursively number of file to get all folder name the user want to obtain
 ---------------------------------------------------------------------------------------
 */
void fn_Tree_vGetNumberOfFilesOrProjectsToGet( tdstProject *_p_stProj, long *_p_lNbFiles )
{
	long		lSubProj;
	long		lFile;
	tdstFile	*p_stFile;

	if (_p_stProj->bGet)
	{
		(*_p_lNbFiles)++;
		if (_p_stProj->bRecurse)
			return;
	}
	else
	{
		for (lFile = 0, p_stFile = _p_stProj->d_stFile; lFile < _p_stProj->lNumberOfFiles; lFile++, p_stFile++ )
			if (p_stFile->bGet)
				(*_p_lNbFiles) ++;
	}

	for (lSubProj = 0; lSubProj < _p_stProj->lNumberOfSubProjects; lSubProj ++)
		fn_Tree_vGetNumberOfFilesOrProjectsToGet( &_p_stProj->d_stSubProject[lSubProj], _p_lNbFiles );
}

/*
 ---------------------------------------------------------------------------------------
  write recursively file to obtain in given array of string
 ---------------------------------------------------------------------------------------
 */
void fn_Tree_vGetFilesOrProjectToGet( tdstProject *_p_stProj, long *_p_lNbFiles, char **_d_szFile )
{
	long		lSubProj;
	long		lFile;
	tdstFile	*p_stFile;

	if (_p_stProj->bGet)
	{
		strcpy ( _d_szFile[ *_p_lNbFiles ], (_p_stProj->bRecurse)?"-R ":"");
		strcat( _d_szFile[ (*_p_lNbFiles)++ ], g_szFullName );
		if (_p_stProj->bRecurse)
			return;
	}
	else
	{
		for (lFile = 0, p_stFile = _p_stProj->d_stFile; lFile < _p_stProj->lNumberOfFiles; lFile++, p_stFile++ )
			if (p_stFile->bGet)
				sprintf(_d_szFile[ (*_p_lNbFiles)++ ], "-F %s\\%s", g_szFullName, p_stFile->szName );
	}
	for (lSubProj = 0; lSubProj < _p_stProj->lNumberOfSubProjects; lSubProj ++)
	{
		strcat( g_szFullName, "\\");
		strcat( g_szFullName, _p_stProj->d_stSubProject[lSubProj].szName );
		fn_Tree_vGetFilesOrProjectToGet( &_p_stProj->d_stSubProject[lSubProj], _p_lNbFiles, _d_szFile );
		*strrchr( g_szFullName, '\\' ) = 0;
	}
}

/*
 ---------------------------------------------------------------------------------------
  count recursively all files to obtain (not project)
 ---------------------------------------------------------------------------------------
 */
void fn_Tree_vGetNumberOfFilesToGet( tdstProject *_p_stProj, long *_p_lNbFiles, BOOL _bAll )
{
	long		lFile = 0;
	tdstProject	*p_stSubProj = _p_stProj->d_stSubProject;
	tdstFile	*p_stFile = _p_stProj->d_stFile;

	/*
	 * add number of obtained file in current project
	 */
	if (_p_stProj->bGet || _bAll)
		(*_p_lNbFiles) += _p_stProj->lNumberOfFiles;
	else
	{
		for ( ; lFile < _p_stProj->lNumberOfFiles; p_stFile++, lFile++ )
			if (p_stFile->bGet)
				(*_p_lNbFiles)++;
	}

	/*
	 * call recursively function for each sub project
	 */
	for (lFile = 0; lFile < _p_stProj->lNumberOfSubProjects; lFile++, p_stSubProj++)
	{
		fn_Tree_vGetNumberOfFilesToGet( p_stSubProj, _p_lNbFiles, (_p_stProj->bRecurse) || _bAll );
	}
}

/*
 ---------------------------------------------------------------------------------------
  write recursively file to obtain (no project) in given array of string
 ---------------------------------------------------------------------------------------
 */
void fn_Tree_vGetFilesToGet( tdstProject *_p_stProj, long *_p_lNbFiles, char **_d_szFile, BOOL _bAll )
{
	long		lFile = 0;
	tdstProject	*p_stSubProj = _p_stProj->d_stSubProject;
	tdstFile	*p_stFile = _p_stProj->d_stFile;

	for ( ; lFile < _p_stProj->lNumberOfFiles; lFile++, p_stFile ++)
	{
		if ( _bAll || (_p_stProj->bGet) || (p_stFile->bGet) )
			sprintf( _d_szFile[ (*_p_lNbFiles)++ ], "-F %s\\%s", g_szFullName, p_stFile->szName ); 
	}

	for (lFile = 0; lFile < _p_stProj->lNumberOfSubProjects; lFile ++, p_stSubProj++)
	{
		strcat( g_szFullName, "\\");
		strcat( g_szFullName, p_stSubProj->szName );
		fn_Tree_vGetFilesToGet( p_stSubProj, _p_lNbFiles, _d_szFile, _bAll || _p_stProj->bRecurse );
		*strrchr( g_szFullName, '\\' ) = 0;
	}

}


/*
 ----------------------------------------------------------------------------------------
  Description   : build list of files to get
  _p_stProj           -> project to look in
  **_ppp_szFile       -> pointer on a list that will be filled
  Returns (long ) number of files in list
 ----------------------------------------------------------------------------------------
 */
long fn_TREE_lBuildListOfFilesToGet( tdstProject *_p_stProj, char ***_ppp_szFile )
{
	long lNbFiles, lFile;

	lNbFiles = 0;
	fn_Tree_vGetNumberOfFilesToGet( _p_stProj, &lNbFiles, FALSE );

	if (lNbFiles == 0)
		return 0;
	
	*_ppp_szFile = (char **) malloc (lNbFiles * sizeof ( char *) );
	for (lFile = 0; lFile < lNbFiles; lFile ++)
		(*_ppp_szFile)[lFile] = (char *) malloc ( MAX_PATH );

	strcpy (g_szFullName, _p_stProj->szName );
	lNbFiles = 0;
	fn_Tree_vGetFilesToGet( _p_stProj, &lNbFiles, *_ppp_szFile, FALSE );

	return lNbFiles;
}


/*
 ----------------------------------------------------------------------------------------
  Description   : free a list of files previously build with fn_TREE_lBuildListOfFilesToGet
					function
  _lNumberOfFiles     -> number of files in list
  *_pp_szFile         -> list of file
 ----------------------------------------------------------------------------------------
 */
void fn_TREE_vFreeListOfFilesToGet( long _lNumberOfFiles, char **_pp_szFile )
{
	long lFile;

	if (_lNumberOfFiles == 0)
		return;

	for (lFile = 0; lFile < _lNumberOfFiles; lFile ++)
		free( _pp_szFile[lFile] );
	free( _pp_szFile );
}


/*
 ---------------------------------------------------------------------------------------
  set new list of file from analysis of vss tree obtaining state
 ---------------------------------------------------------------------------------------
 */
BOOL fn_TREE_bGetFileList( tdstProject *_p_stProj, tdstFileListConfig *_p_stFileList, char _cConfig, char *_szFileListName )
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	char			szFileListId[20];
	long			lNbFiles;
	char			**d_szFile;
	long			lFile;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	sprintf(szFileListId, "FileList-Config%02d", _cConfig);

	lNbFiles = 0;
	fn_Tree_vGetNumberOfFilesOrProjectsToGet( _p_stProj, &lNbFiles );
	if (lNbFiles == 0)
		return FALSE;

	d_szFile = (char **) malloc (lNbFiles * sizeof ( char *) );
	for (lFile = 0; lFile < lNbFiles; lFile ++)
		d_szFile[lFile] = (char *) malloc ( MAX_PATH );

	strcpy (g_szFullName, _p_stProj->szName );
	lNbFiles = 0;
	fn_Tree_vGetFilesOrProjectToGet( _p_stProj, &lNbFiles, d_szFile );

	fn_IniD_vFreeFileList( _p_stFileList );

	strcpy( _p_stFileList->szId, szFileListId );
	strcpy( _p_stFileList->szName, _szFileListName );
	_p_stFileList->cIndex = _cConfig;
	_p_stFileList->lNumberOfFiles = lNbFiles;
	_p_stFileList->d_szFile = d_szFile;

	return TRUE;
}

/*
 ---------------------------------------------------------------------------------------
  update list of file to obtain
 ---------------------------------------------------------------------------------------
 */
/*
void fn_vUpdateFilesToObtainList( void )
{
	long	lNbFiles;
	char	**d_szFile;
	long	lFile;

	lNbFiles = 0;
	fn_Tree_vGetNumberOfFilesToGet( g_p_stVssRootProject, &lNbFiles, FALSE );
	
	d_szFile = (char **) malloc (lNbFiles * sizeof ( char *) );
	for (lFile = 0; lFile < lNbFiles; lFile ++)
		d_szFile[lFile] = (char *) malloc ( MAX_PATH );

	strcpy (g_szFullName, g_p_stVssRootProject->szName );
	lNbFiles = 0;
	fn_Tree_vGetFilesToGet( g_p_stVssRootProject, &lNbFiles, d_szFile, FALSE );

	fn_IniD_vFreeFileListToObtain();
	g_stIniData.lNumberOfFilesToObtain = lNbFiles;
	g_stIniData.d_szFileToObtain = d_szFile;
}
*/

/*
 ---------------------------------------------------------------------------------------
  update list of file to obtain
 ---------------------------------------------------------------------------------------
 */
void fn_vRefreshVssTreeAndFilesToObtainList( void )
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	char				*szFileName, *szFileName2;
	int					iFile, iFile2;
	char				*szEndProj, *szEndProj2;
	BOOL				bContinue, bRecurse, bFile;
	tdstFileListConfig	*p_stConfig = &g_stIniData.stObtainConfig;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	for (iFile = 0; iFile < p_stConfig->lNumberOfFiles; iFile ++)
	{
		szFileName = p_stConfig->d_szFile[iFile];
		
		if (*szFileName == '-')
		{
			switch( *(szFileName + 1) )
			{
				case 'R':
					bRecurse = TRUE;
					bFile = FALSE;
					break;
				case 'F':
					bRecurse = FALSE;
					bFile = TRUE;
					break;
				default:
					bRecurse = FALSE;
					bFile = FALSE;
			}
			szFileName += 3;
		}
		else
		{
			bRecurse = FALSE;
			bFile = FALSE;
		}

		if (bFile)
		{
			szEndProj = strrchr( szFileName, '\\' );
			if (*szEndProj != NULL)
			{
				*szEndProj = 0;

				/*
				 * Watch if owner project has not been yet refreshed
				 */
				bContinue = TRUE;
				for (iFile2 = 0; (iFile2 < iFile) && bContinue; iFile2++)
				{
					szFileName2 = p_stConfig->d_szFile[iFile2];
					if (*szFileName2++ == '_')
					{
						if (*szFileName2 == 'F')
						{
							szFileName += 2;
							szEndProj2 = strrchr( szFileName2, '\\' );
							if (szEndProj2 != NULL)
							{
								*szEndProj2 = 0;
								if (stricmp( szFileName, szFileName2) == 0)
									bContinue = FALSE;
								*szEndProj2 = '\\';
							}
						}
					}
				}
				/*
				 * first file of this project, refresh project
				 */
				if (bContinue)
				{
					fn_bRefreshVssProjectTree( szFileName, FALSE, NULL );
				}
				*szEndProj = '\\';
			}
		}
		else
		{
			fn_bRefreshVssProjectTree( szFileName, bRecurse, NULL );
		}
	}

	fn_Tree_vRefreshWithFileList( g_p_stVssRootProject, p_stConfig);
	//fn_vUpdateFilesToObtainList();
}

/*
 =======================================================================================
	Function for local tree 
 =======================================================================================
 */
char gs_szCurrentPath[ _MAX_PATH ];


/*
 ----------------------------------------------------------------------------------------
  Description   : fill project with local content
  _p_stProject        -> project to fill
  _szEndName          -> end of current path which is a global var )
 ----------------------------------------------------------------------------------------
 */
void fn_Tree_vFillProjectFromDisk( tdstProject *_p_stProject, char *_szEndName )
{
	long		lNbFiles = 0;
	long		lNbProjs = 0;
	tdstProject	*p_stSubProj;

	WIN32_FIND_DATA stFindData;
	HANDLE			hFind;
	
	strcpy( _szEndName, "*.*" );
	hFind = FindFirstFile(gs_szCurrentPath, &stFindData );
	*_szEndName = 0;
	
	if( hFind != INVALID_HANDLE_VALUE)
	{
		do
		{
			if ( stFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
			{
				if ( *stFindData.cFileName != '.')
				{
					gs_d_szProj[ lNbProjs ] = (char *) malloc( strlen(stFindData.cFileName) + 1 );
					strcpy ( gs_d_szProj[ lNbProjs ], stFindData.cFileName );
					lNbProjs++;
				}
			}
			else
			{	
				gs_d_szFile[ lNbFiles ] = (char *) malloc( strlen(stFindData.cFileName) + 1 );
				strcpy ( gs_d_szFile[ lNbFiles ], stFindData.cFileName );
				lNbFiles++;
			}
		} while(FindNextFile( hFind, &stFindData ));
		FindClose( hFind );
	}


	/*
	 * allocate memory for all files and all sub projects
	 */
	if (lNbProjs)
	{
		_p_stProject->lNumberOfSubProjects = lNbProjs;
		_p_stProject->d_stSubProject = (tdstProject *) malloc ( lNbProjs * sizeof( tdstProject) );
		for (lNbProjs = 0; lNbProjs < _p_stProject->lNumberOfSubProjects; lNbProjs ++)
			fn_Tree_vInitProjectWithPointerName( &_p_stProject->d_stSubProject[ lNbProjs ], gs_d_szProj[lNbProjs] );
	}

	if ( lNbFiles )
	{
		if (lNbFiles > 2048)
			AfxMessageBox( "more than 2048 files in a folder\r\nthere will soon be a big bug !!!\r\nContact me .\r\n", MB_ICONSTOP | MB_OK);
 
		_p_stProject->lNumberOfFiles = lNbFiles;
		_p_stProject->d_stFile = (tdstFile *) malloc ( lNbFiles * sizeof( tdstFile) );
		for (lNbFiles = 0; lNbFiles < _p_stProject->lNumberOfFiles; lNbFiles ++)
			fn_Tree_vInitFileWithPointerName( &_p_stProject->d_stFile[ lNbFiles ], gs_d_szFile[ lNbFiles ] );
	}

	/*
	 * iterate again Ivss project content to construct sub project tree
	 */
	for (p_stSubProj = _p_stProject->d_stSubProject, lNbProjs = 0; lNbProjs < _p_stProject->lNumberOfSubProjects; lNbProjs ++, p_stSubProj++)
	{
		lNbFiles = sprintf( _szEndName, "%s\\", p_stSubProj->szName );
		fn_Tree_vFillProjectFromDisk( p_stSubProj, _szEndName + lNbFiles );
		*_szEndName = 0;
	}
}

/*
 ----------------------------------------------------------------------------------------
  Description   : build local tree
  _p_stRootProject    -> project to fill (correspond to root project)
  _szRootName         -> project name (root)
  Returns (BOOL ) TRUE if tree has been build, otherwise FALSE
 ----------------------------------------------------------------------------------------
 */
BOOL fn_Tree_bBuildFromDisk( tdstProject **_pp_stRootProject, char *_szRootName )
{

	/*
	 * check existance of root project
	 */
	if (_access( _szRootName, 0) != 0 )
		return FALSE;

	if (*_pp_stRootProject != NULL)
		fn_Tree_vFreeProjectTree(*_pp_stRootProject, TRUE );

	/*
	 * create and initialize root project
	 */
	*_pp_stRootProject = (tdstProject *) malloc( sizeof (tdstProject) );
	fn_Tree_vInitProject( *_pp_stRootProject, _szRootName );
	
	// allocate memory for name storage
	gs_d_szFile = (char **) malloc ( 2048 * sizeof( char *) );
	gs_d_szProj = (char **) malloc ( 2048 * sizeof( char *) );

	// get recursively and from root project vss tree
	sprintf( gs_szCurrentPath, "%s\\", _szRootName );
	fn_Tree_vFillProjectFromDisk( *_pp_stRootProject, gs_szCurrentPath + strlen( gs_szCurrentPath) );

	free( gs_d_szFile );
	free( gs_d_szProj );
	
	return TRUE;
}