/*
 =======================================================================================
  Name        : DlgConfl.cpp
 
  Author      : vincent lhullier            Date :21/07/97
 
  Description : implementation file for dialog box to display conflict
				implementation of function to compare two section
 =======================================================================================
  Modification -> Author :                  Date :
  Description :
 =======================================================================================
 */
//#undef _DEBUG
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#include "stdafx.h"
#include "mngdata5.h"
#include "dlgconfl.h"
#include "IniData.h"
#include "Constant.h"
#include "HelpId.h"
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

/*
 =======================================================================================
 =======================================================================================
	PART of code to decompose a file/section into a tree of section
 =======================================================================================
 =======================================================================================
 */

/*
 =======================================================================================
	Globals
 =======================================================================================
 */
/*
 * for script parsing functions
 */
char						SCRT_g_szName	[SCR_CV_ui_Cfg_MaxLenWord];
char						SCRT_g_szNameExt[SCR_CV_ui_Cfg_MaxLenWord];
char						SCRT_g_szFormat	[SCR_CV_ui_Cfg_MaxLenLine];
char						SCRT_g_szParams	[SCR_CV_ui_Cfg_MaxLenLine];
SCR_tdst_File_Description	SCRT_g_stFileDesc;
SCR_tdst_Page_Description	SCRT_g_stPageDesc;
static BOOL					SCRT_g_bPageInit = FALSE;

/*
 * for coloration of lines in Rich Edit window
 */
static COLORREF gs_a_xColor[6] = 
	{ 
		RGB( 255,  64,  64),
		RGB( 255,  64,  64),	
		RGB( 255, 255, 255),	
		RGB(   0, 255, 255), 
		RGB(   0, 255,   0), 
		RGB( 128, 128, 128) 
	};


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

#define SCRT_M_vSwapSpaces( __p_stSection_, __iRead_ )\
{\
	__iRead_ = (int) __p_stSection_->d_stCurPage->d_cBuffer[ __p_stSection_->iCurPosInPage ];\
	while ( SCR_M_Pars_IsSpace( __iRead_ ) )\
	{\
		__p_stSection_->iCurPosInPage++;\
		__iRead_ = (int) __p_stSection_->d_stCurPage->d_cBuffer[ __p_stSection_->iCurPosInPage ];\
	}\
}
				

/*
 =======================================================================================
	Functions for global page and file desc
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : initialise global Page desc and file desc variable to analyse
					a string with script parser macros and functions
  _szPageContent      -> content of page
  Returns (void )
 ----------------------------------------------------------------------------------------
 */
void SCRT_fn_vInitFileAndPageDesc( char *_szPageContent, int _iNbChar = -1 )
{
	if (!SCRT_g_bPageInit)
	{
		#ifdef SCR_DM_ProtectedVersion
		SCRT_g_stPageDesc.uiSizeOf = sizeof( SCR_tdst_Page_Description );
		#endif
		SCRT_g_stPageDesc.p_stNext = SCRT_g_stPageDesc.p_stPrev = NULL;
		SCRT_g_stFileDesc.d_stFirstPage = SCRT_g_stFileDesc.d_stLastPage = SCRT_g_stFileDesc.d_stCurPage = &SCRT_g_stPageDesc;
		SCRT_g_bPageInit = 1;
	}

	if (_iNbChar == -1)
		_iNbChar = strlen( _szPageContent ) + 2;
	
	SCRT_g_stPageDesc.d_cBuffer = _szPageContent;
	SCRT_g_stPageDesc.iNumOfChars = _iNbChar;
	SCRT_g_stFileDesc.iCurPosInPage = 0;
}

/*
 =======================================================================================
	Functions to free / clean
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : clean out a section tree
  _p_stSection           -> section tree to emptied
 ----------------------------------------------------------------------------------------
 */
void SCRT_fn_vClean( SCRT_tdstSection *_p_stSection )
{
	long lElement;

	if ( (_p_stSection  == NULL) || (_p_stSection->cType != SCRT_C_cSection) )
		return;

	if (_p_stSection->bNameIsAllocate)
		free( _p_stSection->szName );

	if (_p_stSection->d_p_stElement)
	{
		for (lElement = 0; lElement < _p_stSection->lNumberOfElements; lElement ++)
		{
			SCRT_fn_vClean( (SCRT_tdstSection *) _p_stSection->d_p_stElement[ lElement ]);
			free ( _p_stSection ->d_p_stElement[ lElement ] );
		}
		free ( _p_stSection ->d_p_stElement );
	}
	memset( _p_stSection, 0, sizeof( SCRT_tdstSection) );
}


/*
 ----------------------------------------------------------------------------------------
  Description   : clean out Section tree and deallocate section tree structure
  _p_stSection           -> section tree to deallocate
 ----------------------------------------------------------------------------------------
 */
void SCRT_fn_vFree( SCRT_tdstSection *_p_stSection )
{
	SCRT_fn_vClean( _p_stSection );
	free( _p_stSection );
}

/*
 =======================================================================================
	Functions for build a section tree
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : build a tree that correspond to given section
  _p_stSection           -> tree to be build
  _p_stSection        -> section content
  _szName             -> nmae of file or section
  bFile               -> TRUE if name and section represent a file
 ----------------------------------------------------------------------------------------
 */
