// EDACDgNL.cpp : implementation file
//

#include "stdafx.h"

#include "ACP_Base.h"
#include "ITF.h"
#include "TAC.h"
#include "_Ainterf.hpp"
#include "EDAcIRes.h"
#include "cpa_nll.hpp"
#include "EDACDgNL.hpp"
#include "cpa_nll.hpp"
#include "EDACstrg.hpp"
#include "EDACactr.hpp"
#include "EDACdgif.hpp"

#include "TUT.h"    // Tutorial dll include

#undef CPA_WANTS_IMPORT
#undef CPA_EXPORT
#define CPA_WANTS_EXPORT
    #include "_Actors.hpp"
#undef CPA_WANTS_EXPORT
#define CPA_WANTS_IMPORT

//=======================================================================================
//=======================================================================================
void vZoneAddNameToNameList(short _wIndex, CPA_tdoNameList *_p_oNameList)
{ //notify the activation list editor
	tdstModifZone stModifZone;
	stModifZone.wIndex = _wIndex;
	stModifZone.p_oNameList = _p_oNameList;
	g_pclInterface->GetMainWorld()->GetToolDLLWithName(C_szDLLActionName)->OnQueryAction(g_pclInterface, C_uiInsertZone, (long) &stModifZone);
}

void vWayAddNameToNameList(short _wIndex, CPA_tdoNameList *_p_oNameList)
{	//nothing to do for way lists
}

void vZoneRemoveNameFromNameList(short _wIndex, CPA_tdoNameList *_p_oNameList)
{ //notify the activation list editor
	tdstModifZone stModifZone;
	stModifZone.wIndex = _wIndex;
	stModifZone.p_oNameList = _p_oNameList;
	g_pclInterface->GetMainWorld()->GetToolDLLWithName(C_szDLLActionName)->OnQueryAction(g_pclInterface, C_uiRemoveZone, (long) &stModifZone);
}

void vWayRemoveNameFromNameList(short _wIndex, CPA_tdoNameList *_p_oNameList)
{ //nothing to do for way lists
}

//=======================================================================================
//=======================================================================================
static tdstListSpecificActions gs_stZoneActions =
{
	vZoneAddNameToNameList,
	vZoneRemoveNameFromNameList
};

static tdstListSpecificActions gs_stWayActions =
{
	vWayAddNameToNameList,
	vWayRemoveNameFromNameList
};

static tdstListSpecificActions *gs_p_stSpecificActions = NULL;

//=======================================================================================
//=======================================================================================
tdoDummyName::tdoDummyName(CString _csName, tdeShareMode _eShareMode)
{
	m_wInitIndex = -1;
	m_p_oAssociatedName = NULL;
	m_eShareMode = _eShareMode;
	m_csName = _csName;
}

//=======================================================================================
tdoDummyName::tdoDummyName(tdoObjectName *_p_oObjectName, short _wIndex)
{
	m_wInitIndex = _wIndex;
	m_p_oAssociatedName = _p_oObjectName;
	m_eShareMode = _p_oObjectName->m_eGetShareMode();
	m_csName = _p_oObjectName->GetName();
}

//=======================================================================================
//=======================================================================================
tdoDummyNameList::tdoDummyNameList(CString _csName)
{
	m_p_oAssociatedList = NULL;
	m_csName = _csName;
}

//=======================================================================================
tdoDummyNameList::tdoDummyNameList(CPA_tdoNameList *_p_oNameList)
{
	m_p_oAssociatedList = _p_oNameList;
	m_csName = _p_oNameList->GetName();
	POSITION xPos = _p_oNameList->GetHeadPosition();
	short wIndex = 0;
	while ( xPos )
	{
		tdoObjectName *p_oObjectName = _p_oNameList->GetNext(xPos);
		m_clNames.AddTail(new tdoDummyName(p_oObjectName, wIndex));
		wIndex ++;
	}
}

//=======================================================================================
tdoDummyNameList::~tdoDummyNameList()
{
	POSITION xPos;

	xPos = m_clNames.GetHeadPosition();
	while ( xPos )
		delete m_clNames.GetNext(xPos);

	xPos = m_clDeletedNames.GetHeadPosition();
	while ( xPos )
		delete m_clDeletedNames.GetNext(xPos);
}

//=======================================================================================
tdoDummyName *tdoDummyNameList::m_p_oFindActiveName(CString _csName)
{
	POSITION xNamePos = m_clNames.GetHeadPosition();
	while ( xNamePos )
	{
		tdoDummyName *p_oName = m_clNames.GetNext(xNamePos);
		if ( p_oName->m_csGetName() == _csName )
			return p_oName;
	}
	return NULL;
}

//=======================================================================================
tdoDummyName *tdoDummyNameList::m_p_oFindDeletedName(CString _csName)
{
	POSITION xNamePos = m_clDeletedNames.GetHeadPosition();
	while ( xNamePos )
	{
		tdoDummyName *p_oName = m_clDeletedNames.GetNext(xNamePos);
		if ( p_oName->m_csGetName() == _csName )
			return p_oName;
	}
	return NULL;
}

//=======================================================================================
BOOL tdoDummyNameList::m_bNameExists(CString _csName)
{
	if ( m_p_oFindActiveName(_csName) || m_p_oFindDeletedName(_csName) )
		return TRUE;
	else
		return FALSE;
}

//=======================================================================================
tdoDummyName *tdoDummyNameList::m_p_oAddName(CString _csName, tdeShareMode _eShareMode)
{
	tdoDummyName *p_oAddedName = new tdoDummyName(_csName, _eShareMode);
	if ( p_oAddedName )
		m_clNames.AddTail(p_oAddedName);
	return p_oAddedName;
}

//=======================================================================================
BOOL tdoDummyNameList::m_bRemoveName(CString _csName)
{
	POSITION xPos;
	xPos = m_clNames.GetHeadPosition();
	while ( xPos )
	{
		tdoDummyName *p_oDeletedName = m_clNames.GetAt(xPos);
		if ( p_oDeletedName->m_csGetName() == _csName )
		{
			//make the list of deleted names reference this name
			m_clDeletedNames.AddTail(p_oDeletedName);
			//and remove the name from the active list
			m_clNames.RemoveAt(xPos);
			return TRUE;
		}
		else
			m_clNames.GetNext(xPos);
	}
	return FALSE;
}

//=======================================================================================
BOOL tdoDummyNameList::m_bRenameName(CString _csOldName, CString _csNewName)
{
	tdoDummyName *p_oName = m_p_oFindActiveName(_csOldName);
	if ( p_oName )
		p_oName->m_vSetName(_csNewName);

	return p_oName ? TRUE : FALSE;
}

//=======================================================================================
BOOL tdoDummyNameList::m_bReshareName(CString _csName, tdeShareMode _eShareMode)
{
	tdoDummyName *p_oName = m_p_oFindActiveName(_csName);
	if ( p_oName )
		p_oName->m_vSetShareMode(_eShareMode);

	return p_oName ? TRUE : FALSE;
}

//=======================================================================================
void tdoDummyNameList::m_vValidateActiveNames(EdActors_EditNameListsDialog *_p_oDialog)
{
	CPA_tdoNameList *p_oNameList = m_p_oGetAssociatedList();
	ASSERT(p_oNameList); //we validate only active lists, hence the namelist must exist!

	POSITION xNamePos = m_clNames.GetHeadPosition();
	short wObjectIndex = 0;
	while ( xNamePos )
	{
		tdoDummyName *p_oName = m_clNames.GetNext(xNamePos);
		ASSERT(p_oName);
		if ( p_oName->m_bWasHereOnInit() )
		{
			tdoObjectName *p_oObjectName = p_oName->m_p_oGetAssociatedName();
			if ( p_oName->m_bNameChanged() ) //if the name changed
			{
				//update it
				*p_oObjectName = p_oName->m_csGetName();
				//and save the parent name list
        p_oNameList->fn_vUpdateReference(p_oNameList);
			}
			if ( p_oName->m_bShareModeChanged() )
			{
				if
				(
					p_oNameList->m_pEdtListHandler->fn_bChangeNameListShareMode(
						wObjectIndex,
						p_oName->m_eGetShareMode(),
						_p_oDialog->m_p_stArgs->stIn.p_oEditorActor->m_fn_p_oGetObjectList(
							_p_oDialog->m_p_stArgs->stIn.p_c_szScriptName
						)
					)
				)
          p_oNameList->fn_vUpdateReference(p_oNameList);
			}
		}
		else //this is a brand new name in the list
		{
      p_oNameList->fn_vUpdateReference(p_oNameList);
			tdoObjectName *p_oNewObjectName = new tdoObjectName(
				p_oNameList,
				p_oName->m_csGetName(),
				p_oName->m_eGetShareMode()
			);
			//call the specific code for the object lists associated to the name list
			gs_p_stSpecificActions->fn_vWhenNameAdded(wObjectIndex, p_oNameList);
			/*tdstModifZone stModifZone;
			stModifZone.wIndex = wObjectIndex;
			stModifZone.p_oNameList = p_oNameList;
			//should not be called for lists of way names, but Marc says that in that case he will do nothing, because he updates activations
			//that have the name list as father. Since this is not a zone name list, he will not find any activation, hence he will do nothing
			g_pclInterface->GetMainWorld()->GetToolDLLWithName(C_szDLLActionName)->OnQueryAction(g_pclInterface, C_uiInsertZone, (long) &stModifZone);*/
			//TODO: même chose pour les chemins...

			//ask the handler to add the name to the name list
			p_oNameList->m_pEdtListHandler->fn_vAddObjectToAllLists(p_oNewObjectName, wObjectIndex/*, NULL*/);
		}
		wObjectIndex ++;
	}
}

