/*
///////////////////////////////////////////////////////////////////////////////////////////////////
// Description : WayMod.cpp
//   
// Modification classes
//
///////////////////////////////////////////////////////////////////////////////////////////////////
// inherit from CPA_Modif
//					
///////////////////////////////////////////////////////////////////////////////////////////////////
// Creation date: 21 jan 1997                        Author: J Thénoz
///////////////////////////////////////////////////////////////////////////////////////////////////
// Modification date:			                      Author: 
// 
//
// 
//
///////////////////////////////////////////////////////////////////////////////////////////////////
*/

//ANNECY Shaitan Nettoyage (12/05/98) {
/*

#include "stdafx.h"
#include "acp_base.h"
#include "resource.h"
#include "incitf.h"
#include "incgam.h"
#include "incai.h"
#include "WpObj.hpp"
#include "WayObj.hpp"
#include "LinkObj.hpp"
#include "WayMod.hpp"
#include "Inter.hpp"
#include "WayDia.hpp"


ModifWayInsert::ModifWayInsert (Way* pWay, WayPoint* pInsertWP, WP_tduc_WPIndex stBeforeWP, BOOL bDialog1stRefresh, BOOL pBlock) : CPA_Modif (TYPE_INSERT_WP,"",pBlock)  
{	
	m_pWay = pWay;
	m_pWay->GetInterface()->fn_bComputeRealWay (&m_pWay);
	m_pInsertWP = pInsertWP;
	m_stBeforeWP = stBeforeWP;
	m_DialogRefresh=bDialog1stRefresh;
	SetName(CString("Insert ")+CString(m_pInsertWP->GetName())+CString (" into ")+CString (m_pWay->GetName()));
}

BOOL ModifWayInsert::Do (void)
{
	POSITION lPosWP, lPosLink;
	WayPoint* poWP;
	Link* poLink;
	int iSelect=0;

	// insert object in the editor list
	if (m_stBeforeWP<m_pWay->GetListWaypoint()->GetCount())
	{
		//----------- link
		if (m_stBeforeWP)
		{
			m_pOldLink = m_pWay->fn_pGetLink (m_stBeforeWP-1);
			m_pOldLink->fn_vSplitLink ( m_pWay, m_pInsertWP, &m_pLinkBefore, &m_pLinkAfter );
			m_pOldLink->fn_vSetRemoveInHierarchy (TRUE);
			m_pLinkBefore->fn_vSetAddInHierarchy (TRUE);
			m_pLinkAfter->fn_vSetAddInHierarchy (TRUE);
			for (poLink=m_pWay->GetListLink()->GetHeadElement(lPosLink), iSelect=1; poLink && iSelect!=m_stBeforeWP; poLink=m_pWay->GetListLink()->GetNextElement(lPosLink), iSelect++);
			if (poLink)
			{
				m_pWay->GetListLink()->SetAt( lPosLink, m_pLinkAfter );
				m_pWay->GetListLink()->InsertBefore( lPosLink, m_pLinkBefore );
			}
		}
		else 
		{
			m_pOldLink=NULL;
			m_pLinkBefore=NULL;
			m_pLinkAfter=(Link*)(m_pWay->fn_pCreateLink (m_pWay->fn_cGetDefaultLink())->GetObject());
			m_pLinkAfter->fn_vSetWaypoints ( m_pInsertWP, m_pWay->GetListWaypoint()->GetHead () );
			m_pWay->GetListLink()->AddHead ( m_pLinkAfter );
		}
		
		//------------- waypoint
		for (poWP=m_pWay->GetListWaypoint()->GetHeadElement(lPosWP), iSelect=0; poWP && iSelect!=m_stBeforeWP; poWP=m_pWay->GetListWaypoint()->GetNextElement(lPosWP), iSelect++);
		if (poWP) m_pWay->GetListWaypoint()->InsertBefore(lPosWP,m_pInsertWP);
	}
	else 
	{
		//---------- link
		m_pOldLink=NULL;
		m_pLinkAfter=NULL;
		m_pLinkBefore=NULL;
		if (m_pWay->GetListWaypoint()->GetCount()) 
		{
			m_pLinkBefore = (Link*) (m_pWay->fn_pCreateLink(m_pWay->fn_cGetDefaultLink())->GetObject());
			m_pLinkBefore->fn_vSetWaypoints (m_pWay->GetListWaypoint()->GetTail (), m_pInsertWP);
			m_pLinkBefore->fn_vSetAddInHierarchy (TRUE);
			m_pWay->GetListLink()->AddTail(m_pLinkBefore);
		}

		//---------- waypoint
		m_pWay->GetListWaypoint()->AddTail(m_pInsertWP);
		iSelect=m_pWay->GetListWaypoint()->GetCount();
	}
	
	// insert the WP and the links in the engine structure
	WP_fnv_Way_InsertWayPoint ((WP_tdhWay)(m_pWay->GetStruct()), (WP_tdhWayPoint)(m_pInsertWP->GetStruct()),m_pLinkBefore ? (WP_tdhLink)(m_pLinkBefore->GetStruct()) : NULL, m_pLinkAfter ? (WP_tdhLink)(m_pLinkAfter->GetStruct()) : NULL , m_stBeforeWP);

	// refresh the dialog if it's open
	if (!m_DialogRefresh) m_DialogRefresh=TRUE;
	else
		if (m_pWay->fn_bIsDialog()) m_pWay->fn_pGetDialog()->fn_vRefreshDialog(iSelect);
	
	// refreh the waypoint dialog
	m_pWay->GetInterface()->fn_vRefreshWaypointCoordinate ();
	
	// refresh the graphic
	m_pInsertWP->fn_vDraw(FALSE,TRUE);
	m_pWay->fn_vRefresh();
	m_pWay->GetInterface()->fn_vRefreshHierarchyList ();
	
	m_pWay->fn_vNotifySave ();


	return TRUE;
}

BOOL ModifWayInsert::Undo (void)
{
	POSITION lPosWP, lPosLink;
	WayPoint* poWP;
	Link* poLink;
	int iSelect=0;
	
	// delete object in the engine structure
	WP_fnv_Way_DeleteWayPoint ((WP_tdhWay)(m_pWay->GetStruct()), m_stBeforeWP, m_pOldLink ? (WP_tdhLink)m_pOldLink->GetStruct() : NULL );
	
	// delete object in the editor list
	for (poWP=m_pWay->GetListWaypoint()->GetHeadElement(lPosWP), iSelect=0; poWP && iSelect!=m_stBeforeWP; poWP=m_pWay->GetListWaypoint()->GetNextElement(lPosWP), iSelect++);
	if (poWP) m_pWay->GetListWaypoint()->RemoveAt(lPosWP);
	
	// restore editors links
	if (m_stBeforeWP)
	{
		for (poLink=m_pWay->GetListLink()->GetHeadElement(lPosLink), iSelect=1; poLink && iSelect!=m_stBeforeWP; poLink=m_pWay->GetListLink()->GetNextElement(lPosLink), iSelect++);
		if (m_pOldLink) 
		{
			m_pWay->GetListLink()->SetAt( lPosLink, m_pOldLink );
			m_pOldLink->fn_vSetAddInHierarchy (TRUE);
			m_pWay->GetListLink()->GetNextElement(lPosLink);
		}
		m_pLinkBefore->fn_vSetRemoveInHierarchy (TRUE);
		if (m_pLinkAfter) m_pLinkAfter->fn_vSetRemoveInHierarchy (TRUE);
		if (lPosLink) m_pWay->GetListLink()->RemoveAt(lPosLink);
	}
	else
	{
		if (m_pWay->GetListLink()->GetCount()) m_pWay->GetListLink()->RemoveHead ();
	}
		
	if (m_pWay->fn_bIsDialog()) m_pWay->fn_pGetDialog()->fn_vRefreshDialog(iSelect);
	
	m_pWay->GetInterface()->fn_vRefreshWaypointCoordinate();
	m_pWay->fn_vRefresh();
	m_pWay->GetInterface()->fn_vRefreshHierarchyList ();
	m_pWay->fn_vNotifySave ();
	return TRUE;
}


ModifWayDelete::ModifWayDelete (Way* pWay, WP_tduc_WPIndex stPosDeleteWP, BOOL pBlock) : CPA_Modif (TYPE_DELETE_WP,"",pBlock)  
{	
	m_pWay = pWay;
	m_pWay->GetInterface()->fn_bComputeRealWay (&m_pWay);
	m_stDeletePosWP = stPosDeleteWP;
	m_pDeleteWP=0;
	m_pLink=NULL;
	m_DialogRefresh=!pBlock;
	SetName(CString("Delete ")+CString(m_pWay->fn_pGetWayPoint ((m_stDeletePosWP==WP_fnuc_Way_GetSizeWay ((WP_tdhWay)(pWay->GetEngineStruct()))) ? m_stDeletePosWP-1 : m_stDeletePosWP)->GetName()) + CString (" in ") + CString (m_pWay->GetName()) );
}


BOOL ModifWayDelete::Do (void)
{
	POSITION	lPosWP, lPosLink;
	POSITION	lPosModifyLink;
	WayPoint*	poWP;
	Link*		poLink;
	int iSelect=0;
	

	// delete object in the editor list
	for (poWP=m_pWay->GetListWaypoint()->GetHeadElement(lPosWP), iSelect=0; poWP && iSelect!=m_stDeletePosWP; poWP=m_pWay->GetListWaypoint()->GetNextElement(lPosWP),iSelect++);
	if (poWP) {
		m_pWay->GetListWaypoint()->RemoveAt(lPosWP); // Ok we have it
		m_pDeleteWP=poWP;
	}
	
	// modify links in the editor list
	if (m_stDeletePosWP)
	{
		for (poLink=m_pWay->GetListLink()->GetHeadElement(lPosLink), iSelect=1; poLink && iSelect!=m_stDeletePosWP; poLink=m_pWay->GetListLink()->GetNextElement(lPosLink),iSelect++);
		lPosModifyLink = lPosLink;
		m_pOldLinkBefore=poLink;
		m_pOldLinkAfter=m_pWay->GetListLink()->GetNextElement(lPosLink);
		if (m_pOldLinkBefore && m_pOldLinkAfter)
		{
			m_pLink = m_pOldLinkBefore->fn_pMergeLink (m_pWay, m_pOldLinkAfter);
			m_pLink->fn_vSetAddInHierarchy (TRUE);
			if (m_pOldLinkBefore) m_pOldLinkBefore->fn_vSetRemoveInHierarchy (TRUE);
			if (m_pOldLinkAfter) m_pOldLinkAfter->fn_vSetRemoveInHierarchy (TRUE);
			m_pWay->GetListLink()->SetAt( lPosModifyLink, m_pLink );
			if (m_stDeletePosWP) m_pWay->GetListLink()->RemoveAt(lPosLink);
		}
		else 
		{
			m_pLink=NULL;
			if (m_pOldLinkBefore) m_pOldLinkBefore->fn_vSetRemoveInHierarchy (TRUE);
			m_pWay->GetListLink()->RemoveTail ();
		}
	}
	else 
	{
		m_pOldLinkBefore=NULL;
		m_pOldLinkAfter=m_pWay->GetListLink()->GetHeadElement(lPosLink);
		m_pLink = NULL;
		if (m_pWay->GetListLink()->GetCount())
		{
			m_pWay->GetListLink()->GetHead()->fn_vSetRemoveInHierarchy (TRUE);
			m_pWay->GetListLink()->RemoveHead();
		}
	}
	
	// delete object in the motor structure
	if (m_pWay->IsWayEmpty()) WP_fnv_Way_Free ((WP_tdhWay)(m_pWay->GetStruct()));
	else WP_fnv_Way_DeleteWayPoint ((WP_tdhWay)(m_pWay->GetStruct()), m_stDeletePosWP, m_pLink ? (WP_tdhLink)m_pLink->GetEngineStruct() : NULL );

	// refresh the dialog if it's open
	if (m_pWay->fn_bIsDialog()) m_pWay->fn_pGetDialog()->fn_vRefreshDialog(max (iSelect-1,0));
	
	// refreh the waypoint dialog
	m_pWay->GetInterface()->fn_vRefreshWaypointCoordinate();
	m_pWay->fn_vRefresh();
	if (m_DialogRefresh) m_pWay->GetInterface()->fn_vRefreshHierarchyList ();
	
	
	if (m_pWay->IsWayEmpty()) 
	{
		m_pWay->fn_vNotifyUnSave ();
		m_pWay->fn_vSetRecreate (TRUE);
		if (m_pWay->GetSuperObject()->GetParent()) 
		{
			Way::GetInterface()->fn_vSetModifDeleteOk (TRUE);
			Way::GetInterface()->GetInterface()->fn_bDeleteObjectInHierarchy (m_pWay->GetSuperObject(), FALSE, FALSE, FALSE, FALSE );
			Way::GetInterface()->fn_vSetModifDeleteOk (FALSE);
		}
	}
	else m_pWay->fn_vNotifySave ();
	
	return TRUE;
}


BOOL ModifWayDelete::Undo (void)
{
	POSITION lPosWP,	lPosLink;
	WayPoint*			poWP;
	Link*				poLink;
	long lIndex;

	if (m_pWay->IsWayEmpty())
	{
		Way::GetInterface()->fn_vSetRefreshWay (TRUE);
		if (!m_pWay->GetSuperObject()->GetParent()) Way::GetInterface()->GetInterface()->fn_bInsertObjectInHierarchy (m_pWay->GetSuperObject(), Way::GetInterface()->GetInterface()->GetSpecificInterface()->GetDynamicRoot(), FALSE, FALSE, FALSE );
		Way::GetInterface()->fn_vSetRefreshWay (FALSE);
	}

	// search the position in the editor list to reinsert and do it
	for (poWP=m_pWay->GetListWaypoint()->GetHeadElement(lPosWP), lIndex=0; poWP && lIndex!=m_stDeletePosWP; poWP=m_pWay->GetListWaypoint()->GetNextElement(lPosWP),lIndex++);
	if (poWP) m_pWay->GetListWaypoint()->InsertBefore(lPosWP,m_pDeleteWP);
	else m_pWay->GetListWaypoint()->AddTail(m_pDeleteWP);
	
	if (m_pWay->fn_bIsDialog()) m_pWay->fn_pGetDialog()->fn_vRefreshDialog(lIndex);

	// set the links editor
	if (m_stDeletePosWP)
	{
		if (m_pLink)
		{
			for (poLink=m_pWay->GetListLink()->GetHeadElement(lPosLink), lIndex=1; poLink && lIndex!=m_stDeletePosWP; poLink=m_pWay->GetListLink()->GetNextElement(lPosLink),lIndex++);
			m_pLink->fn_vSetRemoveInHierarchy (TRUE);
			if (m_pOldLinkBefore)
			{
				m_pOldLinkBefore->fn_vSetAddInHierarchy (TRUE);
				m_pWay->GetListLink()->SetAt( lPosLink, m_pOldLinkBefore );
			}
			if (m_pOldLinkAfter)
			{
				m_pOldLinkAfter->fn_vSetAddInHierarchy (TRUE);
				m_pWay->GetListLink()->InsertAfter( lPosLink, m_pOldLinkAfter );
			}
		}
		else 
		{
			m_pOldLinkBefore->fn_vSetAddInHierarchy (TRUE);
			m_pWay->GetListLink()->AddTail (m_pOldLinkBefore);
			m_pOldLinkBefore->fn_vSetAddInHierarchy (TRUE);
		}
	}
	else 
	{
		if (m_pOldLinkAfter) 
		{
			m_pOldLinkAfter->fn_vSetAddInHierarchy (TRUE);
			m_pWay->GetListLink()->AddHead (m_pOldLinkAfter);
		}
	}
	
	// reinsert the object in the motor structure
	WP_fnv_Way_InsertWayPoint ((WP_tdhWay)(m_pWay->GetStruct()), (WP_tdhWayPoint)(m_pDeleteWP->GetStruct()), m_pOldLinkBefore ? (WP_tdhLink)(m_pOldLinkBefore->GetEngineStruct()) : NULL, m_pOldLinkAfter ? (WP_tdhLink)(m_pOldLinkAfter->GetEngineStruct()) : NULL, m_stDeletePosWP);
	
	m_pWay->fn_vRefresh();

	// refresh the dialog if it's open
	if (m_pWay->fn_bIsDialog()) m_pWay->fn_pGetDialog()->fn_vRefreshDialog ();

	// refreh the waypoint dialog
	m_pWay->GetInterface()->fn_vRefreshWaypointCoordinate();
	if (m_DialogRefresh) m_pWay->GetInterface()->fn_vRefreshHierarchyList ();
	m_pWay->fn_vNotifySave ();
	return TRUE;
}


ModifWayRemove::ModifWayRemove (Way* pWay, WayPoint* pRemoveWP, BOOL pBlock) : CPA_Modif (TYPE_REMOVE_WP,"Remove WP",pBlock)  
{	
	m_pWay = pWay;
	m_pWay->GetInterface()->fn_bComputeRealWay (&m_pWay);
	m_pRemoveWP = pRemoveWP;
	m_lNbRemoveWP = 0;
	m_dstRemovePosWP = NULL;
	m_dpoRemoveLinkBefore = NULL;
	m_dpoRemoveLinkAfter = NULL;
}

BOOL ModifWayRemove::Do (void)
{
	POSITION lPos;
	WayPoint* poWP;
	
	// we count the number of waypoint to remove
	m_lNbRemoveWP=0;
	for 
	(
		poWP=m_pWay->GetListWaypoint()->GetHeadElement(lPos);
		poWP; 
		poWP=m_pWay->GetListWaypoint()->GetNextElement(lPos)
	)
	if (poWP==m_pRemoveWP) m_lNbRemoveWP++;
	
	// we allocate the array of position
	m_dstRemovePosWP = new WP_tduc_WPIndex [m_lNbRemoveWP];
	m_dpoRemoveLinkBefore = new Link* [m_lNbRemoveWP];
	m_dpoRemoveLinkAfter = new Link* [m_lNbRemoveWP];
	
	long lIndexRemoveWP = 0;   // indice in the array
	
	for (lIndexRemoveWP=0; lIndexRemoveWP<m_lNbRemoveWP; lIndexRemoveWP++)
	{
		POSITION lPosLinkBefore=0, lPosLinkAfter=0, lPosLink=0;
		
		// delete object in the engine structure
		m_dstRemovePosWP[lIndexRemoveWP] = WP_fnuc_Way_PositionWayPoint ((WP_tdhWay)(m_pWay->GetStruct()), (WP_tdhWayPoint)(m_pRemoveWP->GetStruct()));
		m_dpoRemoveLinkBefore[lIndexRemoveWP] = m_pWay->fn_pGetLink (m_dstRemovePosWP[lIndexRemoveWP]-1);
		m_dpoRemoveLinkAfter[lIndexRemoveWP] = m_pWay->fn_pGetLink  (m_dstRemovePosWP[lIndexRemoveWP]);
		Link* poLink = NULL;
		if (m_dpoRemoveLinkBefore[lIndexRemoveWP] && m_dpoRemoveLinkAfter[lIndexRemoveWP])
		{
			poLink = m_dpoRemoveLinkBefore[lIndexRemoveWP]->fn_pMergeLink (m_pWay, m_dpoRemoveLinkAfter[lIndexRemoveWP] );
			poLink->fn_vSetAddInHierarchy (TRUE);
		}
		
		// delete object in the editor list
		for (poWP=m_pWay->GetListWaypoint()->GetHeadElement(lPos); poWP && poWP!=m_pRemoveWP; poWP=m_pWay->GetListWaypoint()->GetNextElement(lPos) );
		if (poWP==m_pRemoveWP) m_pWay->GetListWaypoint()->RemoveAt(lPos);
			
		// replace link in the editor list
		if (m_dstRemovePosWP[lIndexRemoveWP]) lPosLinkBefore=m_pWay->GetListLink()->FindIndex (m_dstRemovePosWP[lIndexRemoveWP]-1);
		lPosLinkAfter = m_pWay->GetListLink()->FindIndex (m_dstRemovePosWP[lIndexRemoveWP]);
		
		if (lPosLinkBefore) m_pWay->GetListLink()->RemoveAt (lPosLinkBefore);
		if (lPosLinkAfter) m_pWay->GetListLink()->RemoveAt (lPosLinkAfter);
		
		if (m_dstRemovePosWP[lIndexRemoveWP]>=2) lPosLink = m_pWay->GetListLink()->FindIndex (m_dstRemovePosWP[lIndexRemoveWP]-2);
		if (lPosLinkBefore && lPosLinkAfter) 
		{
			if (lPosLink) m_pWay->GetListLink()->InsertAfter ( lPosLink, poLink );
			else m_pWay->GetListLink()->AddHead (poLink);
		}
		WP_fnv_Way_DeleteWayPoint ((WP_tdhWay)(m_pWay->GetStruct()), m_dstRemovePosWP[lIndexRemoveWP],poLink ? (WP_tdhLink)(poLink->GetEngineStruct()) : NULL );
	
		// Links
		if (m_dpoRemoveLinkBefore[lIndexRemoveWP]) m_dpoRemoveLinkBefore[lIndexRemoveWP]->fn_vSetRemoveInHierarchy (TRUE);
		if (m_dpoRemoveLinkAfter[lIndexRemoveWP]) m_dpoRemoveLinkAfter[lIndexRemoveWP]->fn_vSetRemoveInHierarchy (TRUE);
	}
	
	// refreh the waypoint dialog
	m_pWay->GetInterface()->fn_vRefreshWaypointCoordinate();

	// refresh the dialog if it's open
	if (m_pWay->fn_bIsDialog()) m_pWay->fn_pGetDialog()->fn_vRefreshDialog();
	m_pWay->fn_vRefresh();
	m_pWay->GetInterface()->fn_vRefreshHierarchyList ();
	
	if (m_pWay->IsWayEmpty()) 
	{
		m_pWay->fn_vNotifyUnSave ();
		m_pWay->fn_vSetRecreate (TRUE);
		if (m_pWay->GetSuperObject()->GetParent())
		{
			Way::GetInterface()->fn_vSetModifDeleteOk (TRUE);
			Way::GetInterface()->GetInterface()->fn_bDeleteObjectInHierarchy (m_pWay->GetSuperObject(), FALSE, FALSE, FALSE, FALSE );
			Way::GetInterface()->fn_vSetModifDeleteOk (FALSE);
		}
	}
	else m_pWay->fn_vNotifySave ();

	return TRUE;
}

BOOL ModifWayRemove::Undo (void)
{
	POSITION lPos;
	WayPoint* poWP;
	long lWP;
	long lIndexRemoveWP = 0;   

	if (m_pWay->IsWayEmpty())
	{
		Way::GetInterface()->fn_vSetRefreshWay (TRUE);
		if (!m_pWay->GetSuperObject()->GetParent()) Way::GetInterface()->GetInterface()->fn_bInsertObjectInHierarchy (m_pWay->GetSuperObject(), Way::GetInterface()->GetInterface()->GetSpecificInterface()->GetDynamicRoot(), FALSE, FALSE, FALSE );
		Way::GetInterface()->fn_vSetRefreshWay (FALSE);
	}

	// reinsert the object in the motor structure
	for (lIndexRemoveWP=m_lNbRemoveWP-1; lIndexRemoveWP>=0; lIndexRemoveWP--)
	{
		WP_fnv_Way_InsertWayPoint ((WP_tdhWay)(m_pWay->GetStruct()), (WP_tdhWayPoint)(m_pRemoveWP->GetStruct()), m_dpoRemoveLinkBefore[lIndexRemoveWP] ? (WP_tdhLink)(m_dpoRemoveLinkBefore[lIndexRemoveWP]->GetEngineStruct()) : NULL, m_dpoRemoveLinkAfter[lIndexRemoveWP] ? (WP_tdhLink)(m_dpoRemoveLinkAfter[lIndexRemoveWP]->GetEngineStruct()) : NULL, m_dstRemovePosWP[lIndexRemoveWP]);

		// search the position in the editor list to reinsert and do it
		for (poWP=m_pWay->GetListWaypoint()->GetHeadElement(lPos), lWP=0; poWP && lWP!=m_dstRemovePosWP[lIndexRemoveWP]; poWP=m_pWay->GetListWaypoint()->GetNextElement(lPos),lWP++);
		if (poWP) m_pWay->GetListWaypoint()->InsertBefore(lPos,m_pRemoveWP);
		else m_pWay->GetListWaypoint()->AddTail(m_pRemoveWP);
	
		// list links
		if (m_dstRemovePosWP[lIndexRemoveWP]<2) 
		{
			if (m_dpoRemoveLinkAfter[lIndexRemoveWP] && m_dpoRemoveLinkBefore[lIndexRemoveWP]) 
			{
				m_pWay->GetListLink()->GetHead()->fn_vSetRemoveInHierarchy (TRUE);
				m_pWay->GetListLink()->RemoveHead ();
			}
			if (m_dpoRemoveLinkAfter[lIndexRemoveWP]) m_pWay->GetListLink()->AddHead (m_dpoRemoveLinkAfter[lIndexRemoveWP]);
			if (m_dpoRemoveLinkBefore[lIndexRemoveWP]) m_pWay->GetListLink()->AddHead (m_dpoRemoveLinkBefore[lIndexRemoveWP]);
		}
		else 
		{
			POSITION lPosLastLink = m_pWay->GetListLink()->FindIndex (m_dstRemovePosWP[lIndexRemoveWP]-1);
			if (lPosLastLink) 
			{
				m_pWay->GetListLink()->GetAt ( lPosLastLink )->fn_vSetRemoveInHierarchy (TRUE);
				m_pWay->GetListLink()->RemoveAt ( lPosLastLink );
			}
			POSITION lPosInsertLink = m_pWay->GetListLink()->FindIndex ( m_dstRemovePosWP[lIndexRemoveWP]-2 );
			if (m_dpoRemoveLinkBefore[lIndexRemoveWP]) m_pWay->GetListLink()->InsertAfter (lPosInsertLink, m_dpoRemoveLinkBefore[lIndexRemoveWP]);
			m_pWay->GetListLink()->GetNextElement (lPosInsertLink);
			if (m_dpoRemoveLinkAfter[lIndexRemoveWP]) m_pWay->GetListLink()->InsertAfter (lPosInsertLink, m_dpoRemoveLinkAfter[lIndexRemoveWP]);
		}
		
		// Links
		if (m_dpoRemoveLinkBefore[lIndexRemoveWP]) m_dpoRemoveLinkBefore[lIndexRemoveWP]->fn_vSetAddInHierarchy (TRUE);
		if (m_dpoRemoveLinkAfter[lIndexRemoveWP]) m_dpoRemoveLinkAfter[lIndexRemoveWP]->fn_vSetAddInHierarchy (TRUE);

	}
	delete[] m_dstRemovePosWP;
	delete[] m_dpoRemoveLinkBefore;
	delete[] m_dpoRemoveLinkAfter;
	m_dstRemovePosWP=NULL;
	m_dpoRemoveLinkBefore=NULL;
	m_dpoRemoveLinkAfter=NULL;
	if (m_pWay->fn_bIsDialog()) m_pWay->fn_pGetDialog()->fn_vRefreshDialog(lWP);
	
	// refreh the waypoint dialog
	m_pWay->GetInterface()->fn_vRefreshWaypointCoordinate();

	m_pWay->fn_vRefresh();
	m_pWay->GetInterface()->fn_vRefreshHierarchyList ();
	m_pWay->fn_vNotifySave ();
	return TRUE;
}



// Add a new WP in the net
ModifWayAddWP::ModifWayAddWP ( Way* poWay, MTH3D_tdstVector* pAbsolutePosition, WP_tduc_WPIndex stBeforeWP, CPA_Interface* pEditor, BOOL pBlock ) : CPA_Modif (TYPE_ADD_NEW_WP,"Add new WP", pBlock )  
{
	m_poWay = poWay;
	m_poWay->GetInterface()->fn_bComputeRealWay (&m_poWay);
	m_pAbsolutePosition = pAbsolutePosition;
	m_pEditor = pEditor;
	m_poWay->GetInterface()->fn_vSetNextInstanceInWay ();
	m_poSuperWP = m_pEditor->GetNewInstance ("Waypoint", "Waypoint");
	
	HIE_fn_vSetSuperObjectDrawMask(m_poSuperWP->GetStruct(), C_lTexturedElement);

	m_pModifInsertWP=NULL;
	m_stPosBeforeWP = stBeforeWP;

	// compute position of the WayPoint
	POS_tdstCompletePosition InvWorldMatrix;
	POS_fn_vSetIdentityMatrix(&InvWorldMatrix);
	HIE_tdxHandleToSuperObject hSuperWorldEngine = ((DEV_MultiDevice3D *)(m_pEditor->GetMultiDevice()))->GetEngineWorld();
	CPA_SuperObject* poSuperWorldEditor = ((DEV_MultiDevice3D *)(m_pEditor->GetMultiDevice()))->GetWorld()->GetRoot(); 
	
	// set absolute position
	GEO_tdxHandleToMatrix hAbsoluteWorldMatrix = HIE_fn_hGetSuperObjectGlobalMatrix (hSuperWorldEngine);
	GEO_tdxHandleToMatrix hAbsoluteWPMatrix = HIE_fn_hGetSuperObjectGlobalMatrix (m_poSuperWP->GetStruct());
	GEO_tdxHandleToMatrix hRelativeWPMatrix = HIE_fn_hGetSuperObjectMatrix (m_poSuperWP->GetStruct());
	
	POS_fn_vSetIdentityMatrix( hAbsoluteWPMatrix ) ;
			
	POS_fn_vSetTranslationVector
	( 
		hAbsoluteWPMatrix,
		m_pAbsolutePosition
	);	
		
	// compute relative position
	POS_fn_vInvertIsoMatrix( &InvWorldMatrix,  hAbsoluteWorldMatrix );
			
	POS_fn_vMulMatrixMatrix
	( 
        hRelativeWPMatrix,
		&InvWorldMatrix,
		hAbsoluteWPMatrix
	);

	// Set the name 
	SetName(CString("Add new ")+CString(m_poSuperWP->GetObject()->GetName())+CString(" to ")+CString(m_poWay->GetName()));

}
	
BOOL ModifWayAddWP::Do (void)
{
	CPA_SuperObject* poSuperWorldEditor = ((DEV_MultiDevice3D *)(m_pEditor->GetMultiDevice()))->GetWorld()->GetRoot(); 
	m_poWay->GetInterface()->GetInterface()->fn_bInsertObjectInHierarchy ( m_poSuperWP, m_poWay->GetInterface()->GetInterface()->GetSpecificInterface()->GetDynamicRoot(),FALSE,FALSE, FALSE );

	// set the status of the waypoint
	((WayPoint*)(m_poSuperWP->GetObject()))->fn_vSetAlone (FALSE);
	
	// Set the engine structure
	((WayPoint*)(m_poSuperWP->GetObject()))->fn_vComputeMotorStructure ();

	m_pModifInsertWP = new ModifWayInsert (m_poWay, (WayPoint*)(m_poSuperWP->GetObject()), m_stPosBeforeWP );
	m_pModifInsertWP->Do ();
	m_poWay->fn_vNotifySave ();
	return TRUE;
}
	
BOOL ModifWayAddWP::Undo (void)
{
	CPA_SuperObject* poSuperWorldEditor = ((DEV_MultiDevice3D *)(m_pEditor->GetMultiDevice()))->GetWorld()->GetRoot(); 

	// delete the add waypoint from the hiearchie
	m_pModifInsertWP->Undo ();
	Way::GetInterface()->fn_vSetModifDeleteOk (TRUE);
	m_poWay->GetInterface()->GetInterface()->fn_bDeleteObjectInHierarchy ( m_poSuperWP,FALSE,FALSE, FALSE, FALSE );
	Way::GetInterface()->fn_vSetModifDeleteOk (FALSE);
	delete m_pModifInsertWP;
	m_pModifInsertWP=NULL;
	

	// test jt
	if (m_poWay->IsWayEmpty()) 
	{
		m_poWay->fn_vNotifyUnSave ();
		m_poWay->fn_vSetRecreate (TRUE);
		if (m_poWay->GetSuperObject()->GetParent()) 
		{
			Way::GetInterface()->fn_vSetModifDeleteOk (TRUE);
			Way::GetInterface()->GetInterface()->fn_bDeleteObjectInHierarchy (m_poWay->GetSuperObject(), FALSE, FALSE, FALSE, FALSE );
			Way::GetInterface()->fn_vSetModifDeleteOk (FALSE);
		}
	}
	else m_poWay->fn_vNotifySave ();



	m_pEditor->fn_vUpdateAll (E_mc_JustDraw);
//	m_poWay->fn_vNotifySave ();
	return TRUE;
}

*/
//ENDANNECY Shaitan Nettoyage }