void SCRT_fn_vBuildSectionTree( SCRT_tdstSection *_p_stSection, SCR_tdst_File_Description *_p_stContent, char *_szName, unsigned short _uwNameLength, BOOL bFile )
{
	SCR_tde_Cxt_ParseType	eLineType;
	unsigned int			iNbRead;
	char					*szSavePosInSection;
	char					*szEndName;
	char					iRead;

	if (bFile)
	{
		/* allocate memory to store file name */
		_p_stSection->bNameIsAllocate = TRUE;
		_p_stSection->szName = (char *) malloc (strlen( _szName ) + 1 );
		strcpy( _p_stSection->szName, _szName );
	}
	else
	{
		if (_szName == NULL)
		{
			/* get section name */
			while(1)
			{
				SCRT_M_vSwapSpaces( _p_stContent, iRead );
				szSavePosInSection = _p_stContent->d_stCurPage->d_cBuffer + _p_stContent->iCurPosInPage;
	
				iRead = fn_i_Pars_Line(_p_stContent, SCRT_g_szName, SCRT_g_szNameExt, SCRT_g_szFormat, SCRT_g_szParams, &eLineType, &iNbRead);

				if (eLineType == SCR_EPT_Cxt_BeginSection)
				{
					_szName = szSavePosInSection;
					_uwNameLength = (unsigned short) iNbRead;
					szEndName = _szName + _uwNameLength - 1;
					while (  (*szEndName == '\r') || (*szEndName == '\n') || (*szEndName == 0) || (*szEndName == ' ') || (*szEndName == '\t'))
					{
						szEndName --;
						_uwNameLength--;
					}
					break;
				}
				else if (eLineType != SCR_EPT_Cxt_None)
					return;
			}
		}
		_p_stSection->cType = SCRT_C_cSection;
		_p_stSection->bNameIsAllocate = FALSE;
		_p_stSection->szName = _szName;
		_p_stSection->uwNameLength = _uwNameLength;
	}

	while (1)
	{
		SCRT_M_vSwapSpaces( _p_stContent, iRead );
		szSavePosInSection = _p_stContent->d_stCurPage->d_cBuffer + _p_stContent->iCurPosInPage ;

		iRead = fn_i_Pars_Line(_p_stContent, SCRT_g_szName, SCRT_g_szNameExt, SCRT_g_szFormat, SCRT_g_szParams, &eLineType, &iNbRead);
		
		szEndName = szSavePosInSection + iNbRead - 1;
		while (  (*szEndName == '\r') || (*szEndName == '\n') || (*szEndName == 0) || (*szEndName == ' ') || (*szEndName == '\t'))
		{
			iNbRead--;
			szEndName--;
		}

		switch( eLineType )
		{
			case SCR_EPT_Cxt_Entry:
			case SCR_EPT_Cxt_Directive:
				{
					SCRT_tdstEntry *p_stEntry;

					if ( _p_stSection->lNumberOfElements)
					{
						if ( ((SCRT_tdstSection *) _p_stSection->d_p_stElement[ _p_stSection->lNumberOfElements - 1 ])->cType == SCRT_C_cSection )
							((SCRT_tdstSection *) _p_stSection->d_p_stElement[ _p_stSection->lNumberOfElements - 1 ])->szEndSection = szSavePosInSection;
					}

					/*
					 * allocate new entry structure and fill ir
					 */
					p_stEntry = (SCRT_tdstEntry *) malloc( sizeof( SCRT_tdstEntry ) );
					memset( p_stEntry, 0, sizeof( SCRT_tdstEntry ) );
					p_stEntry->cType = SCRT_C_cEntry;
					p_stEntry->szName = szSavePosInSection;
					p_stEntry->uwNameLength = (unsigned short) iNbRead;
					/*
					 * add this entry in current section element
					 */
					if (_p_stSection->d_p_stElement == NULL)
						_p_stSection->d_p_stElement = (SCRT_tdstEntry **) malloc( 16 * sizeof( SCRT_tdstEntry * ) );
					else if ( (_p_stSection->lNumberOfElements & 0xF) == 0)
						_p_stSection->d_p_stElement = (SCRT_tdstEntry **) realloc( _p_stSection->d_p_stElement, (_p_stSection->lNumberOfElements + 16) * sizeof( SCRT_tdstEntry *) );

					_p_stSection->d_p_stElement[ _p_stSection->lNumberOfElements++ ] = p_stEntry;
				}
				break;
			case SCR_EPT_Cxt_BeginSection:
				{
					SCRT_tdstSection *p_stSub;

					if ( _p_stSection->lNumberOfElements)
					{
						if ( ((SCRT_tdstSection *) _p_stSection->d_p_stElement[ _p_stSection->lNumberOfElements - 1 ])->cType == SCRT_C_cSection )
							((SCRT_tdstSection *) _p_stSection->d_p_stElement[ _p_stSection->lNumberOfElements - 1 ])->szEndSection = szSavePosInSection;
					}

					/*
					 * allocate new section structure and initialize it
					 */
					p_stSub = (SCRT_tdstSection *) malloc ( sizeof( SCRT_tdstSection ) );
					memset( p_stSub, 0, sizeof( SCRT_tdstSection) );

					/*
					 * add this sub section to section element array
					 */
					if (_p_stSection->d_p_stElement == NULL)
						_p_stSection->d_p_stElement = (SCRT_tdstEntry **) malloc( 16 * sizeof( SCRT_tdstEntry * ) );
					else if ( (_p_stSection->lNumberOfElements & 0xF) == 0)
						_p_stSection->d_p_stElement = (SCRT_tdstEntry **) realloc( _p_stSection->d_p_stElement, (_p_stSection->lNumberOfElements + 16) * sizeof( SCRT_tdstEntry *) );
					
					_p_stSection->d_p_stElement[ _p_stSection->lNumberOfElements++ ] = (SCRT_tdstEntry *) p_stSub;

					
					SCRT_fn_vBuildSectionTree( p_stSub, _p_stContent, szSavePosInSection, (unsigned short) iNbRead, FALSE );
				}
				break;
			case SCR_EPT_Cxt_EndSection:
				{
					_p_stSection->szEndSection =  _p_stContent->d_stCurPage->d_cBuffer + _p_stContent->iCurPosInPage ;
					return;
				}
				break;
			case SCR_EPT_Cxt_None:
				{
					if (iRead == EOF)
					{
						_p_stSection->szEndSection =  _p_stContent->d_stCurPage->d_cBuffer + _p_stContent->iCurPosInPage ;
						return;
					}
				}
				break;
		}
	}
}

/*
 ----------------------------------------------------------------------------------------
  Description   : init and build section tree that correspond to section store in a 
					tdstFileInfo structure
  _p_stSection           -> tree to be build
  _p_stSectionInfo    -> section information
 ----------------------------------------------------------------------------------------
 */
void SCRT_fn_vInitAndBuildSectionTree( SCRT_tdstSection *_p_stSection, char *_szSectionContent, char *_szFileName )
{
	memset( _p_stSection, 0, sizeof( SCRT_tdstSection) );
	if (_szSectionContent == NULL)
		return;

	SCRT_fn_vInitFileAndPageDesc( _szSectionContent );
	SCRT_fn_vBuildSectionTree( _p_stSection, &SCRT_g_stFileDesc, _szFileName, 0, (_szFileName != NULL)  );
}




/*
 =======================================================================================
	Functions to compare two section tree
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : get index of a line in section if this line exist
  _p_stSection           -> section tree where we search line
  _szEntryName        -> line 
  Returns (long ) index of line or -1 if not found
 ----------------------------------------------------------------------------------------
 */
long SCRT_fn_lGetExactElementIndex( SCRT_tdstSection *_p_stSection, SCRT_tdstEntry *_p_stElement )
{
	long			lIndex;
	SCRT_tdstEntry	*p_stSectionEntry;

	for (lIndex = 0; lIndex < _p_stSection->lNumberOfElements; lIndex ++)
	{
		p_stSectionEntry = (SCRT_tdstEntry *) _p_stSection->d_p_stElement[ lIndex ];
		
		if ( p_stSectionEntry->cCompState != SCRT_C_cNew )
			continue;

		if (p_stSectionEntry->uwNameLength == _p_stElement->uwNameLength)
			if (strnicmp( p_stSectionEntry->szName, _p_stElement->szName, _p_stElement->uwNameLength ) == 0)
				return lIndex;
	}
	return -1;
}

/*
 ----------------------------------------------------------------------------------------
  Description   : search for a entry within a section. Entry must not be linked with a same
					entry in another tree and must have the same name. Parameters of entry
					are different
  _p_stSection           -> section to search in
  _lFirstIndex        -> first not linked entry to begin seaching
  _p_stEntry          -> entry to search for
  Returns (long ) -1 if fails,otherwise index of entry found
 ----------------------------------------------------------------------------------------
 */
long SCRT_fn_lGetDiffEntryIndex( SCRT_tdstSection *_p_stSection, long _lFirstIndex, SCRT_tdstEntry *_p_stEntry )
{
	long			lIndex;
	SCRT_tdstEntry	*p_stSectionEntry;

	SCRT_fn_vInitFileAndPageDesc( _p_stEntry->szName, SCR_CV_ui_Cfg_MaxLenWord );
	fn_i_Pars_Word( &SCRT_g_stFileDesc, SCRT_g_szName );

	for (lIndex = _lFirstIndex; lIndex < _p_stSection->lNumberOfElements; lIndex ++)
	{
		p_stSectionEntry = (SCRT_tdstEntry *) _p_stSection->d_p_stElement[ lIndex ];

		if (p_stSectionEntry->cCompState != SCRT_C_cNew)
			return -1;

		if ( p_stSectionEntry->cType != SCRT_C_cEntry )
			continue;
		
		SCRT_fn_vInitFileAndPageDesc( p_stSectionEntry->szName, SCR_CV_ui_Cfg_MaxLenWord );
		fn_i_Pars_Word( &SCRT_g_stFileDesc, SCRT_g_szNameExt );

		if (stricmp( SCRT_g_szName, SCRT_g_szNameExt) == 0 )
			return lIndex;
	}
	return -1;
}

/*
 ----------------------------------------------------------------------------------------
  Description   : get index of a subsection in section. sub section must have same name and
					name ext as given subsection. But param and format are different
  _p_stSection         -> section tree where we search sub section
  _lFirstIndex		-> first not linked sub section in section
  _p_stSubSection	-> sub section to search for
  Returns (long ) index of line or -1 if not found
 ----------------------------------------------------------------------------------------
 */