//=======================================================================================
void tdoDummyNameList::m_vInvalidateDeletedNames()
{
	CPA_tdoNameList *p_oNameList = m_p_oGetAssociatedList();

	while ( !m_clDeletedNames.IsEmpty() )
	{
		tdoDummyName *p_oName = m_clDeletedNames.RemoveHead();
		ASSERT(p_oName);
		if ( p_oName->m_bWasHereOnInit() )
		{
			ASSERT(p_oNameList); //if the name was here on init, the list was here too...
			tdoObjectName *p_oObjectName = p_oName->m_p_oGetAssociatedName();

			p_oNameList->m_pEdtListHandler->m_vRemoveObjectFromAllLists(p_oName->m_wGetInitIndex());
			//the list is to be saved
      p_oNameList->fn_vUpdateReference(p_oNameList);
			//call the specific code for the object lists associated to the name list
			gs_p_stSpecificActions->fn_vWhenNameRemoved(p_oName->m_wGetInitIndex(), p_oNameList);
		}
		//remove the name from the list
		delete p_oName;
	}
}

//=======================================================================================
void tdoDummyNameList::m_vFillControls(CListBox *_p_oListBox, CEdit *_p_oCurEdit)
{
	POSITION xNamePos = m_clNames.GetHeadPosition();
	while ( xNamePos )
	{
		tdoDummyName *p_oName = m_clNames.GetNext(xNamePos);
		short wIndex = _p_oListBox->AddString(p_oName->m_csGetName());
		_p_oListBox->SetItemDataPtr(wIndex, p_oName);
	}
	_p_oListBox->SetCurSel(LB_ERR);
	_p_oCurEdit->SetWindowText("");
}

//=======================================================================================
void tdoDummyNameList::m_vSetAssociatedList(CPA_tdoNameList *_p_oNameList, BOOL _bAreYouSure /*= FALSE*/)
{
	ASSERT(_bAreYouSure);
	m_p_oAssociatedList = _p_oNameList;
}

//=======================================================================================
//=======================================================================================
tdoListModifHandler::tdoListModifHandler(CString _csNameListType, CPA_Family *_p_oFamily)
{
	m_csNameListType = _csNameListType;
	m_p_oFamily = _p_oFamily;
	m_p_oDialog = NULL; //will be set if the modifs are accepted by the user
	//Gets the current Family List
	CPA_List<CPA_BaseObject> oNameListList;
	g_pclInterface->GetMainWorld()->fn_lFindObjects(
		&oNameListList,
		"", // obj name
		(char *) LPCTSTR(m_csNameListType), //type
		(CPA_BaseObject *) m_p_oFamily // owner
	);

	POSITION xPos = oNameListList.GetHeadPosition();
	while ( xPos )
	{
		//get the list of names
		CPA_tdoNameList *p_oNameList = (CPA_tdoNameList *) oNameListList.GetNext(xPos);
		//create an associated dummy name list and add it to our active list
		tdoDummyNameList *p_oList = new tdoDummyNameList(p_oNameList);
		m_clLists.AddTail(p_oList);
	}
	//emtpy the list before it is destroyed...
	oNameListList.RemoveAll();
}

//=======================================================================================
tdoListModifHandler::~tdoListModifHandler()
{
	if ( m_bModifsAreAccepted() )
		m_vPerformAllModifs();

	POSITION xPos;

	xPos = m_clLists.GetHeadPosition();
	while ( xPos )
		delete m_clLists.GetNext(xPos);

	xPos = m_clDeletedLists.GetHeadPosition();
	while ( xPos )
		delete m_clDeletedLists.GetNext(xPos);
}

//=======================================================================================
tdoDummyNameList *tdoListModifHandler::m_p_oFindActiveNameList(CString _csName)
{
	POSITION xListPos;

	xListPos = m_clLists.GetHeadPosition();
	while ( xListPos )
	{
		tdoDummyNameList *p_oList = m_clLists.GetNext(xListPos);
		if ( p_oList->m_csGetName() == _csName )
			return p_oList;
	}
	return NULL;
}

//=======================================================================================
tdoDummyNameList *tdoListModifHandler::m_p_oFindDeletedNameList(CString _csName)
{
	POSITION xListPos;

	xListPos = m_clDeletedLists.GetHeadPosition();
	while ( xListPos )
	{
		tdoDummyNameList *p_oList = m_clDeletedLists.GetNext(xListPos);
		if ( p_oList->m_csGetName() == _csName )
			return p_oList;
	}
	return NULL;
}

//=======================================================================================
BOOL tdoListModifHandler::m_bListExists(CString _csName)
{
	if ( m_p_oFindActiveNameList(_csName) || m_p_oFindDeletedNameList(_csName) )
		return TRUE;
	else
		return FALSE;
}

//=======================================================================================
BOOL tdoListModifHandler::m_bNameExists(CString _csName)
{
	POSITION xListPos;

	xListPos = m_clLists.GetHeadPosition();
	while ( xListPos )
	if ( m_clLists.GetNext(xListPos)->m_bNameExists(_csName) )
		return TRUE;

	xListPos = m_clDeletedLists.GetHeadPosition();
	while ( xListPos )
	if ( m_clDeletedLists.GetNext(xListPos)->m_bNameExists(_csName) )
		return TRUE;

	return FALSE;
}

//=======================================================================================
tdoDummyNameList *tdoListModifHandler::m_p_oAcceptListAdd(CString _csName)
{
	if ( !m_bListExists(_csName) )
	{
		tdoDummyNameList *p_oAddedList = new tdoDummyNameList(_csName);
		if ( p_oAddedList )
			m_clLists.AddTail(p_oAddedList);
		return p_oAddedList;
	}
	return NULL;
}

//=======================================================================================
BOOL tdoListModifHandler::m_bAcceptListDelete(CString _csName)
{
	POSITION xPos;
	xPos = m_clLists.GetHeadPosition();
	while ( xPos )
	{
		tdoDummyNameList *p_oDeletedList = m_clLists.GetAt(xPos);
		if ( p_oDeletedList->m_csGetName() == _csName )
		{
			//make the list of deleted names reference this name
			m_clDeletedLists.AddTail(p_oDeletedList);
			//and remove the name from the active list
			m_clLists.RemoveAt(xPos);
			return TRUE;
		}
		else
			m_clLists.GetNext(xPos);
	}
	return FALSE;
}

//=======================================================================================
BOOL tdoListModifHandler::m_bAcceptListRename(CString _csOldName, CString _csNewName)
{
	tdoDummyNameList *p_oList = m_p_oFindActiveNameList(_csOldName);
	if ( p_oList )
		p_oList->m_vSetName(_csNewName);

	return p_oList ? TRUE : FALSE;
}

//=======================================================================================
tdoDummyName *tdoListModifHandler::m_p_oAcceptNameAdd(CString _csListName, CString _csName, tdeShareMode _eShareMode)
{
	tdoDummyNameList *p_oList = m_p_oFindActiveNameList(_csListName);
	if ( p_oList && !p_oList->m_bNameExists(_csName) )
		return p_oList->m_p_oAddName(_csName, _eShareMode);

	return NULL;
}

//=======================================================================================
BOOL tdoListModifHandler::m_bAcceptNameDelete(CString _csListName, CString _csName)
{
	tdoDummyNameList *p_oList = m_p_oFindActiveNameList(_csListName);
	if ( p_oList )
		return p_oList->m_bRemoveName(_csName);

	return FALSE;
}

//=======================================================================================
BOOL tdoListModifHandler::m_bAcceptNameRename(CString _csListName, CString _csOldName, CString _csNewName)
{
	tdoDummyNameList *p_oList = m_p_oFindActiveNameList(_csListName);
	if ( p_oList )
		return p_oList->m_bRenameName(_csOldName, _csNewName);

	return FALSE;
}

//=======================================================================================
BOOL tdoListModifHandler::m_bAcceptNameReshare(CString _csListName, CString _csName, tdeShareMode _eShareMode)
{
	tdoDummyNameList *p_oList = m_p_oFindActiveNameList(_csListName);
	if ( p_oList )
		return p_oList->m_bReshareName(_csName, _eShareMode);

	return FALSE;
}

//=======================================================================================
void tdoListModifHandler::m_vPerformAllModifs()
{
	//first of all, remove all the deleted lists
	while ( !m_clDeletedLists.IsEmpty() )
	{
		tdoDummyNameList *p_oList = m_clDeletedLists.RemoveHead();
		if ( p_oList )
		{
			if ( p_oList->m_bWasHereOnInit() ) //if the list was not here from the start
			{
				CPA_tdoNameList *p_oNameList = p_oList->m_p_oGetAssociatedList();
				//tell the coherence manager that the name list no longer exists...
				g_oCoherenceManager.m_fn_vDestroyObject(p_oNameList);
				//tel the name list not to save itself
				//TODO: vérifier que le pointeur sur l'objet n'est pas utilisé par la callback
				//de sauvegarde quand c'est une notification de destruction...
				//au besoin passer NULL comme objet pour un NotifyDelete
				p_oNameList->fn_vNotifyUnSave();
				//start by removing the deleted names from the list
				p_oList->m_vInvalidateDeletedNames();
				//empty the list of names
				p_oNameList->RemoveAll();
				//and destroy it (it will be removed from the reachable list automatically)
				delete p_oNameList;
			}
			delete p_oList;
		}
	}

	//now scan all active lists
	POSITION xListPos = m_clLists.GetHeadPosition();
	while ( xListPos )
	{
		tdoDummyNameList *p_oList = m_clLists.GetNext(xListPos);
		if ( p_oList )
		{
			CPA_tdoNameList *p_oNameList = NULL;
			//start by creating the new lists
			if ( !p_oList->m_bWasHereOnInit() )
			{
				p_oNameList = new CPA_tdoNameList(
					(char *) LPCTSTR(m_csNameListType), /* type name */
					(CPA_BaseObject *) m_p_oFamily, /* owner */
					FALSE, //section does not exist yet
					p_oList->m_csGetName() /* object name */
				); /* last 2 args are optional */
				if ( p_oNameList )
				{
					//give the true list to the dummy list, so that the rest of the processing can continue
					p_oList->m_vSetAssociatedList(p_oNameList, TRUE);
					p_oNameList->fn_vNotifySave();
				}
			}
			else
				p_oNameList = p_oList->m_p_oGetAssociatedList();

			if ( m_bModifsAreAccepted() )
			{	//make the model use the selected list upon return
				if ( m_p_oDialog->m_p_oListSelectedForModel == p_oList )
					m_p_oDialog->m_p_stArgs->stOut.p_oNameListSelectedForModel = p_oList->m_p_oGetAssociatedList();
			}

			//rename it if necessary
			if ( p_oNameList && p_oList->m_bNameChanged() && p_oNameList->fn_eRename(p_oList->m_csGetName()) == E_mc_None )
			{ // if the object was successfully renamed
				//notify all models referencing this list
				CPA_List<CPA_BaseObject> oFatherList;
				short wNbFathers = g_oCoherenceManager.m_fn_iGetFatherList(p_oNameList, &oFatherList);
				while ( wNbFathers )
				{
					CPA_SaveObject *p_oCurFather = (CPA_SaveObject *) oFatherList.RemoveHead();
					if ( p_oCurFather )
						p_oCurFather->fn_vNotifySave();
					wNbFathers --;
				}
			}
			//start by removing the deleted names from the list
			p_oList->m_vInvalidateDeletedNames();
			//now create the added names
			p_oList->m_vValidateActiveNames(m_p_oDialog);
		}
	}
}

//=======================================================================================
void tdoListModifHandler::m_vFillControls(CListBox *_p_oListBox, CEdit *_p_oCurEdit, tdoDummyNameList *_p_oCurrentSelectedList)
{
	_p_oListBox->ResetContent();
	POSITION xListPos = m_clLists.GetHeadPosition();
	while ( xListPos )
	{
		tdoDummyNameList *p_oList = m_clLists.GetNext(xListPos);
		if ( _p_oCurrentSelectedList ) //we display the contents of the current list
		{
			if ( p_oList == _p_oCurrentSelectedList )
			{
				p_oList->m_vFillControls(_p_oListBox, _p_oCurEdit);
				break;
			}
		}
		else //we just display the list of lists
		{
			short wIndex = _p_oListBox->AddString(p_oList->m_csGetName());
			_p_oListBox->SetItemDataPtr(wIndex, p_oList);
		}
	}
}

//=======================================================================================
tdoDummyNameList *tdoListModifHandler::m_p_oGetListforNameList(CPA_tdoNameList *_p_oNameList)
{
	if ( _p_oNameList )
	{
		POSITION xPos = m_clLists.GetHeadPosition();
		while ( xPos )
		{
			tdoDummyNameList *p_oList = m_clLists.GetNext(xPos);
			if ( p_oList && p_oList->m_p_oGetAssociatedList() == _p_oNameList )
				return p_oList;
		}
	}
	return NULL;
}

//=======================================================================================
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// EdActors_EditNameListsDialog dialog


BOOL EdActors_EditNameListsDialog::PreTranslateMessage(MSG* pMsg)
{
 switch( pMsg->message )
 {
 case WM_LBUTTONDOWN:
	if ( pMsg->hwnd == m_p_oItemListBox->m_hWnd )
		return m_bIconClickedInListBox(CPoint(LOWORD(pMsg->lParam), HIWORD(pMsg->lParam)));
	//fall through
 case WM_MOUSEMOVE:
 case WM_LBUTTONUP:
 case WM_RBUTTONDOWN:
 case WM_MBUTTONDOWN:
 case WM_RBUTTONUP:
 case WM_MBUTTONUP:
  m_poToolTip->RelayEvent(pMsg);
 }

 return CDialog::PreTranslateMessage(pMsg);
}

//==========================================================================
//==========================================================================

EdActors_EditNameListsDialog::~EdActors_EditNameListsDialog()
{
	if ( m_poToolTip )
	{
		delete m_poToolTip;
		m_poToolTip = NULL;
	}

	if ( m_p_oListModifHandler )
	{
		delete m_p_oListModifHandler;
		m_p_oListModifHandler = NULL;
	}
}

//==========================================================================
//==========================================================================

EdActors_EditNameListsDialog::EdActors_EditNameListsDialog(tdstCarEditNameListsDialogArgs *p_stArgs, CWnd* pParent /*=NULL*/)
: CDialog(EdActors_EditNameListsDialog::IDD, &g_oBaseFrame)
{
	//messages come from user input, unless otherwise specified
	m_bAutodispatch = FALSE;
	m_bUserEditedAList = FALSE;
	m_eEditMode = E_em_None;
  m_p_oDefaultButton = m_p_oOkButton;

	m_p_stArgs = p_stArgs;
	//{{AFX_DATA_INIT(EdActors_EditNameListsDialog)
	// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	m_p_oListModifHandler = new tdoListModifHandler(
		m_p_stArgs->stIn.p_c_szNameListType,
		m_p_stArgs->stIn.p_oEditorActor->m_pclActor->m_pub_fn_pclGetFamily()
	);
	//here is the only list-type specific code of the dialog: find out which
	//structure to use
	if ( strstr(m_p_stArgs->stIn.p_c_szNameListType, C_szWayName) )
		gs_p_stSpecificActions = &gs_stWayActions;
	else
		gs_p_stSpecificActions = &gs_stZoneActions;
}

//==========================================================================
//==========================================================================

void EdActors_EditNameListsDialog::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(EdActors_EditNameListsDialog)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

//==========================================================================
//==========================================================================

BEGIN_MESSAGE_MAP(EdActors_EditNameListsDialog, CDialog)
	//{{AFX_MSG_MAP(EdActors_EditNameListsDialog)
	ON_BN_CLICKED(IDC_BUTTON_ENL_CURRENTMODE, OnEnlSwapEditModeButtonClicked)
	ON_BN_CLICKED(IDC_RADIO_ENL_COMMON, OnEnlShareModeRadioButtonClicked)
	ON_WM_DRAWITEM()
	ON_LBN_SELCHANGE(IDC_LIST_ENL_ITEMLIST, OnEnlListBoxSelChange)
	ON_EN_CHANGE(IDC_EDIT_ENL_NAME, OnEnlNameEditChange)
	ON_BN_CLICKED(IDC_BUTTON_ENL_ADD, OnEnlAddButtonClicked)
	ON_BN_CLICKED(IDC_BUTTON_ENL_DELETE, OnEnlDeleteButtonClicked)
	ON_BN_CLICKED(IDC_BUTTON_ENL_RENAME, OnEnlRenameButtonClicked)
	ON_WM_CLOSE()
	ON_BN_CLICKED(IDC_RADIO_ENL_SHARED, OnEnlShareModeRadioButtonClicked)
	ON_BN_CLICKED(IDC_RADIO_ENL_SPECIFIC, OnEnlShareModeRadioButtonClicked)
	ON_BN_CLICKED(IDC_DEFAULTBUTTON, OnEnlDefaultButtonClicked)
	ON_NOTIFY_EX(TTN_NEEDTEXT, 0, m_bGetToolTipText)
    ON_WM_DESTROY()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// EdActors_EditNameListsDialog message handlers