long SCRT_fn_lGetDiffSubSectionIndex( SCRT_tdstSection *_p_stSection, long _lFirstIndex, SCRT_tdstSection *_p_stSubSection )
{
	long				lIndex;
	SCRT_tdstSection	*p_stSectionSubSection;

	SCRT_fn_vInitFileAndPageDesc( _p_stSubSection->szName + 1, SCR_CV_ui_Cfg_MaxLenWord );
	fn_i_Pars_SectionName( &SCRT_g_stFileDesc, SCRT_g_szName, SCRT_g_szNameExt );

	for (lIndex = _lFirstIndex; lIndex < _p_stSection->lNumberOfElements; lIndex ++)
	{
		p_stSectionSubSection = (SCRT_tdstSection *) _p_stSection->d_p_stElement[ lIndex ];

		if (p_stSectionSubSection->cCompState != SCRT_C_cNew)
			return -1;

		if (p_stSectionSubSection->cType != SCRT_C_cSection)
			continue;

		SCRT_fn_vInitFileAndPageDesc( p_stSectionSubSection->szName + 1, SCR_CV_ui_Cfg_MaxLenWord );
		fn_i_Pars_SectionName( &SCRT_g_stFileDesc, SCRT_g_szFormat, SCRT_g_szParams );

		if ( (stricmp( SCRT_g_szName, SCRT_g_szFormat) == 0) && (stricmp( SCRT_g_szNameExt, SCRT_g_szParams) == 0) )
			return lIndex;
	}
	return -1;
}


/*
 ----------------------------------------------------------------------------------------
  Description   : compare two section content
  _p_stST1            -> first section tree
  _p_stST2            -> secoind section tree
  Returns (BOOL ) TRUE if section are the same, FALSE else
 ----------------------------------------------------------------------------------------
 */
BOOL SCRT_fn_bCompareSectionTree( SCRT_tdstSection *_p_stSection1, SCRT_tdstSection *_p_stSection2 )
{
	long					lIndex1;
	long					lIndex2;
	long					lFirstIndex;
	BOOL					bResult = TRUE;
	SCRT_tdstEntry			*p_stElement;

	/*
	 * first pass on element : find all exact elements
	 */
	for (lIndex1 = 0; lIndex1 < _p_stSection1->lNumberOfElements; lIndex1 ++)
	{
		p_stElement = _p_stSection1->d_p_stElement[ lIndex1 ];
		lIndex2 = SCRT_fn_lGetExactElementIndex( _p_stSection2, p_stElement );

		if (lIndex2 != -1)
		{
			_p_stSection2->d_p_stElement[ lIndex2 ]->cCompState = p_stElement->cCompState = SCRT_C_cSame;
			p_stElement->lCompWith = lIndex2;
			_p_stSection2->d_p_stElement[ lIndex2 ]->lCompWith = lIndex1;

			if (p_stElement->cType == SCRT_C_cSection )
				bResult &= SCRT_fn_bCompareSectionTree( (SCRT_tdstSection *) p_stElement, (SCRT_tdstSection *) _p_stSection2->d_p_stElement[lIndex2] );				
		}
		else
			bResult = FALSE;
	}

	if (bResult)
		bResult &= (lIndex1 == _p_stSection2->lNumberOfElements );
	else
	{
		/*
		 * Second pass on element to find all diff element
		 */
		lFirstIndex = 0;
		for (lIndex1 = 0; lIndex1 < _p_stSection1->lNumberOfElements; lIndex1 ++)
		{
			p_stElement = _p_stSection1->d_p_stElement[ lIndex1 ];
			if (p_stElement->cCompState == SCRT_C_cNew)
			{
				if (p_stElement->cType == SCRT_C_cSection)
					lIndex2 = SCRT_fn_lGetDiffSubSectionIndex( _p_stSection2, lFirstIndex, (SCRT_tdstSection *) p_stElement );
				else
					lIndex2 = SCRT_fn_lGetDiffEntryIndex( _p_stSection2, lFirstIndex, p_stElement );
				
				if (lIndex2 != -1)
				{
					_p_stSection2->d_p_stElement[ lIndex2 ]->cCompState = p_stElement->cCompState = SCRT_C_cDiff;
					p_stElement->lCompWith = lIndex2;
					_p_stSection2->d_p_stElement[ lIndex2 ]->lCompWith = lIndex1;

					if (p_stElement->cType == SCRT_C_cSection )
						bResult &= SCRT_fn_bCompareSectionTree( (SCRT_tdstSection *) p_stElement, (SCRT_tdstSection *) _p_stSection2->d_p_stElement[lIndex2] );				
				}
			}
			else
				lFirstIndex = p_stElement->lCompWith + 1;
		}
	}
	return bResult;
}

/*
 =======================================================================================
	Functions to build a merge tree with two other tree
 =======================================================================================
 */

void SCRT_fn_vMergeSectionTree( SCRT_tdstSection *_p_stMerge, SCRT_tdstSection *_p_stFirst, SCRT_tdstSection *_p_stSecond )
{
}

/*
 =======================================================================================
	Functions to make correspondance between a section 
 =======================================================================================
 */


/*
 ----------------------------------------------------------------------------------------
  Description   : get owner section of an entry
  _p_stEntry          -> pointer on entry
  _p_oTree            -> pointer on Tree Control that own entry
  Returns (SCRT_tdstSection ) father section of entry
 ----------------------------------------------------------------------------------------
 */
SCRT_tdstSection *SCRT_fnp_stGetOwnerSection( SCRT_tdstEntry *_p_stEntry, CTreeCtrl *_p_oTree )
{
	HTREEITEM hOwnerSectionItem;

	hOwnerSectionItem = _p_oTree->GetParentItem( _p_stEntry->hItem );
	return (SCRT_tdstSection *) _p_oTree->GetItemData( hOwnerSectionItem );
}


/*
 ----------------------------------------------------------------------------------------
  Description   : get all parent of a section
  _ppp_stGenealogy	-> array of all parent of given section
  _hItem            -> item that correspond to section
  _p_oTree          -> Tree Control that own item
  Returns (long ) number of parent
 ----------------------------------------------------------------------------------------
 */
long SCRT_fn_lGetSectionGenealogy( SCRT_tdstSection ***_ppp_stGenealogy, HTREEITEM _hItem, CTreeCtrl *_p_oTree )
{
	long		lNumberOfParents = 0;
	HTREEITEM	hParent;
	long		lIndex;
	
	/*
	 * first :count number of parent
	 */
	hParent = _p_oTree->GetParentItem( _hItem );
	while( hParent != NULL)
	{
		lNumberOfParents++;
		hParent = _p_oTree->GetParentItem( hParent );
	}
	if (lNumberOfParents != 0)
	{
		/*
		 * allocate and fill genealogy
		 */
		*_ppp_stGenealogy = (SCRT_tdstSection **) malloc( lNumberOfParents * sizeof( SCRT_tdstSection *) );
		lIndex = lNumberOfParents;
		hParent = _p_oTree->GetParentItem( _hItem );
		while (hParent != NULL)
		{
			(*_ppp_stGenealogy)[ --lIndex ] = (SCRT_tdstSection *) _p_oTree->GetItemData( hParent );
			hParent = _p_oTree->GetParentItem( hParent );
		}
	}
	return lNumberOfParents;
}


/*
 ----------------------------------------------------------------------------------------
  Description   : get section in a tree that is linked with the given one in another tree
  _p_stSection        -> section linked
  _p_oFromTree        -> tree that own previous section
  _p_oInTree          -> tree where we search linked section
  Returns (SCRT_tdstSection ) section that is linked with first parameter
 ----------------------------------------------------------------------------------------
 */