void EdActors_EditNameListsDialog::m_vSetDefaultButton(CButton *_p_oButton)
{
	m_p_oDefaultButton = _p_oButton;
	return; //until we have something that works, do nothing...
}

//==========================================================================
//==========================================================================

BOOL EdActors_EditNameListsDialog::m_bGetToolTipText(UINT uiControlId, NMHDR *pNMHDR, LRESULT *pResult )
{
	TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;

	//since uiControlId is not used, we can use it as a local variable...
	uiControlId = pNMHDR->idFrom;
	uiControlId = ::GetDlgCtrlID((HWND)uiControlId);

	short wIndex;
	for
	(
		wIndex = 0;
		wIndex < sizeof(m_a13_stToopTipData) / sizeof(m_a13_stToopTipData[0]);
		wIndex ++
	)
	if ( m_a13_stToopTipData[wIndex].uiControlId == uiControlId )
	{
		strcpy(pTTT->szText, m_a13_stToopTipData[wIndex].pszTipText);
		return TRUE;
	}
	return FALSE;
}

//==========================================================================
//==========================================================================

void EdActors_EditNameListsDialog::OnEnlNameEditChange()
{
	//do not handle calls generated by automodifications
	if ( m_bAutodispatch )
		return;
	m_bAutodispatch = TRUE;

	CString oNewNameString;
	short wIndex = m_p_oItemListBox->GetCurSel();
	m_p_oNameEdit->GetWindowText(oNewNameString);
  oNewNameString = g_pclInterface->GetInterface()->GetPrefixedName(oNewNameString);

	if ( oNewNameString.IsEmpty() )
	{
		//there is no item with such name, so unselect all items in the listbox
		m_p_oAddButton->EnableWindow(FALSE);
		m_p_oItemListBox->SetCurSel(LB_ERR);
    m_vSetDefaultButton(m_p_oOkButton);
		M_vFakeMessage(OnEnlListBoxSelChange);
	}
	else // there is text in the edit
	{
		//look for an object with the same name
		CPA_List<CPA_BaseObject> oItemList;
		g_pclInterface->GetMainWorld()->fn_lFindObjects(
			&oItemList,
			oNewNameString, // obj name
			(m_eEditMode == E_em_NameListEdit) //the combo lists names ?
			? C_szObjectNameType //the combo lists object names -> look for object name
			: (char *) m_p_stArgs->stIn.p_c_szNameListType, //else look for name lists
			(m_eEditMode == E_em_NameListEdit) //the combo lists names ?
			? m_p_oCurrentSelectedList->m_p_oGetAssociatedList() //owner of a name is the name list
			: (CPA_BaseObject *) m_p_stArgs->stIn.p_oEditorActor->m_pclActor->m_pub_fn_pclGetFamily() //owner of a list is the family
		);
		short wFoundItem = oItemList.GetCount();
		if ( !wFoundItem ) //now search in the dummy names too...
		{
			wFoundItem = (m_eEditMode == E_em_NameListEdit)
			? (m_p_oListModifHandler->m_bNameExists(oNewNameString) ? 1 : 0)
			: (m_p_oListModifHandler->m_bListExists(oNewNameString) ? 1 : 0);
		}
		//there is at most one item with such a	name...
		ASSERT(wFoundItem <= 1);
		if ( wFoundItem ) //we found an item with that name
		{
			BOOL bItemIsInListBox = FALSE;
			CString csItemName;
			short wNbItems = m_p_oItemListBox->GetCount();
			for ( short wItem = 0; wItem < wNbItems; wItem ++ )
			{
				//make the list box select the object with the same name. Since we cannot get the
				//inde from the item data, we have to search for the string ourselves
				csItemName = (m_eEditMode == E_em_NameListEdit)
				? ((tdoDummyName *) m_p_oItemListBox->GetItemDataPtr(wItem))->m_csGetName()
				: ((tdoDummyNameList *) m_p_oItemListBox->GetItemDataPtr(wItem))->m_csGetName();
				if ( csItemName == oNewNameString )
				{
					bItemIsInListBox = TRUE;
					m_p_oItemListBox->SetCurSel(wItem);
					M_vFakeMessage(OnEnlListBoxSelChange);
					break;
				}
			}
			if ( !bItemIsInListBox ) //we found the name in a "deleted" list
			{
				//we cannot re-add it
				m_p_oAddButton->EnableWindow(FALSE);
				//nor delete it again
				m_p_oDeleteButton->EnableWindow(FALSE);
				//nor name an item with this name, else we would have at the same time
				//a deleted and an active item of the same name...
				m_p_oRenameButton->EnableWindow(wIndex != LB_ERR);
			}
      m_vSetDefaultButton(m_p_oSwapEditModeButton);
		}
		else //no object was found with the same name (which is not empty, BTW)
		{
			m_p_oAddButton->EnableWindow(TRUE);
			//the names are not equal, so we cannot delete
			m_p_oDeleteButton->EnableWindow(FALSE);
			//we can rename if an item is selected
			m_p_oRenameButton->EnableWindow(wIndex != LB_ERR);
			//we can delete if an item is selected, and if we have the right to do so:
			//the item is an object name or it is a name list with no associated object list
			//that is not the list of the model
			/*m_p_oDeleteButton->EnableWindow(
				(wIndex != LB_ERR)
				&&
				(
					(m_eEditMode == E_em_NameListEdit)
					||
					(
						(m_p_stArgs->stOut.p_oNameListSelectedForModel != m_p_oCurrentSelectedList->m_p_oGetAssociatedList())
						&& (m_p_oCurrentSelectedList->m_p_oGetAssociatedList()->m_pEdtListHandler->fn_oGetListOfEdtLists()->GetCount() <= 0)
					)
				)
			);*/
      m_vSetDefaultButton(m_p_oAddButton);
		}
		//empty the list, else the destructor will ASSERT()
		oItemList.RemoveAll();
	}

	m_bAutodispatch = FALSE;
}

//==========================================================================
//==========================================================================

void EdActors_EditNameListsDialog::OnEnlShareModeRadioButtonClicked()
{
	//do not handle calls generated by automodifications
	if ( m_bAutodispatch )
		return;
	m_bAutodispatch = TRUE;

	short wIndex = m_p_oItemListBox->GetCurSel();
	if ( wIndex != LB_ERR )
	{
		tdoDummyName *p_oName = (tdoDummyName *) m_p_oItemListBox->GetItemDataPtr(wIndex);
		tdeShareMode ePreviousMode = p_oName->m_eGetShareMode();

		tdeShareMode eNewMode = m_eGetRadioShareMode();
		ASSERT(eNewMode != E_sm_None);

		//if the model has no instance, or if he has instances he does not set the attribute to to Virge,
		//accept and perform the change
		if ( m_p_stArgs->stIn.bModelCanSelectANameList || eNewMode != E_sm_Virge )
		{
			//change the share mode of the currently selected name
			m_p_oListModifHandler->m_bAcceptNameReshare(m_p_oCurrentSelectedList->m_csGetName(), p_oName->m_csGetName(), eNewMode);
			//make the listbox redraw the item
			CRect oItemRect;
			m_p_oItemListBox->GetItemRect(wIndex, &oItemRect);
			m_p_oItemListBox->InvalidateRect(oItemRect);
			//the list was edited, hence we cannot get back to list selection mode
			m_bUserEditedAList = TRUE;
			m_p_oSwapEditModeButton->EnableWindow(FALSE);
		}
		else //we do not accept the change
			m_vSetRadioShareMode(ePreviousMode); //restore the buttons to what they were before
	}

  m_vSetDefaultButton(m_p_oOkButton);

  m_bAutodispatch = FALSE;
}

//==========================================================================
//==========================================================================

void EdActors_EditNameListsDialog::OnEnlSwapEditModeButtonClicked()
{
	//do not handle calls generated by automodifications
	if ( m_bAutodispatch )
		return;
	m_bAutodispatch = TRUE;

	//empty the list box anyway
	//m_p_oItemListBox->ResetContent();

	if ( m_eEditMode != E_em_NameListEdit ) //we enter name list edition mode
	{
    ASSERT(m_p_oCurrentSelectedList);
		m_eEditMode = E_em_NameListEdit;

		//update the various displays
		m_p_oSwapEditModeButton->SetWindowText("Swap to name list selection mode");
		m_p_oEditGroupTitle->SetWindowText("Current selected name");
		m_p_oItemListTitle->SetWindowText(
			CString("List of names in list ") + m_p_oCurrentSelectedList->m_csGetName()
		);

		m_p_oVirgeRadioButton->ShowWindow(TRUE);
		m_p_oSharedRadioButton->ShowWindow(TRUE);
		m_p_oCommonRadioButton->ShowWindow(TRUE);

    //a new item can be set to Virge only if there are no object list or if the name list
		//already has a virge field
		CPA_tdoNameList *p_oNameList = m_p_oCurrentSelectedList->m_p_oGetAssociatedList();
		m_p_oVirgeRadioButton->EnableWindow(
			m_p_stArgs->stIn.bModelCanSelectANameList
			|| (!p_oNameList || p_oNameList->m_bHasAVirgeField())
		);

		//fill the listbox with the contents of the current name list
		m_p_oListModifHandler->m_vFillControls(m_p_oItemListBox, m_p_oNameEdit, m_p_oCurrentSelectedList);
		/*POSITION xPos;
		m_p_oCurrentSelectedNameList->GetHeadElement(xPos);
		while ( xPos )
		{
			tdoObjectName *p_oName = m_p_oCurrentSelectedNameList->GetNext(xPos);
			int iIndex = m_p_oItemListBox->AddString(p_oName->GetName());
			m_p_oItemListBox->SetItemData(iIndex, p_oName->m_eGetShareMode());
		}
		m_p_oItemListBox->SetCurSel(LB_ERR);*/
		M_vFakeMessage(OnEnlListBoxSelChange);
	}
	else if ( m_eEditMode != E_em_NameListSelect ) //we enter name list choice mode
	{
		m_eEditMode = E_em_NameListSelect;

		m_p_oSwapEditModeButton->SetWindowText("Swap to list edition mode");
		m_p_oEditGroupTitle->SetWindowText("Current selected list");
		m_p_oItemListTitle->SetWindowText(
			CString("List of name lists for family ")
			+ ((CPA_BaseObject *) m_p_stArgs->stIn.p_oEditorActor->m_pclActor->m_pub_fn_pclGetFamily())->GetName()
		);

		m_p_oVirgeRadioButton->ShowWindow(FALSE);
		m_p_oSharedRadioButton->ShowWindow(FALSE);
		m_p_oCommonRadioButton->ShowWindow(FALSE);

		//fill the listbox with the list of name lists
		m_p_oListModifHandler->m_vFillControls(m_p_oItemListBox, m_p_oNameEdit, NULL);
		/*//Gets the current Family List
		CPA_ReachableObjectList oNameListList;
		g_pclInterface->GetMainWorld()->fn_lFindObjects(
			&oNameListList,
			"", // obj name
			(char *) m_p_stArgs->stIn.p_c_szNameListType,
			(CPA_ReachableObject *) m_p_stArgs->stIn.p_oEditorActor->m_fn_pclGetFamily() // owner
		);

		POSITION xPos;
		oNameListList.GetHeadElement(xPos);
		while ( xPos )
		{
			CPA_tdoNameList *p_oNameList = (CPA_tdoNameList *) oNameListList.GetNext(xPos)->GetObject();
			int iIndex = m_p_oItemListBox->AddString(p_oNameList->GetName());
			m_p_oItemListBox->SetItemDataPtr(iIndex, p_oNameList);
		}
		//emtpy the list before it is destroyed...
		oNameListList.RemoveAll();

		m_p_oItemListBox->SetCurSel(LB_ERR);*/
		M_vFakeMessage(OnEnlListBoxSelChange);
	}
	else
		ASSERT(FALSE);

  m_vSetDefaultButton(m_p_oOkButton);

	m_bAutodispatch = FALSE;
}

//==========================================================================
//==========================================================================

void EdActors_EditNameListsDialog::OnEnlListBoxSelChange()
{
	//do not handle calls generated by automodifications
	if ( m_bAutodispatch )
		return;
	m_bAutodispatch = TRUE;

	int iIndex = m_p_oItemListBox->GetCurSel();

	//either the change failed, and the edit is empty, or is succeded and the edit
	//holds the name of the selected item
	//-> and nothing can be done with the rename button in either case
	m_p_oRenameButton->EnableWindow(FALSE);

	//irrelevant for E_em_NameListSelect, but useful when no item is selected...
  BOOL bCanTakeVirgeMode =
	!m_p_oCurrentSelectedList
	|| m_p_stArgs->stIn.bModelCanSelectANameList
	|| !m_p_oCurrentSelectedList->m_bWasHereOnInit()
	|| m_p_oCurrentSelectedList->m_p_oGetAssociatedList()->m_bHasAVirgeField();

  if ( iIndex == LB_ERR )
	{
		//we can swap mode only from list edition to list selection, and if the current list
		//was not modified
		m_p_oSwapEditModeButton->EnableWindow((m_eEditMode == E_em_NameListSelect) ? FALSE : !m_bUserEditedAList);
		//no item is selected yet, so clear the other controls
		m_p_oNameEdit->SetWindowText("");
		//m_p_oVirgeRadioButton->EnableWindow(TRUE);
		m_p_oSharedRadioButton->EnableWindow(TRUE);
		m_p_oCommonRadioButton->EnableWindow(TRUE);
		m_p_oVirgeRadioButton->EnableWindow(bCanTakeVirgeMode);
		m_p_oDeleteButton->EnableWindow(FALSE);
		//we cannot add, because empty is not a defined name
		m_p_oAddButton->EnableWindow(FALSE);
	}
	else //a valid item was selected
	{
		/*m_p_oVirgeRadioButton->EnableWindow(TRUE);
		m_p_oSharedRadioButton->EnableWindow(TRUE);
		m_p_oCommonRadioButton->EnableWindow(TRUE);*/
		if ( m_eEditMode == E_em_NameListSelect ) //we display the list of name lists
		{
			//remember which list was selected last
			m_p_oCurrentSelectedList = (tdoDummyNameList *) m_p_oItemListBox->GetItemDataPtr(iIndex);
			//we can enter list edit mode only if the is the list of the model
			m_p_oSwapEditModeButton->EnableWindow(m_p_oCurrentSelectedList == m_p_oListSelectedForModel);
			//we can delete the list only if it has no associated object list, or if it is a list we
			//just created (hence it does not have an associated existing name list, hence no object
			//list will be affected either
			CPA_tdoNameList *p_oNameList = m_p_oCurrentSelectedList->m_p_oGetAssociatedList();
  		m_p_oDeleteButton->EnableWindow(
	   		(!p_oNameList)
				|| (p_oNameList->m_pEdtListHandler->fn_oGetListOfEdtLists()->GetCount() <= 0)
  		);
		}
		else if ( m_eEditMode == E_em_NameListEdit ) //we display the list of names for the model's list
		{
			tdoDummyName *p_oName = (tdoDummyName *) m_p_oItemListBox->GetItemDataPtr(iIndex);
			//set the share buttons according to the selected item status
			m_vSetRadioShareMode(p_oName->m_eGetShareMode());
			//if the name was here on init, and is Virge, and the name list has object list, the mode cannot be changed
			BOOL bCannotLeaveVirgeMode =
			(
				p_oName->m_bWasHereOnInit() && p_oName->m_p_oGetAssociatedName()->m_eGetShareMode() == E_sm_Virge
				&& m_p_oCurrentSelectedList->m_p_oGetAssociatedList()->m_pEdtListHandler->fn_oGetListOfEdtLists()->GetCount() > 0 //there are object lists
			);
			m_p_oCommonRadioButton->EnableWindow(!bCannotLeaveVirgeMode);
			m_p_oSharedRadioButton->EnableWindow(!bCannotLeaveVirgeMode);
			m_p_oVirgeRadioButton->EnableWindow(bCanTakeVirgeMode);
			//we can go back to selection mode only if the current list has not been edited
			m_p_oSwapEditModeButton->EnableWindow(!m_bUserEditedAList);
			//we can delete the current name from the list only if the section for the associated name list
			//does not exist yet or if this is a brand new list
      m_p_oDeleteButton->EnableWindow(
				!m_p_oCurrentSelectedList->m_bWasHereOnInit()
				|| !m_p_oCurrentSelectedList->m_p_oGetAssociatedList()->fn_bSectionExists()
			);
		}
		else
			ASSERT(FALSE);

		CString csNameToEdit, csNameInEdit;
		m_p_oNameEdit->GetWindowText(csNameInEdit);
    csNameInEdit = g_pclInterface->GetInterface()->GetPrefixedName(csNameInEdit);
		if ( m_eEditMode == E_em_NameListEdit )
			csNameToEdit = ((tdoDummyName *) m_p_oItemListBox->GetItemDataPtr(iIndex))->m_csGetName();
		else
			csNameToEdit = ((tdoDummyNameList *) m_p_oItemListBox->GetItemDataPtr(iIndex))->m_csGetName();
		//put the name in the edit
		if ( csNameInEdit != csNameToEdit )
			m_p_oNameEdit->SetWindowText(csNameToEdit);
		//we cannot add another item with the name of the selected item
		m_p_oAddButton->EnableWindow(FALSE);
	}

  m_vSetDefaultButton(m_p_oOkButton);

	m_bAutodispatch = FALSE;
}