SCRT_tdstSection *SCRT_fnp_stGetCorrespondantSection( SCRT_tdstSection *_p_stSection, CTreeCtrl *_p_oFromTree, CTreeCtrl *_p_oInTree )
{
	SCRT_tdstSection	**pp_stSectionGenealogy;
	long				lNumberOfParents;
	long				lIndex;
	SCRT_tdstSection	*p_stSection;

	if (_p_stSection->cCompState == SCRT_C_cNew)
		return NULL;

	p_stSection = (SCRT_tdstSection *) _p_oInTree->GetItemData(_p_oInTree->GetRootItem());
	lNumberOfParents = SCRT_fn_lGetSectionGenealogy( &pp_stSectionGenealogy, _p_stSection->hItem, _p_oFromTree );
	if (lNumberOfParents != 0)
	{
		for ( lIndex = 1; lIndex < lNumberOfParents; lIndex ++)
			p_stSection = (SCRT_tdstSection *) p_stSection->d_p_stElement[ pp_stSectionGenealogy[lIndex]->lCompWith ];
		free( pp_stSectionGenealogy );
		p_stSection = (SCRT_tdstSection *) p_stSection->d_p_stElement[ _p_stSection->lCompWith ];
	}
	
	return p_stSection;
}


/*
 ----------------------------------------------------------------------------------------
  Description   : get in a section tree control item that correspond to given one in 
					another tree
  _hItem              -> item to find in InTree tree control
  _p_oFromTree        -> tree that own item
  _p_oInTree          -> tree where we search for a correspondant item
  Returns (HTREEITEM ) item in InTree control that correspond to item parameter
 ----------------------------------------------------------------------------------------
 */
HTREEITEM SCRT_fn_hGetCorrespondantItem( HTREEITEM _hItem, CTreeCtrl *_p_oFromTree, CTreeCtrl *_p_oInTree )
{
	int					iImage, iSelImage;
	SCRT_tdstSection	*p_stSection;
	SCRT_tdstEntry		*p_stEntry;

	_p_oFromTree->GetItemImage( _hItem, iImage, iSelImage );

	if (iImage < 4)
	{
		/*
		 * a section line
		 */
		p_stSection = (SCRT_tdstSection *) _p_oFromTree->GetItemData( _hItem );
		p_stSection = SCRT_fnp_stGetCorrespondantSection( p_stSection, _p_oFromTree, _p_oInTree );
		return (p_stSection == NULL) ? NULL : p_stSection->hItem;
	}

	/*
	 * an entry line
	 */
	p_stEntry = (SCRT_tdstEntry *) _p_oFromTree->GetItemData( _hItem );
	if (p_stEntry->cCompState == SCRT_C_cNew)
		return NULL;

	p_stSection = SCRT_fnp_stGetOwnerSection( p_stEntry, _p_oFromTree );
	p_stSection = SCRT_fnp_stGetCorrespondantSection( p_stSection, _p_oFromTree, _p_oInTree );
	if (p_stSection == NULL)
		return NULL;
		
	p_stEntry = p_stSection->d_p_stElement[ p_stEntry->lCompWith ];
	return p_stEntry->hItem;
}

 


/*
 =======================================================================================
 =======================================================================================
	CConflictDlg dialog
 =======================================================================================
 =======================================================================================
 */


/*
 ----------------------------------------------------------------------------------------
  Description   : constructor
 ----------------------------------------------------------------------------------------
 */
CConflictDlg::CConflictDlg(CWnd* pParent /*=NULL*/)	: CDialog(CConflictDlg::IDD, pParent)
{
	int iImage;

	//{{AFX_DATA_INIT(CConflictDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	m_szUserName = NULL;
	m_szSectionName = NULL;
	m_szVssSection = NULL;
	m_szLocalSection = NULL;

	m_bLocalOp = FALSE;

	m_cDisplayMode = -1;

	m_a_hIcon[0] = AfxGetApp()->LoadIcon( IDI_ICON_TREESECTIONSAME );
	m_a_hIcon[1] = AfxGetApp()->LoadIcon( IDI_ICON_TREESECTIONDIFF );
	m_a_hIcon[2] = AfxGetApp()->LoadIcon( IDI_ICON_TREESECTIONVSS );
	m_a_hIcon[3] = AfxGetApp()->LoadIcon( IDI_ICON_TREESECTIONLOCAL );
	m_a_hIcon[4] = AfxGetApp()->LoadIcon( IDI_ICON_TREEENTRYSAME );
	m_a_hIcon[5] = AfxGetApp()->LoadIcon( IDI_ICON_TREEENTRYDIFF );
	m_a_hIcon[6] = AfxGetApp()->LoadIcon( IDI_ICON_TREEENTRYVSS );
	m_a_hIcon[7] = AfxGetApp()->LoadIcon( IDI_ICON_TREEENTRYLOCAL );

	/* initialize and fill image list */
	m_oImageList.Create( 16, 16, TRUE, 8, 5 );
	for (iImage = 0; iImage < 8; iImage ++)
		m_oImageList.Add( m_a_hIcon[ iImage ] );

}

/*
 ----------------------------------------------------------------------------------------
  Description   : destructor
 ----------------------------------------------------------------------------------------
 */
CConflictDlg::~CConflictDlg()
{
	m_oImageList.DeleteImageList();
}



/*
 ----------------------------------------------------------------------------------------
  Description   : Message map
 ----------------------------------------------------------------------------------------
 */
BEGIN_MESSAGE_MAP(CConflictDlg, CDialog)
	//{{AFX_MSG_MAP(CConflictDlg)
	ON_WM_DESTROY()
	ON_WM_SIZE()
	ON_WM_SIZING()
	ON_WM_HELPINFO()
	ON_NOTIFY(TVN_SELCHANGED, IDC_TREE_LOCAL, OnSelchangedTreeLocal)
	ON_NOTIFY(TVN_ITEMEXPANDED, IDC_TREE_LOCAL, OnItemexpandedTreeLocal)
	ON_NOTIFY(TVN_SELCHANGED, IDC_TREE_VSS, OnSelchangedTreeVss)
	ON_NOTIFY(TVN_ITEMEXPANDED, IDC_TREE_VSS, OnItemexpandedTreeVss)
	ON_EN_VSCROLL(IDC_RICHEDIT_LOCALSECTION, OnVscrollRicheditLocal)
	ON_EN_VSCROLL(IDC_RICHEDIT_VSSSECTION, OnVscrollRicheditVss)
	ON_BN_CLICKED(IDC_BUTTON_TREETEXT, OnButtonTreetext)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/*
 =======================================================================================
	CConflictDlg specific functions
 =======================================================================================
 */

void CConflictDlg::m_fn_vChangeDisplayMode( char _cMode )
{
	if (m_cDisplayMode != _cMode)
	{
		m_cDisplayMode = _cMode;
		switch( _cMode )
		{
			case C_cDisplayText:
				GetDlgItem( IDC_BUTTON_TREETEXT )->SetWindowText( "Tree" );
				GetDlgItem( IDC_RICHEDIT_VSSSECTION )->ShowWindow( TRUE );
				GetDlgItem( IDC_RICHEDIT_LOCALSECTION)->ShowWindow( TRUE );
				GetDlgItem( IDC_TREE_VSS )->ShowWindow( FALSE );
				GetDlgItem( IDC_TREE_LOCAL )->ShowWindow( FALSE );
				break;
			case C_cDisplayTree:
				GetDlgItem( IDC_BUTTON_TREETEXT )->SetWindowText( "Text" );
				GetDlgItem( IDC_RICHEDIT_VSSSECTION )->ShowWindow( FALSE );
				GetDlgItem( IDC_RICHEDIT_LOCALSECTION)->ShowWindow( FALSE );
				GetDlgItem( IDC_TREE_VSS )->ShowWindow( TRUE );
				GetDlgItem( IDC_TREE_LOCAL )->ShowWindow( TRUE );
				break;
		}
	}
}