//==========================================================================
//==========================================================================

void EdActors_EditNameListsDialog::OnEnlAddButtonClicked()
{
	//do not handle calls generated by automodifications
	if ( m_bAutodispatch )
		return;
	m_bAutodispatch = TRUE;

	CString csEditText;
	m_p_oNameEdit->GetWindowText(csEditText);
  csEditText = g_pclInterface->GetInterface()->GetPrefixedName(csEditText);

	if ( m_eEditMode == E_em_NameListSelect )	//we add a list
	{
		tdoDummyNameList *p_oAddedList = m_p_oListModifHandler->m_p_oAcceptListAdd(csEditText);
		if ( p_oAddedList )
		{
			if ( m_p_oListSelectedForModel == NULL )
				m_p_oListSelectedForModel = p_oAddedList;
			short wIndex = m_p_oItemListBox->AddString(p_oAddedList->m_csGetName());
			m_p_oItemListBox->SetItemDataPtr(wIndex, p_oAddedList);
			m_p_oItemListBox->SetCurSel(wIndex);
			M_vFakeMessage(OnEnlListBoxSelChange);
			if ( m_p_oListSelectedForModel == p_oAddedList ) //if this is the list for the model
				M_vFakeMessage(OnEnlSwapEditModeButtonClicked); //go directly to edit it
		}
	}
	else //we add a name in the current list
	{
		tdeShareMode eShareMode = m_eGetRadioShareMode();
		tdoDummyName *p_oAddedName = m_p_oListModifHandler->m_p_oAcceptNameAdd(
			m_p_oCurrentSelectedList->m_csGetName(),
			csEditText,
			eShareMode == E_sm_None ? E_sm_Common : eShareMode
		);
		if ( p_oAddedName )
		{
			m_bUserEditedAList = TRUE;
			short wIndex = m_p_oItemListBox->AddString(p_oAddedName->m_csGetName());
			m_p_oItemListBox->SetItemDataPtr(wIndex, p_oAddedName);
			m_p_oItemListBox->SetCurSel(wIndex);
			M_vFakeMessage(OnEnlListBoxSelChange);
		}
	}

	//next time we press RETURN will activate the Ok button
  m_vSetDefaultButton(m_p_oOkButton);

  m_bAutodispatch = FALSE;
}

//==========================================================================
//==========================================================================

void EdActors_EditNameListsDialog::OnEnlDeleteButtonClicked()
{
	//do not handle calls generated by automodifications
	if ( m_bAutodispatch )
		return;
	m_bAutodispatch = TRUE;

	CString csEditText;
	m_p_oNameEdit->GetWindowText(csEditText);
  csEditText = g_pclInterface->GetInterface()->GetPrefixedName(csEditText);

	short wSelIndex = m_p_oItemListBox->GetCurSel();
	ASSERT(wSelIndex != LB_ERR); //just a failsafe, should never occur...

	tdoDummyNameList *p_oList = (tdoDummyNameList *) m_p_oItemListBox->GetItemDataPtr(wSelIndex);
	CPA_tdoNameList *p_oNameList = p_oList->m_p_oGetAssociatedList();
  if ( p_oNameList && (m_eEditMode == E_em_NameListSelect) ) //we delete an existing name list
	{
		//if some instances use that list, ask the operator if he want to proceed
		CList<CPA_BaseObject *, CPA_BaseObject *> oFatherList;
		int iNbFathers = g_oCoherenceManager.m_fn_iGetFatherList(p_oNameList, &oFatherList);
		if ( iNbFathers > 0 )
		{
			CString csFatherNames
			= "The following models (and their instances) are using this name list.\n"
			"Are you sure you want to destroy it ?\n\n";
			POSITION xFatherPos;
			xFatherPos = oFatherList.GetHeadPosition();
			//add each name to the string
			while ( xFatherPos )
			{
				csFatherNames += oFatherList.GetNext(xFatherPos)->GetName();
				csFatherNames += "\n";
			}

			//ask if the designer wants to destroy the object list
      if ( AfxMessageBox(csFatherNames, MB_YESNO) != IDYES )
			{
				m_bAutodispatch = FALSE;
				return;
			}
		}
	}

	BOOL bResult = FALSE;
  if ( m_eEditMode == E_em_NameListSelect ) //we delete a list
		bResult = m_p_oListModifHandler->m_bAcceptListDelete(csEditText);
  else //we delete a name from the current list
		bResult = m_p_oListModifHandler->m_bAcceptNameDelete(
			m_p_oCurrentSelectedList->m_csGetName(), csEditText
		);
	//update display
	if ( bResult )
	{
		if ( m_eEditMode == E_em_NameListSelect )	//we delete a list
		{
			if ( m_p_oListSelectedForModel == p_oList ) //if this is the list selected for the model
			{
				//clear the selection
				m_p_oListSelectedForModel = NULL;
				//redisplay all controls as should be
				m_p_oItemListBox->Invalidate();
			}
		}
		else
			m_bUserEditedAList = TRUE;
		m_p_oItemListBox->DeleteString(wSelIndex);
		m_p_oItemListBox->SetCurSel(LB_ERR);
		M_vFakeMessage(OnEnlListBoxSelChange);
	}

  m_vSetDefaultButton(m_p_oOkButton);

	m_bAutodispatch = FALSE;
}

//==========================================================================
//==========================================================================

void EdActors_EditNameListsDialog::OnEnlRenameButtonClicked()
{
	//do not handle calls generated by automodifications
	if ( m_bAutodispatch )
		return;
	m_bAutodispatch = TRUE;

	short wSelIndex = m_p_oItemListBox->GetCurSel();
	ASSERT(wSelIndex != LB_ERR); //just a failsafe, should never occur...

	CString csEditText, csOriginalName;
	m_p_oNameEdit->GetWindowText(csEditText);
  csEditText = g_pclInterface->GetInterface()->GetPrefixedName(csEditText);
	csOriginalName = (m_eEditMode == E_em_NameListEdit)
	? ((tdoDummyName *) m_p_oItemListBox->GetItemDataPtr(wSelIndex))->m_csGetName()
	: ((tdoDummyNameList *) m_p_oItemListBox->GetItemDataPtr(wSelIndex))->m_csGetName();

	if ( csOriginalName != csEditText ) //just a failsafe, should never occur...
	{
		BOOL bResult = FALSE;
		if ( m_eEditMode == E_em_NameListSelect )	//we rename a list
			bResult = m_p_oListModifHandler->m_bAcceptListRename(csOriginalName, csEditText);
		else //we rename a name in the current list
			bResult = m_p_oListModifHandler->m_bAcceptNameRename(
				m_p_oCurrentSelectedList->m_csGetName(), csOriginalName, csEditText
			);

		//update display
		if ( bResult )
		{
			/*//we cannot add or rename again, since an object with the name in the edit now exists
			m_p_oAddButton->EnableWindow(FALSE);
			m_p_oRenameButton->EnableWindow(FALSE);
			//but we can delete because the forementionned object is selected
			m_p_oDeleteButton->EnableWindow(FALSE);*/
			m_p_oItemListBox->Invalidate();
			//M_vFakeMessage(OnEnlListBoxSelChange);
		}
	}

  m_vSetDefaultButton(m_p_oOkButton);

	m_bAutodispatch = FALSE;
}

//==========================================================================
//==========================================================================

BOOL EdActors_EditNameListsDialog::m_bIconClickedInListBox(CPoint oPoint)
{
	//do not handle calls generated by automodifications
	if ( m_bAutodispatch )
		return FALSE;
	m_bAutodispatch = TRUE;

	short wSelectedItem = m_p_oItemListBox->GetCurSel();
	short wNbItems = m_p_oItemListBox->GetCount();
	m_p_oItemListBox->ClientToScreen(&oPoint);
	CRect oListRect;
	m_p_oItemListBox->GetWindowRect(&oListRect);

	if ( oListRect.PtInRect(oPoint) )
	{
		short wClickedItem = LB_ERR;
		for ( short wItem = 0; wItem < wNbItems; wItem ++ )
		{
			//get the item rect in the list's rect coordinates
			CRect oIconRect, oClientItemRect;
			m_p_oItemListBox->GetItemRect(wItem, &oClientItemRect);
			oIconRect = oClientItemRect;
			//convert the item rect in screen coordinates
			oIconRect.OffsetRect(oListRect.TopLeft());
			//before we shrink to the icon's size, check if we clicked in the full rectangle
			if ( oIconRect.PtInRect(oPoint) )
				wClickedItem = wItem;
			//we test only the left part, where the icon is drawn
			oIconRect.right = oIconRect.left + oIconRect.Height();
      //if we clicked on the icon
			if ( oIconRect.PtInRect(oPoint) )
			{
				if ( m_eEditMode == E_em_NameListEdit ) //we want to change the share mode
				{
					//the user edited a list -> we cannot get back into list selection mode
					m_bUserEditedAList = TRUE;
					tdoDummyName *p_oName = (tdoDummyName *) m_p_oItemListBox->GetItemDataPtr(wItem);
					tdeShareMode eNewMode;
					//get the old mode
					eNewMode = p_oName->m_eGetShareMode();
					//compute the new mode
					if ( eNewMode == E_sm_Common )
						eNewMode = E_sm_Shared;
					else if ( eNewMode == E_sm_Shared )
          {
						//if the model has instances, he cannot make a name specific, so we swap back to common
            BOOL bCanTakeVirgeMode =
						!m_p_oCurrentSelectedList
						|| m_p_stArgs->stIn.bModelCanSelectANameList
						|| !m_p_oCurrentSelectedList->m_bWasHereOnInit()
						|| m_p_oCurrentSelectedList->m_p_oGetAssociatedList()->m_bHasAVirgeField();
						eNewMode = bCanTakeVirgeMode ? E_sm_Virge : E_sm_Common;
					}
					else if ( eNewMode == E_sm_Virge )
					{
						//if the name was here on init, and is Virge, and the name list has object list, the mode cannot be changed
						BOOL bCannotLeaveVirgeMode =
						(
							p_oName->m_bWasHereOnInit() && p_oName->m_p_oGetAssociatedName()->m_eGetShareMode() == E_sm_Virge
							&& m_p_oCurrentSelectedList->m_p_oGetAssociatedList()->m_pEdtListHandler->fn_oGetListOfEdtLists()->GetCount() > 0 //there are object lists
						);
						m_p_oCommonRadioButton->EnableWindow(!bCannotLeaveVirgeMode);
						m_p_oSharedRadioButton->EnableWindow(!bCannotLeaveVirgeMode);
						//determine the new mode
						eNewMode = bCannotLeaveVirgeMode ? E_sm_Virge : E_sm_Common;
						//if we couyd change the mode, the list was edited, else is was not...
						m_bUserEditedAList = !bCannotLeaveVirgeMode;
					}
					else
						ASSERT(FALSE);
					//put the new mode in the item
					p_oName->m_vSetShareMode(eNewMode);
					//update the radio buttons if we modify the selected item
					if ( wItem == m_p_oItemListBox->GetCurSel() )
            m_vSetRadioShareMode(p_oName->m_eGetShareMode());
					//make the listbox redraw the icon
					m_p_oItemListBox->InvalidateRect(oClientItemRect);
					//the user edited a list -> we cannot get back into list selection mode
					//m_bUserEditedAList = TRUE;
          m_p_oSwapEditModeButton->EnableWindow(!m_bUserEditedAList);
					//reenable message handling before returning
					m_bAutodispatch = FALSE;
					return TRUE; //short-circuit standard behaviour
				}
				else /* m_eEditMode == E_em_NameListSelect */ //we want to make the model use the clicked list
				{
					//we dont have the right to select another name list
					if ( !m_p_stArgs->stIn.bModelCanSelectANameList )
					{
						m_bAutodispatch = FALSE;
						return TRUE; //the click is handled, but we do nothing...
					}
					//failsafe test:
					//we should never be in name list selection mode if the user modified a list,
					//because the user cannot get back into list selection mode after having modified a list
					//TODO: a model cannot change name list if the instances have object lists !!!
					if ( !m_bUserEditedAList )
					{
						//get the clicked name list
						tdoDummyNameList *p_oList = (tdoDummyNameList *) m_p_oItemListBox->GetItemDataPtr(wItem);
						if ( p_oList != m_p_oListSelectedForModel )
							m_p_oListSelectedForModel = p_oList;
						else
							m_p_oListSelectedForModel = NULL;
						//redisplay all controls as should be
						m_p_oItemListBox->Invalidate();
						M_vFakeMessage(OnEnlListBoxSelChange);
					}
					//reenable message handling before returning
					m_bAutodispatch = FALSE;
					return TRUE;
				}
			}
			else if ( wClickedItem != LB_ERR ) //we clicked outside the icon of the item, but on an item nonetheless
			{
				if ( wSelectedItem == wClickedItem ) //if we clicked on the selected item
				{
					m_p_oItemListBox->SetCurSel(LB_ERR);
					M_vFakeMessage(OnEnlListBoxSelChange);
					//reenable message handling before returning
					m_bAutodispatch = FALSE;
					return TRUE;
				}
			}
		} //item loop
	} //clicked in CListBox client area
	//reenable message handling before returning
	m_bAutodispatch = FALSE;
	//we did not click on the icon, so resume standard behaviour
	return FALSE;
}

//==========================================================================
//==========================================================================