/*
 ----------------------------------------------------------------------------------------
  Description   : recursive function to fill section tree
  _p_oTree            -> tree control to  fill
  _p_stSection        -> section to consider
  _hParent            -> current father item
 ----------------------------------------------------------------------------------------
 */
void CConflictDlg::m_fn_vFillTree( CTreeCtrl *_p_oTree, SCRT_tdstSection *_p_stSection, HTREEITEM _hParent, int _iImage, BOOL _bVss )
{
	char			*szEnd, cEndChar;
	HTREEITEM		hCurrent;
	long			lIndex;
	int				iImage;
	char			cComp;
	HTREEITEM		hItem;
	SCRT_tdstEntry	*p_stElement;

	//cEndChar = *(szEnd = SCRT_fn_p_szGetEndLine( _p_stSection->szName ));
	szEnd = _p_stSection->szName + _p_stSection->uwNameLength;
	cEndChar = *szEnd;
	*szEnd = 0;
	hCurrent = _p_oTree->InsertItem( _p_stSection->szName, _iImage, _iImage, _hParent );
	_p_stSection->hItem = hCurrent;
	_p_oTree->SetItemData( hCurrent, (DWORD) _p_stSection );
	*szEnd = cEndChar;

	for (lIndex = 0; lIndex < _p_stSection->lNumberOfElements; lIndex ++)
	{
		p_stElement = _p_stSection->d_p_stElement[ lIndex ];
		if (p_stElement->cType == SCRT_C_cEntry )
		{
			szEnd = p_stElement->szName + p_stElement->uwNameLength;
			*szEnd = 0;
			cComp = p_stElement->cCompState;
			iImage = (cComp == SCRT_C_cNew) ? (_bVss ? 6 : 7) : ((cComp == SCRT_C_cDiff) ? 5 : 4 );
			hItem = _p_oTree->InsertItem( p_stElement->szName, iImage, iImage, hCurrent );
			_p_oTree->SetItemData( hItem, (DWORD) p_stElement );
			p_stElement->hItem = hItem;
			*szEnd = cEndChar;
		}
		else
		{
			cComp = p_stElement->cCompState;
			iImage = (cComp == SCRT_C_cNew) ? (_bVss ? 2 : 3) : ((cComp == SCRT_C_cDiff) ? 1 : 0 );
			m_fn_vFillTree( _p_oTree, (SCRT_tdstSection *) p_stElement, hCurrent, iImage, _bVss );
		}
	}
}

/*
 =======================================================================================
	Function to fill Rich Edit boxes
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : add a line in RichEdit Control
  szLine              -> line to add
  cLineType           -> type of line (info, ok, error)
 ----------------------------------------------------------------------------------------
 */
long CConflictDlg::m_fn_RE_lAddText( CRichEditCtrl *_p_oRE, char *_szText, char *_szEndText, char _cType )
{
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
	long	lOldLength;
	long	lNewLength;
	long	lSize;
	char	cSaveEnd;
	/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/

	m_stCharFormat.crTextColor = gs_a_xColor[ _cType ];
	m_stCharFormat.dwEffects = 0;
	
	lOldLength = _p_oRE->GetTextLength();
	lNewLength = lOldLength + (_szEndText - _szText);
	lSize = _p_oRE->GetLimitText();
	if (lNewLength > lSize)
	{
		lSize += 10000;
		_p_oRE->LimitText( lSize );
	}
	cSaveEnd = *_szEndText;
	*_szEndText = 0;
	_p_oRE->ReplaceSel( _szText );
	*_szEndText = cSaveEnd;
	
	_p_oRE->SetSel( lOldLength, -1 );
	_p_oRE->SetSelectionCharFormat( m_stCharFormat );
	_p_oRE->SetSel( lNewLength, lNewLength ); 

	return 0;
}


/*
 ----------------------------------------------------------------------------------------
  Description   : function to assure that the two given Rich edit control have the same
					number of lines
  _p_oRE1             -> first RichEditCtrl
  _p_oRE2             -> second RichEditCtrl
 ----------------------------------------------------------------------------------------
 */
void CConflictDlg::m_fn_RE_vRecaleLine( CRichEditCtrl *_p_oRE1, CRichEditCtrl *_p_oRE2 )
{
	long			lDiffLine;
	CRichEditCtrl	*p_oRE;
	char			*szNewLines;

	lDiffLine = _p_oRE1->GetLineCount() - _p_oRE2->GetLineCount();
	if (lDiffLine == 0)
		return;

	if (lDiffLine < 0)
	{
		p_oRE = _p_oRE1;
		lDiffLine = -lDiffLine;
	}
	else
		p_oRE = _p_oRE2;

	szNewLines = (char *) malloc (lDiffLine + 1);
	memset( szNewLines, '\n', lDiffLine );
	m_fn_RE_lAddText( p_oRE, szNewLines, szNewLines + lDiffLine, SCRT_C_cComment );
	free (szNewLines );
}


/*
 ----------------------------------------------------------------------------------------
  Description   : print the beginning of section in a RichEditCtrl
  _p_oRE              -> the RichEdit Control
  _p_stSection        -> section to print
  _szFrom             -> current position in section content
  _bVss               -> say if it's a Vss or a local section
  Returns (char *) new position in section content
 ----------------------------------------------------------------------------------------
 */
char *CConflictDlg::m_fn_RE_vPrintSectionBeginning( CRichEditCtrl *_p_oRE, SCRT_tdstSection *_p_stSection, char *_szFrom, BOOL _bVss )
{
	char cType;

	if (_szFrom < _p_stSection->szName )
	{
		m_fn_RE_lAddText( _p_oRE, _szFrom, _p_stSection->szName, SCRT_C_cComment);
		_szFrom = _p_stSection->szName;
	}
	
	if ((cType = _p_stSection->cCompState) == SCRT_C_cNew)
		cType = _bVss ? SCRT_C_cNewVss : SCRT_C_cNewLocal;

	m_fn_RE_lAddText( _p_oRE, _szFrom, _szFrom + _p_stSection->uwNameLength, cType );
	return _szFrom + _p_stSection->uwNameLength; 
}


/*
 ----------------------------------------------------------------------------------------
  Description   : print a section entry in a RichEdit Ctrl
  _p_oRE              -> the RichEdit Ctrl
  _p_stEntry          -> the entry
  _szFrom             -> current position in section content
  _bVss               -> say if it's a Vss entry or local entry
  Returns (char *) new position in section content
 ----------------------------------------------------------------------------------------
 */
char *CConflictDlg::m_fn_RE_vPrintEntry( CRichEditCtrl *_p_oRE, SCRT_tdstEntry *_p_stEntry, char *_szFrom, BOOL _bVss )
{
	char cType;

	if (_szFrom < _p_stEntry->szName )
	{
		m_fn_RE_lAddText( _p_oRE, _szFrom, _p_stEntry->szName, SCRT_C_cComment);
		_szFrom = _p_stEntry->szName;
	}
	
	if ((cType = _p_stEntry->cCompState) == SCRT_C_cNew)
		cType = _bVss ? SCRT_C_cNewVss : SCRT_C_cNewLocal;

	m_fn_RE_lAddText( _p_oRE, _szFrom, _szFrom + _p_stEntry->uwNameLength, cType );
	return _szFrom + _p_stEntry->uwNameLength; 
}


/*
 ----------------------------------------------------------------------------------------
  Description   : print end of section in a RichEdit Ctrl
  _p_oRE              -> the RichEdit Control
  _p_stSection        -> section to print
  _szFrom             -> current position in section content
  _bVss               -> say if it's a Vss or a local section
  Returns (char *) new position in section content
 ----------------------------------------------------------------------------------------
 */