BOOL EdActors_EditNameListsDialog::OnInitDialog()
{
	short /*wIndex, wMode, wOk,*/ wModelIndex = LB_ERR;

	CDialog::OnInitDialog();

	//Creates tool tips
	m_poToolTip = new CToolTipCtrl;
	m_poToolTip->Create(this, WS_VISIBLE | TTS_ALWAYSTIP);
	EnableToolTips(TRUE);

	CString oDialogTitle;
	GetWindowText(oDialogTitle);
	SetWindowText(oDialogTitle + " (" + m_p_stArgs->stIn.p_c_szScriptName + ")");

	M_vRegisterControl(m_p_oNameEdit, CEdit *, IDC_EDIT_ENL_NAME, 0, "enter a new name");
	M_vRegisterControl(m_p_oEditGroupTitle, CStatic *, IDC_STATIC_ENL_GROUP, 1, "type of edited items");
	M_vRegisterControl(m_p_oItemListTitle, CStatic *, IDC_STATIC_ENL_ITEMLIST, 2, "type of listed items");
	M_vRegisterControl(m_p_oSwapEditModeButton, CButton *, IDC_BUTTON_ENL_CURRENTMODE, 3, "swap the edit mode");
	M_vRegisterControl(m_p_oAddButton, CButton *, IDC_BUTTON_ENL_ADD, 4, "add a new item");
	M_vRegisterControl(m_p_oRenameButton, CButton *, IDC_BUTTON_ENL_RENAME, 5, "rename the current item");
	M_vRegisterControl(m_p_oDeleteButton, CButton *, IDC_BUTTON_ENL_DELETE, 6, "delete the current item");
	M_vRegisterControl(m_p_oCommonRadioButton, CButton *, IDC_RADIO_ENL_COMMON, 7, "change the item's share mode");
	M_vRegisterControl(m_p_oSharedRadioButton, CButton *, IDC_RADIO_ENL_SHARED, 8, "change the item's share mode");
	M_vRegisterControl(m_p_oVirgeRadioButton, CButton *, IDC_RADIO_ENL_SPECIFIC, 9, "change the item's share mode");
	M_vRegisterControl(m_p_oItemListBox, CListBox *, IDC_LIST_ENL_ITEMLIST, 10, "select an item to edit");
	M_vRegisterControl(m_p_oOkButton, CButton *, IDOK, 11, "Irremediably accept all changes");
	M_vRegisterControl(m_p_oCancelButton, CButton *, IDCANCEL, 12, "Cancel all changes");

    // Register the controls for the tutorial
    TUT_M_vGetTutDll ();
    TUT_M_vRegisterControlID (IDC_EDIT_ENL_NAME           , "OAC_NL_NewName"        , TUT_e_TextEdit);
    TUT_M_vRegisterControlID (IDC_BUTTON_ENL_CURRENTMODE  , "OAC_NL_ChangeMode"     , TUT_e_Button  );
    TUT_M_vRegisterControlID (IDC_BUTTON_ENL_ADD          , "OAC_NL_Add"            , TUT_e_Button  );
    TUT_M_vRegisterControlID (IDC_BUTTON_ENL_RENAME       , "OAC_NL_Rename"         , TUT_e_Button  );
    TUT_M_vRegisterControlID (IDC_BUTTON_ENL_DELETE       , "OAC_NL_Delete"         , TUT_e_Button  );
    TUT_M_vRegisterControlID (IDC_RADIO_ENL_COMMON        , "OAC_NL_Common"         , TUT_e_Button  );
    TUT_M_vRegisterControlID (IDC_RADIO_ENL_SHARED        , "OAC_NL_Shared"         , TUT_e_Button  );
    TUT_M_vRegisterControlID (IDC_RADIO_ENL_SPECIFIC      , "OAC_NL_Specific"       , TUT_e_Button  );
    TUT_M_vRegisterControlID (IDC_LIST_ENL_ITEMLIST       , "OAC_NL_List"           , TUT_e_ListBox );
    TUT_M_vRegisterControlID (IDOK                        , "OAC_NL_Ok"             , TUT_e_Button  );
    TUT_M_vRegisterControlID (IDCANCEL                    , "OAC_NL_Cancel"         , TUT_e_Button  );

	m_p_stArgs->stOut.p_oNameListSelectedForModel = m_p_stArgs->stIn.p_oCurrentNameList;
	m_p_oListSelectedForModel = m_p_oCurrentSelectedList = m_p_oListModifHandler->m_p_oGetListforNameList(m_p_stArgs->stOut.p_oNameListSelectedForModel);

	//load the icons
  m_hIconCommon  = M_GetMainApp()->LoadIcon(IDI_ICON_COMMON_MODE);
  m_hIconShared  = M_GetMainApp()->LoadIcon(IDI_ICON_SHARED_MODE);
  m_hIconVirge   = M_GetMainApp()->LoadIcon(IDI_ICON_VIRGE_MODE);
	m_hIconChecked = M_GetMainApp()->LoadIcon(IDI_ICON_BOOLCHECK);

	//enter the correct mode
	if ( m_p_stArgs->stIn.p_oCurrentNameList ) //if the model has a name list, edit it
		m_eEditMode = E_em_NameListSelect;
	 else
		m_eEditMode = E_em_NameListEdit;
	M_vFakeMessage(OnEnlSwapEditModeButtonClicked);


	m_bAutodispatch = FALSE;

	//now fill the combo and edit with what we got
	//m_p_oListModifHandler->m_vFillControls(m_p_oItemListBox, m_p_oNameEdit, m_p_oCurrentSelectedList);

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

//==========================================================================
//==========================================================================

void EdActors_EditNameListsDialog::OnEnlDefaultButtonClicked()
{
	//do not handle calls generated by automodifications
	if ( m_bAutodispatch )
		return;
	m_bAutodispatch = TRUE;

  if ( m_p_oDefaultButton == m_p_oOkButton )
		M_vFakeMessage(OnOK);
	else if ( m_p_oDefaultButton == m_p_oAddButton )
		M_vFakeMessage(OnEnlAddButtonClicked);
	else if ( m_p_oDefaultButton == m_p_oSwapEditModeButton )
		M_vFakeMessage(OnEnlSwapEditModeButtonClicked);
	else
		ASSERT(m_p_oDefaultButton == NULL);

  m_bAutodispatch = FALSE;
}

//==========================================================================
//==========================================================================

void EdActors_EditNameListsDialog::OnOK()
{
	//update the out structure only if the changes are accepted
	m_p_oListModifHandler->m_vModifsAreAccepted(this);
	CDialog::OnOK();
}

//==========================================================================
//==========================================================================

/*void EdActors_EditNameListsDialog::OnMeasureItem(int _nIDCtl, LPMEASUREITEMSTRUCT _lpMeasureItemStruct)
{
	ASSERT(_nIDCtl == IDC_LIST_ENL_ITEMLIST );

	_lpMeasureItemStruct->itemWidth = 100;
	_lpMeasureItemStruct->itemHeight = 20;
}*/

void EdActors_EditNameListsDialog::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT _lpDrawItemStruct)
{
	if ( nIDCtl == IDC_LIST_ENL_ITEMLIST )
	{
		//draw the line of the list box
    CDC  *pDC = CDC::FromHandle (_lpDrawItemStruct->hDC);  // Get the drawing device
    RECT xItemRect  = _lpDrawItemStruct->rcItem;           // Get the position to draw
		short wItemId = _lpDrawItemStruct->itemID; //item to redraw
    BOOL bSelected = _lpDrawItemStruct->itemState & ODS_SELECTED; // Get if the line is selected or not
		CString csStringToDraw;

    pDC->SetMapMode(MM_TEXT);
    // Select colors
    pDC->FillSolidRect(&xItemRect, GetSysColor(bSelected ? COLOR_HIGHLIGHT : COLOR_WINDOW));
		if ( wItemId != LB_ERR )
		{
      pDC->SetBkMode(TRANSPARENT);
      pDC->SetTextColor(GetSysColor (bSelected ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT));

      if ( m_eEditMode == E_em_NameListEdit )
      {
        tdoDummyName *p_oName = (tdoDummyName *) m_p_oItemListBox->GetItemDataPtr(wItemId);
        // Draw the icon for shared mode
        tdeShareMode eShareMode = p_oName->m_eGetShareMode();
        if ( eShareMode != E_sm_None )
        {
          HICON hIconToDraw;
          switch ( eShareMode )
          {
          case E_sm_Common  : hIconToDraw = m_hIconCommon;    break;
          case E_sm_Shared  : hIconToDraw = m_hIconShared;    break;
          case E_sm_Virge   : hIconToDraw = m_hIconVirge;     break;
          default           : ASSERT (0);
          }
          pDC->DrawIcon(xItemRect.left, xItemRect.top, hIconToDraw);
        }
        csStringToDraw = p_oName->m_csGetName();
      }
      else
      {
        tdoDummyNameList *p_oList = (tdoDummyNameList *) m_p_oItemListBox->GetItemDataPtr(wItemId); //name list
        //draw the checkmark if this is the current name list for the model
        if ( m_p_oListSelectedForModel == p_oList )
          pDC->DrawIcon(xItemRect.left, xItemRect.top, m_hIconChecked);
        //get the name list's name
        csStringToDraw = p_oList->m_csGetName();
      }
      //draw the items's name
      xItemRect.left += 16;
      pDC->DrawText ((char *)LPCTSTR(csStringToDraw), -1 , &xItemRect, DT_SINGLELINE | DT_LEFT | DT_VCENTER);
    }
	}
	else
		CDialog::OnDrawItem(nIDCtl, _lpDrawItemStruct);
}

//==========================================================================
//==========================================================================

void EdActors_EditNameListsDialog::m_vSetRadioShareMode(tdeShareMode _eShareMode)
{
	m_p_oCommonRadioButton->SetCheck(_eShareMode == E_sm_Common);
	m_p_oSharedRadioButton->SetCheck(_eShareMode == E_sm_Shared);
	m_p_oVirgeRadioButton->SetCheck(_eShareMode == E_sm_Virge);
}

//==========================================================================
//==========================================================================

tdeShareMode EdActors_EditNameListsDialog::m_eGetRadioShareMode()
{
	tdeShareMode eNewMode;

	if ( m_p_oCommonRadioButton->GetCheck() )
		eNewMode = E_sm_Common;
	else if ( m_p_oSharedRadioButton->GetCheck() )
		eNewMode = E_sm_Shared;
	else if ( m_p_oVirgeRadioButton->GetCheck() )
		eNewMode = E_sm_Virge;
	else
		eNewMode = E_sm_None;

	return eNewMode;
}

void EdActors_EditNameListsDialog::OnDestroy ()
{
    // Unregister the controls for the tutorial
    TUT_M_vGetTutDll ();
    TUT_M_vUnregisterControlID (IDC_EDIT_ENL_NAME         );
    TUT_M_vUnregisterControlID (IDC_BUTTON_ENL_CURRENTMODE);
    TUT_M_vUnregisterControlID (IDC_BUTTON_ENL_ADD        );
    TUT_M_vUnregisterControlID (IDC_BUTTON_ENL_RENAME     );
    TUT_M_vUnregisterControlID (IDC_BUTTON_ENL_DELETE     );
    TUT_M_vUnregisterControlID (IDC_RADIO_ENL_COMMON      );
    TUT_M_vUnregisterControlID (IDC_RADIO_ENL_SHARED      );
    TUT_M_vUnregisterControlID (IDC_RADIO_ENL_SPECIFIC    );
    TUT_M_vUnregisterControlID (IDC_LIST_ENL_ITEMLIST     );
    TUT_M_vUnregisterControlID (IDOK                      );
    TUT_M_vUnregisterControlID (IDCANCEL                  );

    CDialog::OnDestroy ();
}