char *CConflictDlg::m_fn_RE_vPrintSectionEnd( CRichEditCtrl *_p_oRE, SCRT_tdstSection *_p_stSection, char *_szFrom, BOOL _bVss )
{
	char cType;
	char *szBeforeEnd;

	szBeforeEnd = _p_stSection->szEndSection;
	while ( *szBeforeEnd != SCR_CC_c_Cfg_SectionEndMark )
		szBeforeEnd --;

	if (_szFrom < szBeforeEnd )
	{
		m_fn_RE_lAddText( _p_oRE, _szFrom, szBeforeEnd, SCRT_C_cComment);
		_szFrom = szBeforeEnd;
	}

	if ((cType = _p_stSection->cCompState) == SCRT_C_cNew)
		cType = _bVss ? SCRT_C_cNewVss : SCRT_C_cNewLocal;

	m_fn_RE_lAddText( _p_oRE, _szFrom, _p_stSection->szEndSection, cType );
	return _p_stSection->szEndSection; 
}


/*
 ----------------------------------------------------------------------------------------
  Description   : print a full section in a RichEdit Ctrl
  _p_oRE              -> the RichEdit Ctrl
  _p_stSection        -> the Section
  _szFrom             -> current position in section content
  _bVss               -> say if it's a Vss or local section
  Returns (char *) new position in section content
 ----------------------------------------------------------------------------------------
 */
char *CConflictDlg::m_fn_RE_vPrintSection( CRichEditCtrl *_p_oRE, SCRT_tdstSection *_p_stSection, char *_szFrom, BOOL _bVss )
{
	long lElement;

	_szFrom = m_fn_RE_vPrintSectionBeginning( _p_oRE, _p_stSection, _szFrom, _bVss );
	for (lElement = 0; lElement < _p_stSection->lNumberOfElements; lElement ++)
	{
		if (_p_stSection->d_p_stElement[lElement]->cType == SCRT_C_cEntry )
			_szFrom = m_fn_RE_vPrintEntry( _p_oRE, _p_stSection->d_p_stElement[lElement], _szFrom, _bVss );
		else
			_szFrom = m_fn_RE_vPrintSection( _p_oRE, (SCRT_tdstSection *) _p_stSection->d_p_stElement[lElement], _szFrom, _bVss );
	}
	_szFrom = m_fn_RE_vPrintSectionEnd( _p_oRE, _p_stSection, _szFrom, _bVss );
	return _szFrom;
}

/*
 ----------------------------------------------------------------------------------------
  Description   : print two section in parrallel in the two RichEditCtrl (Vss and local of the
					dialog box )
  _p_stVssSection     -> the VssSection
  _szVssFrom          -> current position in Vss section content
  _p_stLclSection     -> the LocalSection
  _szLclFrom          -> current position in local section content
 ----------------------------------------------------------------------------------------
 */
void CConflictDlg::m_fn_RE_vPrintTwoSection	( SCRT_tdstSection *_p_stVssSection,char **_p_szVssFrom, SCRT_tdstSection *_p_stLclSection,char **_p_szLclFrom )
{
	long lVssElement, lLclElement;

	m_fn_RE_vRecaleLine( &m_oVssRichEdit, &m_oLocalRichEdit );
	*_p_szVssFrom = m_fn_RE_vPrintSectionBeginning( &m_oVssRichEdit, _p_stVssSection, *_p_szVssFrom, TRUE );
	*_p_szLclFrom = m_fn_RE_vPrintSectionBeginning( &m_oLocalRichEdit, _p_stLclSection, *_p_szLclFrom, FALSE );

	lVssElement = 0;
	lLclElement = 0;

	while (1)
	{
		for ( ; lVssElement < _p_stVssSection->lNumberOfElements; lVssElement++ )
		{
			if (_p_stVssSection->d_p_stElement[ lVssElement ]->cCompState != SCRT_C_cNew )
				break;

			if (_p_stVssSection->d_p_stElement[lVssElement]->cType == SCRT_C_cEntry )
				*_p_szVssFrom = m_fn_RE_vPrintEntry( &m_oVssRichEdit, _p_stVssSection->d_p_stElement[lVssElement], *_p_szVssFrom, TRUE );
			else
				*_p_szVssFrom = m_fn_RE_vPrintSection( &m_oVssRichEdit, (SCRT_tdstSection *) _p_stVssSection->d_p_stElement[lVssElement], *_p_szVssFrom, TRUE );
		}

		for (; lLclElement < _p_stLclSection->lNumberOfElements; lLclElement++ )
		{
			if (_p_stLclSection->d_p_stElement[ lLclElement ]->cCompState != SCRT_C_cNew )
				break;

			if (_p_stLclSection->d_p_stElement[lLclElement]->cType == SCRT_C_cEntry )
				*_p_szLclFrom = m_fn_RE_vPrintEntry( &m_oLocalRichEdit, _p_stLclSection->d_p_stElement[lLclElement], *_p_szLclFrom, FALSE );
			else
				*_p_szLclFrom = m_fn_RE_vPrintSection( &m_oLocalRichEdit, (SCRT_tdstSection *) _p_stLclSection->d_p_stElement[lLclElement], *_p_szLclFrom, FALSE );
		}

		if ( (lVssElement == _p_stVssSection->lNumberOfElements) && (lLclElement == _p_stLclSection->lNumberOfElements) )
			break;

		if (_p_stLclSection->d_p_stElement[lLclElement]->cType == SCRT_C_cEntry )
		{
			m_fn_RE_vRecaleLine( &m_oVssRichEdit, &m_oLocalRichEdit );
			*_p_szVssFrom = m_fn_RE_vPrintEntry( &m_oVssRichEdit, _p_stVssSection->d_p_stElement[lVssElement], *_p_szVssFrom, TRUE );
			*_p_szLclFrom = m_fn_RE_vPrintEntry( &m_oLocalRichEdit, _p_stLclSection->d_p_stElement[lLclElement], *_p_szLclFrom, FALSE );
		}
		else
			m_fn_RE_vPrintTwoSection
				(	
					(SCRT_tdstSection *) _p_stVssSection->d_p_stElement[ lVssElement ], 
					_p_szVssFrom,
					(SCRT_tdstSection *) _p_stLclSection->d_p_stElement[ lLclElement ],
					_p_szLclFrom 
				);
		lVssElement ++;
		lLclElement ++;
	}

	m_fn_RE_vRecaleLine( &m_oVssRichEdit, &m_oLocalRichEdit );
	*_p_szVssFrom = m_fn_RE_vPrintSectionEnd( &m_oVssRichEdit, _p_stVssSection, *_p_szVssFrom, TRUE );
	*_p_szLclFrom = m_fn_RE_vPrintSectionEnd( &m_oLocalRichEdit, _p_stLclSection, *_p_szLclFrom, FALSE );
}

/*
 ----------------------------------------------------------------------------------------
  Description   : Fill content of the Vss and local RichEdit control
 ----------------------------------------------------------------------------------------
 */
void CConflictDlg::m_fn_RE_vFill( void )
{
	char *szVssFrom, *szLocalFrom;

	szVssFrom = m_szVssSection;
	szLocalFrom = m_szLocalSection;
	if ( ( szVssFrom != NULL) && ( szLocalFrom != NULL) )
	{
		m_fn_RE_vPrintTwoSection( &m_stVssTree, &szVssFrom, &m_stLocalTree, &szLocalFrom );
	}
	else
	{
		if (szVssFrom != NULL)
			m_fn_RE_vPrintSection( &m_oVssRichEdit, &m_stVssTree, m_szVssSection, TRUE );
		if (szLocalFrom != NULL)
			m_fn_RE_vPrintSection( &m_oLocalRichEdit, &m_stLocalTree, m_szLocalSection, FALSE);
		m_fn_RE_vRecaleLine( &m_oVssRichEdit, &m_oLocalRichEdit );
	}
}


/*
 =======================================================================================
	CConflictDlg message handlers
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : WM_INITDIALOG
 ----------------------------------------------------------------------------------------
 */
BOOL CConflictDlg::OnInitDialog() 
{
	char szText[1024];
	BOOL bComp;

	CDialog::OnInitDialog();

	/*
	 * Set sections names
	 */
	GetDlgItem( IDC_STATIC_SECTION )->SetWindowText( m_szSectionName != NULL ? m_szSectionName: "" );
	sprintf( szText, "Vss section\r\nchecked in by %s", m_szUserName != NULL ? m_szUserName: "???" );
	GetDlgItem( IDC_STATIC_VSS )->SetWindowText(  szText );

	/*
	 * create and initialize RichEdit Control
	 */
	DWORD	dwStyle = WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_HSCROLL | ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | ES_AUTOHSCROLL | ES_READONLY;
	RECT	stRect;

	GetDlgItem( IDC_TREE_VSS)->GetWindowRect( &stRect );
	m_oVssRichEdit.Create( dwStyle, stRect, this, IDC_RICHEDIT_VSSSECTION );

	GetDlgItem( IDC_TREE_LOCAL )->GetWindowRect( &stRect );
	m_oLocalRichEdit.Create( dwStyle, stRect, this, IDC_RICHEDIT_LOCALSECTION );

	m_oVssRichEdit.GetDefaultCharFormat( m_stCharFormat );
	m_stCharFormat.dwEffects = 0;
	m_stCharFormat.crTextColor = RGB(255,255,255);
	strcpy ( m_stCharFormat.szFaceName, "Arial" );
	m_stCharFormat.dwMask = CFM_COLOR | CFM_BOLD | CFM_FACE;
	m_oVssRichEdit.SetBackgroundColor( FALSE, 0 );
	m_oVssRichEdit.SetDefaultCharFormat( m_stCharFormat );
	m_oVssRichEdit.SetEventMask( ENM_SCROLL );
	m_oLocalRichEdit.SetBackgroundColor( FALSE, 0 );
	m_oLocalRichEdit.SetDefaultCharFormat( m_stCharFormat );
	m_oLocalRichEdit.SetEventMask( ENM_SCROLL );

	m_p_oVssTree = (CTreeCtrl *) GetDlgItem( IDC_TREE_VSS );
	m_p_oLocalTree = (CTreeCtrl *) GetDlgItem( IDC_TREE_LOCAL );
	m_p_oMergeTree = (CTreeCtrl *) GetDlgItem( IDC_TREE_MERGE );

	if ( g_stWinPref.lUpdateFlags & C_UpdateOption_lShowDifferences)
	{
		/*
		 * build tree associated with vss section
		 */
		SCRT_fn_vInitAndBuildSectionTree( &m_stVssTree, m_szVssSection, NULL);
		if (m_szVssSection == NULL)
		{
			m_stVssTree.bNameIsAllocate = TRUE;
			m_stVssTree.szName = (char *) malloc ( 13 );
			strcpy( m_stVssTree.szName, "<No section>" );
		}

		/*
		 * build tree associated with local section
		 */
		SCRT_fn_vInitAndBuildSectionTree( &m_stLocalTree, m_szLocalSection, NULL);
		if (m_szLocalSection == NULL)
		{
			m_stLocalTree.bNameIsAllocate = TRUE;
			m_stLocalTree.szName = (char *) malloc ( 13 );
			strcpy( m_stLocalTree.szName, "<No section>" );
		}

		/*
		 * compare the two section
		 */
		bComp = SCRT_fn_bCompareSectionTree( &m_stVssTree,&m_stLocalTree );
		m_stLocalTree.cCompState = m_stVssTree.cCompState = SCRT_C_cSame;

		/*
		 * fill tree control with vss section tree
		 */
		m_p_oVssTree->SetImageList( &m_oImageList, TVSIL_NORMAL );
		m_p_oVssTree->DeleteAllItems();
		m_fn_vFillTree( m_p_oVssTree, &m_stVssTree, TVI_ROOT, 0, TRUE );
		
		/*
		 * fill tree control with local section tree
		 */
		m_p_oLocalTree->DeleteAllItems();
		m_p_oLocalTree->SetImageList( &m_oImageList, TVSIL_NORMAL );
		m_fn_vFillTree( m_p_oLocalTree, &m_stLocalTree, TVI_ROOT, 0, FALSE );

		/*
		 * merge tree
		 */
		m_p_oMergeTree->DeleteAllItems();
		m_p_oMergeTree->SetImageList( &m_oImageList, TVSIL_NORMAL );
		m_p_oMergeTree->ShowWindow( FALSE );
			
		/*
		 * Fill Rich edit 
		 */
		m_fn_RE_vFill();

		m_cNbBottomButtons = 3;
	}
	else
	{
		m_oVssRichEdit.SetWindowText( (m_szVssSection == NULL) ? "<no section>" : m_szVssSection );
		m_oLocalRichEdit.SetWindowText( (m_szLocalSection == NULL) ? "<no section>" : m_szLocalSection );
		m_cNbBottomButtons = 2;
		m_bLocalOp = TRUE; /* to avoid doing sometinh in response of RichEdit Control message */
	}

	/*
	 * set bottom buttons ID
	 */
	m_a_uiBottomButton[ 0 ] = IDCANCEL;
	m_a_uiBottomButton[ 1 ] = IDOK;
	m_a_uiBottomButton[ 2 ] = IDC_BUTTON_TREETEXT;

	/*
	 * resize window with Window pref size
	 */
	MoveWindow( &g_stWinPref.stConflictPos );
	m_fn_vChangeDisplayMode( C_cDisplayText );
	
	return TRUE;  
}

/*
 ----------------------------------------------------------------------------------------
  Description   : WM_DESTROY
 ----------------------------------------------------------------------------------------
 */
void CConflictDlg::OnDestroy() 
{
	CDialog::OnDestroy();
	GetWindowRect( &g_stWinPref.stConflictPos );	
	if ( g_stWinPref.lUpdateFlags & C_UpdateOption_lShowDifferences)
	{
		SCRT_fn_vClean( &m_stVssTree );
		SCRT_fn_vClean( &m_stLocalTree );
	}
}

/*
 ----------------------------------------------------------------------------------------
  Description : WM_SIZING
 ----------------------------------------------------------------------------------------
 */
void CConflictDlg::OnSizing( UINT nSide, LPRECT lpRect )
{
	long lWidth = lpRect->right - lpRect->left + 1;
	long lHeight= lpRect->bottom - lpRect->top + 1;

	if (lWidth < C_iConflictMinWidth)
	{
		switch (nSide)
		{
			case WMSZ_BOTTOMLEFT:
			case WMSZ_LEFT:
			case WMSZ_TOPLEFT:
				lpRect->left = lpRect->right - C_iConflictMinWidth;
				break;
			case WMSZ_BOTTOMRIGHT:
			case WMSZ_RIGHT:
			case WMSZ_TOPRIGHT:
				lpRect->right = lpRect->left + C_iConflictMinWidth;
				break;
		}
	}

	if (lHeight < C_iConflictMinHeight)
	{
		switch (nSide)
		{
			case WMSZ_BOTTOM:
			case WMSZ_BOTTOMLEFT:
			case WMSZ_BOTTOMRIGHT:
				lpRect->bottom = lpRect->top + C_iConflictMinHeight;
				break;
			case WMSZ_TOP:
			case WMSZ_TOPLEFT:
			case WMSZ_TOPRIGHT:
				lpRect->top = lpRect->bottom - C_iConflictMinHeight;
		}
	}

	CDialog::OnSizing( nSide, lpRect );
}

/*
 ----------------------------------------------------------------------------------------
  Description : WM_SIZE
 ----------------------------------------------------------------------------------------
 */
void CConflictDlg::OnSize(UINT nType, int cx, int cy) 
{
	RECT	stRectL, stRectR;
	int		iMiddle, iHalfLength;
	int		iHeight;
	long	lWidth;
	char	cButton;

	CDialog::OnSize(nType, cx, cy);

	if ( (nType != SIZE_MINIMIZED) && (GetDlgItem( IDC_STATIC_SECTION ) != NULL) )
	{
		iMiddle = cx / 2;
		iHalfLength = iMiddle - 8;

		/*
		 * resizing top static for section name
		 */
		stRectL.top = 5;
		stRectL.bottom = 20;
		stRectL.left = 5;
		stRectL.right = cx - 5;
		GetDlgItem( IDC_STATIC_SECTION )->MoveWindow( &stRectL, FALSE );

		stRectL.left = 5;
		stRectL.right = stRectL.left + iHalfLength;
		stRectR.left = iMiddle + 3;
		stRectR.right = stRectR.left + iHalfLength;
		/* 
		 * static window for vss/local file 
		 */
		stRectL.top = stRectR.top = 23;
		stRectL.bottom = stRectR.bottom = 50;
		GetDlgItem( IDC_STATIC_VSS )->MoveWindow( &stRectL, FALSE );
		GetDlgItem( IDC_STATIC_LOCAL )->MoveWindow( &stRectR, FALSE );

		/* 
		 * vss and local Tree and Edit window
		 */
		iHeight = cy - 83;

		stRectL.top = stRectR.top = 53;
		//stRectL.bottom = stRectR.bottom = stRectL.top + (iHeight / 2) - 5;
		stRectL.bottom = stRectR.bottom = cy - 30;
		m_oVssRichEdit.MoveWindow( &stRectL, FALSE );
		m_oLocalRichEdit.MoveWindow( &stRectR, FALSE );
		m_p_oVssTree->MoveWindow( &stRectL, FALSE );
		m_p_oLocalTree->MoveWindow( &stRectR, FALSE );

		/* 
		 * merge Tree window
		 */
		/*
		stRectL.bottom = stRectR.bottom = cy - 30;
		stRectL.top = stRectR.top = stRectL.bottom - (iHeight / 2);
		m_p_oMergeTree->MoveWindow( &stRectL, FALSE );
		//GetDlgItem( IDC_TREE_LOCAL )->MoveWindow( &stRectR, FALSE );
		*/

		/*
		 * bottom buttons 
		 */
		stRectL.top = stRectR.top = cy - 25;
		stRectL.bottom = stRectR.bottom = cy - 5;

		lWidth = (cx - 12) / m_cNbBottomButtons;
		stRectL.right = 4;
		for (cButton = 0; cButton < m_cNbBottomButtons; cButton++ )
		{
			stRectL.left = stRectL.right + 1;
			stRectL.right = stRectL.left + lWidth;
			GetDlgItem( m_a_uiBottomButton[ cButton ] )->MoveWindow( &stRectL, FALSE );
		}

		Invalidate();
	}
	
}


/*
 ----------------------------------------------------------------------------------------
  Description   : WM_HELPINFO
 ----------------------------------------------------------------------------------------
 */
BOOL CConflictDlg::OnHelpInfo(HELPINFO* pHelpInfo) 
{
	::WinHelp(this->GetSafeHwnd(), C_szHelpFile, HELP_CONTEXT, IDH_J_CONFLICT );	
	return TRUE;
}


/*
 ----------------------------------------------------------------------------------------
  Description   : BN_CLICKED on IDc_BUTTON_TREETEXT
 ----------------------------------------------------------------------------------------
 */
void CConflictDlg::OnButtonTreetext() 
{
	if (m_cDisplayMode == C_cDisplayText)
		m_fn_vChangeDisplayMode( C_cDisplayTree );
	else
		m_fn_vChangeDisplayMode( C_cDisplayText );
}


/*
 =======================================================================================
	Notify message handle from Tree controls 
 =======================================================================================
 */

/*
 ----------------------------------------------------------------------------------------
  Description   : TVN_SELCHANGED on IDC_TREE_LOCAL
 ----------------------------------------------------------------------------------------
 */
void CConflictDlg::OnSelchangedTreeLocal(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW	*pNMTreeView = (NM_TREEVIEW*) pNMHDR;
	HTREEITEM	hItem;
	
	if (!m_bLocalOp)
	{
		hItem = SCRT_fn_hGetCorrespondantItem( pNMTreeView->itemNew.hItem , m_p_oLocalTree, m_p_oVssTree );
		m_bLocalOp = TRUE;
		m_p_oVssTree->SelectItem( hItem );
		m_bLocalOp = FALSE;
	}
	
	*pResult = 0;
}

/*
 ----------------------------------------------------------------------------------------
  Description   : TVN_ITEMEXPANDED on IDC_TREE_LOCAL
 ----------------------------------------------------------------------------------------
 */
void CConflictDlg::OnItemexpandedTreeLocal(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW	*pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	HTREEITEM	hItem;
	
	if (!m_bLocalOp)
	{
		hItem = SCRT_fn_hGetCorrespondantItem( pNMTreeView->itemNew.hItem , m_p_oLocalTree, m_p_oVssTree );
		m_bLocalOp = TRUE;
		m_p_oVssTree->Expand( hItem, pNMTreeView->action );
		m_bLocalOp = FALSE;
	}

	*pResult = 0;
}


/*
 ----------------------------------------------------------------------------------------
  Description   : TVN_SELCHANGED on IDC_TREE_VSS
 ----------------------------------------------------------------------------------------
 */
void CConflictDlg::OnSelchangedTreeVss(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW	*pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	HTREEITEM	hItem;
	
	if (!m_bLocalOp)
	{
		hItem = SCRT_fn_hGetCorrespondantItem( pNMTreeView->itemNew.hItem , m_p_oVssTree, m_p_oLocalTree );
		m_bLocalOp = TRUE;
		m_p_oLocalTree->SelectItem( hItem );
		m_bLocalOp = FALSE;
	}
		
	*pResult = 0;
}

/*
 ----------------------------------------------------------------------------------------
  Description   : TVN_ITEMEXPANDED on IDC_TREE_VSS
 ----------------------------------------------------------------------------------------
 */
void CConflictDlg::OnItemexpandedTreeVss(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW	*pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	HTREEITEM	hItem;
	
	if (!m_bLocalOp)
	{
		m_bLocalOp = TRUE;
		hItem = SCRT_fn_hGetCorrespondantItem( pNMTreeView->itemNew.hItem , m_p_oVssTree, m_p_oLocalTree );
		m_bLocalOp = FALSE;
		m_p_oLocalTree->Expand( hItem, pNMTreeView->action );
	}
	
	
	*pResult = 0;
}

/*
 =======================================================================================
	Message handle from Rich edit control 
 =======================================================================================
 */


/*
 ----------------------------------------------------------------------------------------
  Description   : EN_VSCROLL on IDC_RICHEDIT_LOCALSECTION
 ----------------------------------------------------------------------------------------
 */
void CConflictDlg::OnVscrollRicheditLocal() 
{
	int iDiff;

	if (!m_bLocalOp)
	{
		m_bLocalOp = TRUE;
		iDiff = m_oLocalRichEdit.GetFirstVisibleLine() - m_oVssRichEdit.GetFirstVisibleLine();
		m_oVssRichEdit.LineScroll( iDiff );
		
		m_bLocalOp = FALSE;
	}
}

/*
 ----------------------------------------------------------------------------------------
  Description   : EN_VSCROLL on IDC_RICHEDIT_VSSSECTION
 ----------------------------------------------------------------------------------------
 */
void CConflictDlg::OnVscrollRicheditVss() 
{
	int iDiff;

	if (!m_bLocalOp)
	{
		m_bLocalOp = TRUE;
		iDiff = m_oVssRichEdit.GetFirstVisibleLine() - m_oLocalRichEdit.GetFirstVisibleLine();
		m_oLocalRichEdit.LineScroll( iDiff );
		m_bLocalOp = FALSE;
	}
}

