/*
------------------------------------------------------------------------------------------
IMPLEMENTATION FILE FOR WP:
WayPoint.c

Creation Date : January,1997
Author : Jacques (Annecy)

------------------------------------------------------------------------------------------
Modifications : 
January, 1997    Alb     Many modification in all file to conform it with  3DOS

------------------------------------------------------------------------------------------
This file implements functions used to manage waypoints and ways
in the engine
------------------------------------------------------------------------------------------
Remarks :
WP and Way are allocated inside the AI memory module.
AI has access to WP through handles
Way are contained inside a specific actor's MS
AI has access to Way through indexes. These indexes are used in common with the MS to 
retrieve an handle on the effective way.
------------------------------------------------------------------------------------------
*/

#include "stdafx.h"
#include "ACP_Base.h"
//#include "ToolsCPA.h"
#include "CPALib.h"
#include "Hie.h"

//#ifdef _AI_LIB_
	#include "AIUseCPA.h"

	#include "Options\Options.h"
	#include "Macros.h"
	#include "Structur\StdObjSt.h"
	#include "Structur\MemGame.h"
	#include "ZeMem.h"
	#include "GameEng.h"

	/*#include "IntelLib.h"*/
	#include "IAOption.h"
	#include "IAMacros.h"
	/* AI memory and error management */
	#include "MemIA.h"
	#include "ErrIA.h"
/*#else
	#include "stdafx.h"
	#include "ACP_Base.h"
//	#include "ToolsCPA.h"
	#include "CPALib.h"
	#include "Hie.h"
	#include "MemIA.h"
	#include "ErrIA.h"
 #endif*/

unsigned char g_ucIAModuleId;

//------ pour compiler en mode editeur sans MemIA et ErrIA
/*
#define M_IAAlloc(pointer,cast,size) (pointer=(cast)malloc(size))
#define M_IA_MemSet memset
#define M_IAFree free
#define M_IA_DEBUG_ASSERT ASSERT
#define M_IAFatalError(x);
#define M_IARealloc(pointerDest,pointerSrc,cast,size) (pointerDest=(cast)realloc(pointerSrc,size))
 */ 



#define WP_GLOBALS

// #include "WayPoint.h"
#undef WP_GLOBALS

#include "dynamic.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

//-------------------------------- static counter for script load
static long gs_lScriptWayCounter = 0;
static long gs_lScriptLinkCounter = 0;


/*
------------------------------------------------------------------------------------------
WAYPOINT MANAGEMENT :
------------------------------------------------------------------------------------------
*/
// construction, destruction, copy
ACP_tdxHandleOfWaypoint fn_hConstructWaypoint (void)
{
	ACP_tdxHandleOfWaypoint hNewWP;
 /* allocate the WP :*/
 M_IAAlloc
 (
  hNewWP, /* Var to allocate*/
  ACP_tdxHandleOfWaypoint, /* var type */
  sizeof(tdst_WayPoint) /* size in bytes*/
 );
 /* initialise all field to default value :*/
	M_IA_MemSet( hNewWP, 0, sizeof(tdst_WayPoint));
	return hNewWP;
}

void fn_vDestroyWaypoint (ACP_tdxHandleOfWaypoint _hWP)
{
	M_IAFree(_hWP);
}

ACP_tdxHandleOfWaypoint  fn_hDuplicateWaypoint (ACP_tdxHandleOfWaypoint _hWP)
{
	ACP_tdxHandleOfWaypoint hCopyWP = fn_hConstructWaypoint ();
	(*hCopyWP) = (*_hWP); // ok
	return hCopyWP;
}

void fn_vCopyWaypoint (ACP_tdxHandleOfWaypoint _hDestWP, ACP_tdxHandleOfWaypoint _hSrcWP)
{
	*_hDestWP=*_hSrcWP;
}

void fn_vInvalidateWaypoint(ACP_tdxHandleOfWaypoint* _hWP)
{
	*_hWP = ACP_C_InvalidWayPointHandle;
}

ACP_tdxBool fn_bIsWaypointValid (ACP_tdxHandleOfWaypoint _hWP)
{
	return _hWP==ACP_C_InvalidWayPointHandle; 
}

/*
////////////////////////////////////////////////////////////////////////////////
Description :fn_hAddRefWaypoint
Increase the used count
////////////////////////////////////////////////////////////////////////////////
Input :
a handle on the waypoint
////////////////////////////////////////////////////////////////////////////////
Output :
the handle of the waypoint
////////////////////////////////////////////////////////////////////////////////
Error raised:
None
////////////////////////////////////////////////////////////////////////////////
Creation date : January 22,1997
Author : Albert Pais
////////////////////////////////////////////////////////////////////////////////
*/
ACP_tdxHandleOfWaypoint fn_hAddRefWaypoint(ACP_tdxHandleOfWaypoint _hWayPoint)
{
// ANNECY AV {
// M_ucGetWPUsedCount(_hWayPoint)++;
// END ANNECY AV }
 return _hWayPoint;
}

/*
////////////////////////////////////////////////////////////////////////////////
Description :fn_hReleaseWaypoint
Decrease the used count of the waypoint. If it reachs zero, the WP is destroyed
////////////////////////////////////////////////////////////////////////////////
Input :
A handle to the waypoint
////////////////////////////////////////////////////////////////////////////////
Output :
The handle to the WP if it has not been destroyed 
otherwise ACP_C_InvalidWayPointHandle
////////////////////////////////////////////////////////////////////////////////
Error raised:
None
////////////////////////////////////////////////////////////////////////////////
Creation date : January 22,1997
Author : Albert Pais
////////////////////////////////////////////////////////////////////////////////
*/
ACP_tdxHandleOfWaypoint fn_hReleaseWaypoint(ACP_tdxHandleOfWaypoint _hWayPoint)
{
 //M_ucGetWPUsedCount(_hWayPoint)--;
 ///* if it is zero, then destroy it :*/
 //if(!M_ucGetWPUsedCount(_hWayPoint))
// {
  //fn_vDestroyWaypoint(_hWayPoint);
  //_hWayPoint = ACP_C_InvalidWayPointHandle;
 //}
 return _hWayPoint;
}

void fn_vSetVertexWaypoint (ACP_tdxHandleOfWaypoint _hWP, MTH3D_tdstVector* _pstVertex)
{
	M_stGetVertex(_hWP) = *_pstVertex;	
}


void fn_vSetRadiusWaypoint (ACP_tdxHandleOfWaypoint _hWP, GLI_tdxValue _xRadius)
{
	M_xGetWPRadius(_hWP) = _xRadius;	
}


void fn_vSetSuperObjetWaypoint (ACP_tdxHandleOfWaypoint _hWP, HIE_tdxHandleToSuperObject _hSuperObject)
{
	M_hGetSuperObject(_hWP) = _hSuperObject;	
}

void fn_vGetVertexWaypoint (ACP_tdxHandleOfWaypoint _hWP, MTH3D_tdstVector* _pstVertex)
{
	(*_pstVertex) = M_stGetVertex(_hWP);
}


void fn_vGetRadiusWaypoint (ACP_tdxHandleOfWaypoint _hWP, GLI_tdxValue* _pxRadius )
{
	*_pxRadius = M_xGetWPRadius(_hWP);
}

HIE_tdxHandleToSuperObject fn_pGetSuperObjetWaypoint (ACP_tdxHandleOfWaypoint _hWP)
{
	return M_hGetSuperObject(_hWP);
}

SCRIPT_tdeReturnValue fn_eScriptCallBackLoadWaypoint(FILE *p_fFile, char *szAction, char *szParams[], SCRIPT_tdeAction cType)
{
#ifdef toto
	HIE_tdxHandleToSuperObject hSuperObjParent;
	ACP_tdxHandleOfWaypoint hWaypoint;
	MTH3D_tdstVector			stVertex;
	
 switch (cType)
	{
	 case C_SCRIPT_Section:
   hWaypoint =  fn_hConstructWaypoint();
   /* Set father to an invalid value :*/
   fn_vSetSuperObjetWaypoint (hWaypoint,NULL);
   SCRIPT_vSetResult ((long)hWaypoint);
		 break;		 
	 case C_SCRIPT_Entry:
		 hWaypoint = (ACP_tdxHandleOfWaypoint) SCRIPT_ulGetResult();
			 
		 if (strcmp(szAction,"Vertex")==0)
		 {
			 /* load the vertex*/
    stVertex.xX = MTH_M_xFloatToReal(atof(szParams[0]));
    stVertex.xY = MTH_M_xFloatToReal(atof(szParams[1]));
    stVertex.xZ = MTH_M_xFloatToReal(atof(szParams[2]));
     
 			fn_vSetVertexWaypoint (hWaypoint, &stVertex);    
		 }

		 else if (strcmp(szAction,"Radius")==0)
		 {
			 /* load the radius */
			 fn_vSetRadiusWaypoint (hWaypoint,MTH_M_xFloatToReal(atof(szParams[0])));
		 }

		 else if (strcmp(szAction,"Father")==0)
		 {
			 // load the father
			 SCRIPT_vSetResultSubSection((unsigned long)NULL);
    hSuperObjParent = (HIE_tdxHandleToSuperObject) (SCRIPT_ulAnalyseSection(szParams[0],szParams[1]));
			 fn_vSetSuperObjetWaypoint (hWaypoint,hSuperObjParent);
    /* HIE :*
    HIE_fn_vSuperObjectAddTail(hSuperObjParent,hSuperObjWP);*/
		 }
		 break;
		 
	 case C_SCRIPT_EndSection:
   /* if it is a static WP, the handle to the belonger is NULL*/
   break;
	}
#endif

	return R_SCRIPT_NormalReturn;
}	


//---------------- location of the waypoint

void fn_vComputeLocationWaypoint ( ACP_tdxHandleOfWaypoint _hWP, MTH3D_tdstVector* _pstVertex )
{
	if (M_hGetSuperObject(_hWP))
	{
		GEO_tdxHandleToMatrix hGlobalMatrix = HIE_fn_hGetSuperObjectGlobalMatrix (M_hGetSuperObject(_hWP));
		
		POS_fn_vMulMatrixVertex
		( 
			_pstVertex,
   hGlobalMatrix,
			&(M_stGetVertex(_hWP))
		);	
	}
	else *_pstVertex = M_stGetVertex(_hWP);
}


//---------------- Retrieve a handle on the WP when loading
//---------------- Albert PAIS
//---------------- January 15, 1997
ACP_tdxHandleOfWaypoint fn_hGetHWPLoaded(char *_p_szFileName, char*_p_szWPName)
{
#ifdef toto
/* check parameter validity :*/
 if
 (
    (!_p_szFileName)
  ||(!_p_szWPName)
 )
 {
  /* Raise an error :*/
  M_IAFatalError(E_uwIAFatalInvalidParameter);
 }
 char *p_szSectionName;
 ACP_tdxHandleOfWaypoint  hReturned;
 M_IAAlloc
 (
  p_szSectionName, /* Var to allocate*/
  char*, /* var type */
  strlen("Waypoint_") + strlen(_p_szWPName) /* size in bytes*/
 );
 sprintf(p_szSectionName,"WayPoint_%s",_p_szWPName);
 hReturned = (ACP_tdxHandleOfWaypoint ) (SCRIPT_ulAnalyseSection(_p_szFileName,p_szSectionName));
 /* free the sz :*/
 M_IAFree(p_szSectionName);
 return hReturned;
 #endif
	return 0;
}

/*
------------------------------------------------------------------------------------------
LINK MANAGEMENT :
------------------------------------------------------------------------------------------
*/
/*
Some macros :
*/
#define M_bIsLinkTypeStaticLine(_p_szTerm)\
 (!strcmpi(_p_szTerm,"StaticLine"))
#define M_bIsLinkTypeDynamicLine(_p_szTerm)\
 (!strcmpi(_p_szTerm,"DynamicLine"))
#define M_bIsLinkTypeBezier(_p_szTerm)\
 (!strcmpi(_p_szTerm,"Bezier"))
#define M_bIsLinkTypeCircle(_p_szTerm)\
 (!strcmpi(_p_szTerm,"Circle"))

#define	M_bIsLinkDynTypeNone(_p_szTerm)\
 (!strcmpi(_p_szTerm,"None"))
#define M_bIsLinkDynTypeConstant(_p_szTerm)\
 (!strcmpi(_p_szTerm,"Constant"))
#define	M_bIsLinkDynTypeLinear(_p_szTerm)\
 (!strcmpi(_p_szTerm,"Linear"))
#define	M_bIsLinkDynTypeSinus(_p_szTerm)\
 (!strcmpi(_p_szTerm,"Sinus"))

// construction, destruction, copy
ACP_tdxHandleOfLink fn_hConstructLink (void)
{
	ACP_tdxHandleOfLink hNewLink;
 M_IAAlloc
 (
  hNewLink, /* var */
  ACP_tdxHandleOfLink, /* cast */
  sizeof(tdst_Link) /* size */
 );
#ifdef __DEBUG_IA__
 /* initialise data :*/
	M_IA_MemSet(hNewLink, 0, sizeof(tdst_Link) );
	M_eucGetLinkConnectionType(hNewLink) = ACP_ConnType_ucInvalid;
 M_eucGetLinkConnectionDynType(hNewLink) = ACP_ConDynType_ucInvalid;
#endif /* __DEBUG_IA__ */
	return hNewLink;
}

void fn_vDestroyLink (ACP_tdxHandleOfLink _hLink)
{
 /* destroy information buffer :*/
 fn_vFreeLink(_hLink);
 M_IAFree(_hLink);
}

ACP_tdxHandleOfLink fn_hDuplicateLink (ACP_tdxHandleOfLink hLink)
{
	ACP_tdxHandleOfLink	hCopyLink = fn_hConstructLink ();
	fn_vCopyLink (hCopyLink, hLink);
	return hCopyLink;
}


void fn_vCopyLink (ACP_tdxHandleOfLink _hDestLink, ACP_tdxHandleOfLink _hSrcLink)
{
	fn_vAllocLink
	(
		_hDestLink,
		M_eucGetLinkConnectionType(_hSrcLink),
		M_eucGetLinkConnectionDynType(_hSrcLink)
	);
	/* Just set the pointer :*/
	M_pvGetLinkConnTypeInfo(_hDestLink) = M_pvGetLinkConnTypeInfo(_hSrcLink);
	/* copy dynam info :*/
	 memcpy
	(
	&M_stGetLinkConnDynTypeInfo(_hDestLink), /* dest buffer*/
	&M_stGetLinkConnDynTypeInfo(_hSrcLink), /* src buffer*/
	sizeof(ACP_tdstDynaParam) /* Number of bytes to copy*/
	);
}


void fn_vInvalidateLink (ACP_tdxHandleOfLink* _hLink)
{
	*_hLink = ACP_C_InvalidLinkHandle;
}

ACP_tdxBool fn_bIsLinkValid (ACP_tdxHandleOfLink _hLink)
{
	return _hLink==ACP_C_InvalidLinkHandle;
}

void fn_vAllocLink	(ACP_tdxHandleOfLink _hLink,ACP_tde_ucConnectionType _eucConnType,ACP_tde_ucConnectionDynamicType _eucConnDynType)
{
 /* First the connection type :*/
	M_eucGetLinkConnectionType(_hLink) = _eucConnType;
	switch (_eucConnType)
	{
  case ACP_ConnType_ucStaticLine:
   /* For static lines, a vector is needed to store the Wp at the execution :*/
   M_IAAlloc
   (
    M_stGetLinkConnTypeStaticVector(_hLink),
    MTH3D_tdstVector *,
    sizeof(MTH3D_tdstVector)
   );
   break;
  case ACP_ConnType_ucDynamicLine :
   /* No information is needed for dynamic lines :*/
   M_pvGetLinkConnTypeInfo(_hLink) = NULL;
   break;
  case ACP_ConnType_ucBezier:
   /* following structure describes Bezier curve :*/
   M_IAAlloc
   (
    M_stGetLinkConnTypeBezierObject(_hLink),
    tdstBezierObject *,
    sizeof(tdstBezierObject)
   );
   break;
  case ACP_ConnType_ucCircle :
   /* Certainly something TODO :*/
   break;
#ifdef __DEBUG_IA__
  default :
   /* Raise an error :*/
   M_IAFatalError(E_uwIAFatalTypeLinkInvalid);
   M_pvGetLinkConnTypeInfo(_hLink) = NULL;
#endif /*__DEBUG_IA__*/
	}
 
 /* Dynamic information is directly inside the structure, 
 so there is nothing to allocate */
 /* Just check that the type is valid :*/
 M_IA_DEBUG_ASSERT(M_bIsValidDynTypeLink(_eucConnDynType),E_uwIAFatalDynTypeLinkInvalid);
 M_eucGetLinkConnectionDynType(_hLink) = _eucConnDynType;
// M_IA_MemSet(&M_stGetLinkConnDynTypeInfo(_hLink),0xaa,sizeof(ACP_tdstDynaParam));
}

void fn_vFreeLink(ACP_tdxHandleOfLink _hLink)
{
 /* May be things to free depending on connection type :*/
 if(M_pvGetLinkConnTypeInfo(_hLink))
 {
  M_IAFree(M_pvGetLinkConnTypeInfo(_hLink));
 }
 M_eucGetLinkConnectionType(_hLink) = ACP_ConnType_ucInvalid;
 M_eucGetLinkConnectionDynType(_hLink) = ACP_ConDynType_ucInvalid;
}

ACP_tde_ucConnectionType fn_eucGetConTypeLink(ACP_tdxHandleOfLink _hLink)
{
 return M_eucGetLinkConnectionType(_hLink);
}
ACP_tde_ucConnectionDynamicType fn_eucGetConDynTypeLink(ACP_tdxHandleOfLink _hLink)
{
	return M_eucGetLinkConnectionDynType(_hLink);
}

void* fn_pvGetLinkConTypeInfo(ACP_tdxHandleOfLink _hLink)
{
	return M_pvGetLinkConnTypeInfo(_hLink);
}

ACP_tdstDynaParam  *fn_pvGetLinkConDynTypeInfo(ACP_tdxHandleOfLink _hLink)
{
 return &M_stGetLinkConnDynTypeInfo(_hLink);
}

void fn_vSetLinkConTypeInfo(ACP_tdxHandleOfLink _hLink, void* _pLinkConTypeInfo)
{
	M_pvGetLinkConnTypeInfo(_hLink)=_pLinkConTypeInfo;
}

void fn_vSetConTypeLink(ACP_tdxHandleOfLink _hLink,ACP_tde_ucConnectionType _eucType)
{
 /* Only change if it is not the same :*/
 if(M_eucGetLinkConnectionType(_hLink) != _eucType)
 {
  M_eucGetLinkConnectionType(_hLink) = _eucType;
  /* if there was previous data :erase it */
  if(M_pvGetLinkConnTypeInfo(_hLink))
  {
   M_IAFree(M_pvGetLinkConnTypeInfo(_hLink));
  }
  /* now, allocate depending on the type :*/
	 switch (M_eucGetLinkConnectionType(_hLink))
	 {
   case ACP_ConnType_ucStaticLine:
    /* For static lines, a vector is needed to store the Wp at the execution :*/
    M_IAAlloc
    (
     M_stGetLinkConnTypeStaticVector(_hLink),
     MTH3D_tdstVector *,
     sizeof(MTH3D_tdstVector)
    );
    break;
   case ACP_ConnType_ucDynamicLine :
    /* No information is needed for dynamic lines :*/
    M_pvGetLinkConnTypeInfo(_hLink) = NULL;
    break;
   case ACP_ConnType_ucBezier:
    /* following structure describes Bezier curve :*/
    M_IAAlloc
    (
     M_stGetLinkConnTypeBezierObject(_hLink),
     tdstBezierObject *,
     sizeof(tdstBezierObject)
    );
    break;
   case ACP_ConnType_ucCircle :
    /* Certainly something TODO :*/
    break;
 #ifdef __DEBUG_IA__
   default :
    /* Raise an error :*/
    M_IAFatalError(E_uwIAFatalTypeLinkInvalid);
    M_pvGetLinkConnTypeInfo(_hLink) = NULL;
 #endif /*__DEBUG_IA__*/
	 }
 }
}

void fn_vSetConDynTypeLink(ACP_tdxHandleOfLink _hLink,ACP_tde_ucConnectionDynamicType eucType)
{
 /* Nothing to check or change since the dynamic structure is not allocated 
 but it is directly contained inside the Link structure :*/
	M_eucGetLinkConnectionDynType(_hLink) = eucType;
}


/*
////////////////////////////////////////////////////////////////////////////////
Description :fn_hAddRefLink
Increase the used count
////////////////////////////////////////////////////////////////////////////////
Input :
a handle on the link
////////////////////////////////////////////////////////////////////////////////
Output :
the handle of the link
////////////////////////////////////////////////////////////////////////////////
Error raised:
None
////////////////////////////////////////////////////////////////////////////////
Creation date : January 22,1997
Author : Albert Pais
////////////////////////////////////////////////////////////////////////////////
*/
ACP_tdxHandleOfLink fn_hAddRefLink(ACP_tdxHandleOfLink _hLink)
{
 M_ucGetLinkUsedCount(_hLink)++;
 return _hLink;
}
/*
////////////////////////////////////////////////////////////////////////////////
Description :fn_hReleaseLink
Increase the used count
////////////////////////////////////////////////////////////////////////////////
Input :
a handle on the link
////////////////////////////////////////////////////////////////////////////////
Output :
the handle of the link
////////////////////////////////////////////////////////////////////////////////
Error raised:
None
////////////////////////////////////////////////////////////////////////////////
Creation date : January 22,1997
Author : Albert Pais
////////////////////////////////////////////////////////////////////////////////
*/
ACP_tdxHandleOfLink fn_hReleaseLink(ACP_tdxHandleOfLink _hLink)
{
// Jack  enlevé car BOOM
// M_ucGetLinkUsedCount(_hLink)--;
// if(!M_ucGetLinkUsedCount(_hLink))
// {/* it is time to free the object :*/
//  fn_vDestroyLink(_hLink);
// return NULL;
// }
 return _hLink;
}

/*
////////////////////////////////////////////////////////////////////////////////
Description :fn_vBuildLinkFromszParams
Builds the link data from information contained in the array of zero terminated
strings
////////////////////////////////////////////////////////////////////////////////
Input :
a handle on the link
an array to szStrings
////////////////////////////////////////////////////////////////////////////////
Output :
None
////////////////////////////////////////////////////////////////////////////////
Error raised:
None
////////////////////////////////////////////////////////////////////////////////
Creation date : January 23,1997
Author : Albert Pais
////////////////////////////////////////////////////////////////////////////////
szParam should be :
LinkType,LinkDynType[,LinkTypeParam][,LinkDynTypeParam]
////////////////////////////////////////////////////////////////////////////////
*/
void fn_vBuildLinkFromszParams
(
 ACP_tdxHandleOfLink _hLink,
 char *szParams[],
 ACP_tdxHandleOfWaypoint _hWayPointBefore,
 ACP_tdxHandleOfWaypoint _hWayPointAfter
)
{
 unsigned char ucCurrentParam;
 ACP_tde_ucConnectionType eucConnType;
 ACP_tde_ucConnectionDynamicType eucConnDynType;

 /* information for dynamic :*/
 unsigned char ucSamplingRate = 0;
	unsigned char	ucDynamicType = 0;
	MTH_tdxReal	xFirst = MTH_C_ZERO;
	MTH_tdxReal	xSecond = MTH_C_ZERO;
	MTH_tdxReal	xThird = MTH_C_ZERO;
 /* information for lynik type :*/
 MTH3D_tdstVector stVFirst,stVSecond;
 
 /* first parameter should be the type of the link :*/
 if(M_bIsLinkTypeStaticLine(szParams[0]))
 {
  eucConnType = ACP_ConnType_ucStaticLine;
 }
 else if(M_bIsLinkTypeDynamicLine(szParams[0]))
 {
  eucConnType = ACP_ConnType_ucDynamicLine;
 }
 else if(M_bIsLinkTypeBezier(szParams[0]))
 {
  eucConnType = ACP_ConnType_ucBezier;
 }
 else if(M_bIsLinkTypeCircle(szParams[0]))
 {
  eucConnType = ACP_ConnType_ucCircle;
 }
 else
 {
  eucConnType = ACP_ConnType_ucInvalid;
  M_IAFatalError(E_uwIAFatalTypeLinkInvalid);
 }

 /* Second parameter should be the dynamic type of the link :*/
 if(M_bIsLinkDynTypeNone(szParams[1]))
 {
  eucConnDynType = ACP_ConDynType_ucNone;
 }
 else if(M_bIsLinkDynTypeConstant(szParams[1]))
 {
  eucConnDynType = ACP_ConDynType_ucConstant;
 }
 else if(M_bIsLinkDynTypeLinear(szParams[1]))
 {
  eucConnDynType = ACP_ConDynType_ucLinear;
 }
 else if(M_bIsLinkDynTypeSinus(szParams[1]))
 {
  eucConnDynType = ACP_ConDynType_ucSinus;
 }
 else
 {
  eucConnDynType = ACP_ConDynType_ucInvalid;
  M_IAFatalError(E_uwIAFatalDynTypeLinkInvalid);
 }
 
 /* allocate link according to the type and the dynamic type :*/
 fn_vAllocLink
 (
  _hLink,
  eucConnType,
  eucConnDynType
 );
 
 ucCurrentParam =2;
 /* Now, depending on the type of the link, read parameter(s) : */
 switch(M_eucGetLinkConnectionType(_hLink))
 {
 /* No parameter is needed for the Static and Dynamic line type :
  case ACP_ConnType_ucStaticLine :

  case ACP_ConnType_ucDynamicLine :
   break;*/

  case ACP_ConnType_ucBezier :
/*   M_IA_DEBUG_ASSERT
   (
    (_hWayPointBefore!=ACP_C_InvalidWayPointHandle)&&(_hWayPointAfter!=ACP_C_InvalidWayPointHandle),
    E_uwIAFaralWayFirstLinkMustBeLine
   );*/
   /* Parameters for Bezier curve :*/
   /*
     SamplingRate,
     StartVector->X,
     StartVertor->Y,
     StartVector->Z,
     EndVector->X,
     EndVertor->Y,
     EndVector->Z,
   */
   /* first param contains the sampling rate :*/
   ucSamplingRate = (tduc_SamplingRate)(atoi(szParams[ucCurrentParam]));
   ucCurrentParam++;
   /* First vertor tangeant : */
   MTH3D_M_vSetVectorElements
   (
    &stVFirst,
    MTH_M_xFloatToReal(atof(szParams[ucCurrentParam++])),
    MTH_M_xFloatToReal(atof(szParams[ucCurrentParam++])),
    MTH_M_xFloatToReal(atof(szParams[ucCurrentParam++]))
   );
   /* Second Vector tangeant :*/
   MTH3D_M_vSetVectorElements
   (
    &stVSecond,
    MTH_M_xFloatToReal(atof(szParams[ucCurrentParam++])),
    MTH_M_xFloatToReal(atof(szParams[ucCurrentParam++])),
    MTH_M_xFloatToReal(atof(szParams[ucCurrentParam++]))
   );
   /* Create the object : */
   fn_vBezierObject_Create
   (
    M_stGetLinkConnTypeBezierObject(_hLink),/* Bezier object */
    ucSamplingRate,/* ucSamplingRate */
    &M_stGetVertex(_hWayPointBefore),/* Starting point */
    &M_stGetVertex(_hWayPointAfter),/* Ending point */
    &stVFirst, /* Start Vector */
    &stVSecond, /* End Vector */
    C_ucModeNoObject,/* ucObjectMode */
    &M_stGetLinkConnDynTypeInfo(_hLink)/* DynamParam*/
   );
   break;
  case ACP_ConnType_ucCircle :
   /* TODO, but probably something like previous*/
   break;
 }
 
 /* Now, depending on the dynamic type of the link, read parameter(s) : */
 switch(M_eucGetLinkConnectionDynType(_hLink))
 {
  case ACP_ConDynType_ucNone :
   ucDynamicType = C_ucNone;
   break;
  case ACP_ConDynType_ucConstant :
   ucDynamicType = C_ucConst;
   /* contains the speed :*/
   xFirst = MTH_M_xFloatToReal(atof(szParams[ucCurrentParam]));
   ucCurrentParam++;
   break;
  case ACP_ConDynType_ucLinear :
   ucDynamicType = C_ucLinear;
   /* contains the starting speed :*/
   xFirst = MTH_M_xFloatToReal(atof(szParams[ucCurrentParam]));
   ucCurrentParam++;
   /* contains the ending speed :*/
   xSecond = MTH_M_xFloatToReal(atof(szParams[ucCurrentParam]));
   ucCurrentParam++;
   break;
  case ACP_ConDynType_ucSinus :
   ucDynamicType = C_ucSinus;
   /* contains the statring angle : */
   xFirst = MTH_M_xFloatToReal(atof(szParams[ucCurrentParam]));
   ucCurrentParam++;
   /* contains the ending angle : */
   xSecond = MTH_M_xFloatToReal(atof(szParams[ucCurrentParam]));
   ucCurrentParam++;
   /* contains the maximum speed :*/
   xThird = MTH_M_xFloatToReal(atof(szParams[ucCurrentParam]));
   ucCurrentParam++;
   break;
 }
 /* if there is a sampling rate : */
 if(ucSamplingRate)
 {
  fn_vDynamicObject_Create
  (
   &M_stGetLinkConnDynTypeInfo(_hLink),
   ucSamplingRate,
   ucDynamicType,
   xFirst,
   xSecond,
   xThird
  );
 }
 else
 {/* Dynamic object should not be sampled :*/
  fn_vDynamicObject_CreateNotSampled
  (
   &M_stGetLinkConnDynTypeInfo(_hLink),
   ucDynamicType,
   xFirst,
   xSecond,
   xThird
  );
 }
}

/*
------------------------------------------------------------------------------------------
WAY MANAGEMENT :
------------------------------------------------------------------------------------------
*/
ACP_tdxHandleOfWay fn_hConstructWay (void)
{
	ACP_tdxHandleOfWay hNewWay;
 /* allocate a way structure and return it :*/
 M_IAAlloc
 (
  hNewWay, /* Var to allocate*/
  ACP_tdxHandleOfWay, /* var type */
  sizeof(tdst_Way) /* size in bytes*/
 );
 /* initialize it to a default value :*/
	M_IA_MemSet(hNewWay, 0, sizeof(tdst_Way) );
	return hNewWay;
}

void fn_vDestroyWay(ACP_tdxHandleOfWay _hWay)
{
 fn_vFreeWay(_hWay);
	M_IAFree(_hWay);
}

ACP_tdxHandleOfWay fn_hDuplicateWay (ACP_tdxHandleOfWay _hWay)
{
 /* construction of a new structure :*/
 ACP_tdxHandleOfWay hCopyWay = fn_hConstructWay ();
 /* copy data to the new Way :*/
 fn_vCopyWay(hCopyWay/* dest */,_hWay /* Src */);
	return hCopyWay;
}

void fn_vCopyWay (ACP_tdxHandleOfWay _hWayDst, ACP_tdxHandleOfWay _hWaySrc)
{
 /* allocate the new way :*/
	fn_vAllocWay (_hWayDst, M_ucGetWaySizeWay(_hWaySrc));
 /* copy the current WP Index :*/
	M_ucGetWayCurrentWPIndex(_hWayDst) = M_ucGetWayCurrentWPIndex(_hWaySrc);
 /* copy the WP handle array :*/
 memcpy
 (
  M_dhGetWayWPHandleArray(_hWayDst), 
  M_dhGetWayWPHandleArray(_hWaySrc), 
  M_ucWayNbrOfWP(_hWaySrc) * sizeof(ACP_tdxHandleOfWaypoint )
 );
 /* Copy the link handle array :*/
	memcpy
 (
  M_dhGetWayLinkHandleArray(_hWayDst),
  M_dhGetWayLinkHandleArray(_hWaySrc),
  M_ucWayNbrOfLink(_hWaySrc) * sizeof(ACP_tdxHandleOfLink)
 );
}

void fn_vInvalidateWay(ACP_tdxHandleOfWay* _hWay)
{/* ?? Warning, before using this function, Way should be free */
	*_hWay = ACP_C_InvalidWayHandle;
}

ACP_tdxBool fn_bIsWayValid (ACP_tdxHandleOfWay _hWay)
{
	return _hWay == ACP_C_InvalidWayHandle;
}

void fn_vInitWay (ACP_tdxHandleOfWay _hWay)
{
//	M_IA_MemSet(_hWay, 0xaa, sizeof (tdst_Way) );
}

void fn_vAllocWay (ACP_tdxHandleOfWay _hWay, tducWPIndex _ucSizeWay)
{
	M_ucGetWaySizeWay(_hWay) = _ucSizeWay;
	M_ucGetWayCurrentWPIndex(_hWay) = 0;
	
 /* allocate WP array :*/
 M_IAAlloc
 (
  M_dhGetWayWPHandleArray(_hWay), /* Var to allocate*/
  ACP_tdxHandleOfWaypoint *, /* var type */
  M_ucWayNbrOfWP(_hWay)*sizeof(ACP_tdxHandleOfWaypoint) /* size in bytes*/
 );
// M_IA_MemSet(M_dhGetWayWPHandleArray(_hWay),0xaa,M_ucWayNbrOfWP(_hWay)*sizeof(ACP_tdxHandleOfWaypoint));
 /* allocate link array :*/
 M_IAAlloc
 (
  M_dhGetWayLinkHandleArray(_hWay), /* Var to allocate*/
  ACP_tdxHandleOfLink*, /* var type */
  (M_ucWayNbrOfLink(_hWay))*sizeof(ACP_tdxHandleOfLink) /* size in bytes*/
 );
// M_IA_MemSet(M_dhGetWayLinkHandleArray(_hWay),0xaa,M_ucWayNbrOfLink(_hWay)*sizeof(ACP_tdxHandleOfLink));
}

void fn_vFreeWay (ACP_tdxHandleOfWay _hWay)
{
	while(M_ucGetWaySizeWay(_hWay))
	{/* Erase previous data :*/
  fn_vDeleteWayPoint(_hWay,M_ucGetWaySizeWay(_hWay)-1, NULL);
	}
 /* set other fields to 0 */
 M_ucGetWayCurrentWPIndex(_hWay) = 0;
}

void fn_vReallocWay (ACP_tdxHandleOfWay _hWay, tducWPIndex _ucNewSizeWay)
{
 if(M_ucGetWaySizeWay(_hWay) != _ucNewSizeWay) fn_vAllocWay (_hWay, 2);
 {
  // jack
  if (!M_ucGetWaySizeWay(_hWay))  
  /* set new size :*/
  M_ucGetWaySizeWay(_hWay) = _ucNewSizeWay;
  /* reallocate the WP dynamic array :*/
  if(_ucNewSizeWay)
  {/* if it is a non zero value :*/
   M_IARealloc
   (
    M_dhGetWayWPHandleArray(_hWay),
    M_dhGetWayWPHandleArray(_hWay),
    ACP_tdxHandleOfWaypoint*,
    M_ucWayNbrOfWP(_hWay)*sizeof(ACP_tdxHandleOfWaypoint)
   );
   M_IARealloc
   (
    M_dhGetWayLinkHandleArray(_hWay),
    M_dhGetWayLinkHandleArray(_hWay),
    ACP_tdxHandleOfLink*,
    M_ucWayNbrOfLink(_hWay)*sizeof(ACP_tdxHandleOfLink)
   );
  }
  else
  {
   if(M_ucGetWaySizeWay(_hWay))
   {/* if there was previously elements in the arrays :*/
    M_IAFree(M_dhGetWayWPHandleArray(_hWay));
    M_IAFree(M_dhGetWayLinkHandleArray(_hWay));
   }
  }
 }
 /* else : nothing to do... */
}

/*
////////////////////////////////////////////////////////////////////////////////
Description :fn_hAddRefWay
Increase the used count
////////////////////////////////////////////////////////////////////////////////
Input :
a handle on the way
////////////////////////////////////////////////////////////////////////////////
Output :
the handle of the way
////////////////////////////////////////////////////////////////////////////////
Error raised:
None
////////////////////////////////////////////////////////////////////////////////
Creation date : January 22,1997
Author : Albert Pais
////////////////////////////////////////////////////////////////////////////////
*/
ACP_tdxHandleOfWay fn_hAddRefWay(ACP_tdxHandleOfWay _hWay)
{
 M_ucGetWayCurrentUsedCount(_hWay)++;
 return _hWay;
}

/*
////////////////////////////////////////////////////////////////////////////////
Description :fn_hReleaseWay
Decrease the used count of the way. If it reachs zero, the way is destroyed
////////////////////////////////////////////////////////////////////////////////
Input :
A handle to the way
////////////////////////////////////////////////////////////////////////////////
Output :
The handle to the way if it has not been destroyed 
otherwise ACP_C_InvalidWayHandle
////////////////////////////////////////////////////////////////////////////////
Error raised:
None
////////////////////////////////////////////////////////////////////////////////
Creation date : January 22,1997
Author : Albert Pais
////////////////////////////////////////////////////////////////////////////////
*/
ACP_tdxHandleOfWay fn_hReleaseWay(ACP_tdxHandleOfWay _hWay)
{
// M_ucGetWayCurrentUsedCount(_hWay)--;
// /* if it is zero, then destroy it :*/
// if(!M_ucGetWayCurrentUsedCount(_hWay))
// {
//  fn_vDestroyWay(_hWay);
//  _hWay = ACP_C_InvalidWayHandle;
// }
 return _hWay;
}

/*
////////////////////////////////////////////////////////////////////////////////
Description :fn_vInsertWayPoint 
Inserts a new waypoint in the way 
////////////////////////////////////////////////////////////////////////////////
Input :
A handle to the way
a handle on the new WP
a handle on the connected link before
a handle on the connected link after
the position where to insert the new WP
////////////////////////////////////////////////////////////////////////////////
Output :
None
////////////////////////////////////////////////////////////////////////////////
Error raised:
None
////////////////////////////////////////////////////////////////////////////////
Creation date : January 1997
Author : Jacques Ternoz (annecy)
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
Modification date : January 30,1997
Author : Albert Pais
Adding management depending on whether there is as much link as WP or not
////////////////////////////////////////////////////////////////////////////////
Modification date : February 10,1997
Author : Jacques Ternoz
Adding the modification of links due to the add WP
////////////////////////////////////////////////////////////////////////////////

*/
void fn_vInsertWayPoint 
(
 ACP_tdxHandleOfWay _hWay,
 ACP_tdxHandleOfWaypoint _hNewWP, 
 ACP_tdxHandleOfLink _hNewLinkBefore, 
 ACP_tdxHandleOfLink _hNewLinkAfter, 
 tducWPIndex  _ucPosWP
)
{
 tducWPIndex c_ucCount;
/* M_IA_DEBUG_ASSERT
 (
  _ucPosWP < M_ucGetWaySizeWay(_hWay),
  E_uwIAFatalWayPositionInvalid
 );*/
 
 /* First of all, re-allocate the way :*/
 fn_vReallocWay (_hWay, M_ucGetWaySizeWay(_hWay)+1);
#ifdef _WAY_FirstLinkIsFirstWaypoint_
 /* No problemo....*/
 for (c_ucCount=M_ucGetWaySizeWay(_hWay)-1; c_ucCount>_ucPosWP; c_ucCount--)
	{
		M_hGetWPAtPositionWay(_hWay,c_ucCount)=M_hGetWPAtPositionWay(_hWay,c_ucCount-1);
		M_hGetLinkAtPositionWay(_hWay,c_ucCount)=M_hGetLinkAtPositionWay(_hWay,c_ucCount-1);
	}

#else /*_WAY_FirstLinkIsFirstWaypoint_*/
 /* now shift arrays :*/
 for (c_ucCount=M_ucGetWaySizeWay(_hWay)-1; c_ucCount>_ucPosWP+1; c_ucCount--)
	{
		M_hGetWPAtPositionWay(_hWay,c_ucCount)=M_hGetWPAtPositionWay(_hWay,c_ucCount-1);
  M_hGetLinkAtPositionWay(_hWay,c_ucCount-1)=M_hGetLinkAtPositionWay(_hWay,c_ucCount-2);
	}
 /* since there is one more WP to shift :*/
 /* here,, c_ucCount = _ucPosWP + 1:*/
	M_hGetWPAtPositionWay(_hWay,c_ucCount)=M_hGetWPAtPositionWay(_hWay,c_ucCount-1);

#endif /*_WAY_FirstLinkIsFirstWaypoint_*/
 
 /* insert the new WP :*/
	M_hGetWPAtPositionWay(_hWay,_ucPosWP)=_hNewWP;
	if (_hNewLinkBefore) M_hGetLinkAtPositionWay(_hWay,_ucPosWP-1)=_hNewLinkBefore;
	if (_hNewLinkAfter) M_hGetLinkAtPositionWay(_hWay,_ucPosWP)=_hNewLinkAfter;
}

void fn_vDeleteWayPoint (ACP_tdxHandleOfWay _hWay, tducWPIndex  _ucPosWP, ACP_tdxHandleOfLink _hNewLink)
{
	tducWPIndex ucWP;
/*
 M_IA_DEBUG_ASSERT
 (
  _ucPosWP < M_ucGetWaySizeWay(_hWay),
  E_uwIAFatalWayPositionInvalid
 );*/
 
 /* Release WP and link :*/
 fn_hReleaseWaypoint(M_hGetWPAtPositionWay(_hWay,ucWP));
#ifndef _WAY_FirstLinkIsFirstWaypoint_
 if(_ucPosWP < M_ucWayNbrOfLink(_hWay))
 {
#endif /*_WAY_FirstLinkIsFirstWaypoint_*/
  fn_hReleaseLink(M_hGetLinkAtPositionWay(_hWay,ucWP));
#ifndef _WAY_FirstLinkIsFirstWaypoint_
 }
 else
 {/* the last WP is currently been removed. So release the last link :*/
  fn_hReleaseLink(M_hGetLinkAtPositionWay(_hWay,ucWP-1));
 }
#endif /* _WAY_FirstLinkIsFirstWaypoint_ */
 
 /* shift the end of the arrays :*/
	for
 (
  ucWP=_ucPosWP;
#ifdef _WAY_FirstLinkIsFirstWaypoint_
  ucWP<M_ucGetWaySizeWay(_hWay)-1;
#else /* _WAY_FirstLinkIsFirstWaypoint_ */
  ucWP<M_ucGetWaySizeWay(_hWay)-2;
#endif /* _WAY_FirstLinkIsFirstWaypoint_ */
  ucWP++
 )
	{
		M_hGetWPAtPositionWay(_hWay,ucWP) = M_hGetWPAtPositionWay(_hWay,ucWP+1);
		M_hGetLinkAtPositionWay(_hWay,ucWP) = M_hGetLinkAtPositionWay(_hWay,ucWP+1);
	}
#ifndef _WAY_FirstLinkIsFirstWaypoint_
  /* number of WPs is greater than number of links, so shift the last WP also :*/
  /* tip : here ucWP gots the good value :
  either M_ucWayNbrOfWP(_hWay) - 2  if it is not the last WP currently removed
  or M_ucWayNbrOfWP(_hWay) - 1 if it is the last WP currently removed
  */
  if(ucWP < M_ucWayNbrOfWP(_hWay) -1 )
  {/* that's not the last WP that is currently removed : */
   M_hGetWPAtPositionWay(_hWay,ucWP) = M_hGetWPAtPositionWay(_hWay,ucWP+1);
  }

#endif /* _WAY_FirstLinkIsFirstWaypoint_ */
 
	if (_hNewLink) M_hGetLinkAtPositionWay (_hWay,_ucPosWP-1) = _hNewLink;

  /* reallocate the way :*/
	fn_vReallocWay(_hWay, M_ucGetWaySizeWay(_hWay)-1);
}

void fn_vSetCurrentWPWay(ACP_tdxHandleOfWay _hWay,tducWPIndex _ucCurrentWP)
{
 if((_ucCurrentWP>=(tducWPIndex)0)&&(_ucCurrentWP<M_ucGetWaySizeWay(_hWay)))
 {
  M_ucGetWayCurrentWPIndex(_hWay) = _ucCurrentWP;
 }
}

// get
tducWPIndex fn_ucGetSizeWay (ACP_tdxHandleOfWay _hWay)
{
	return M_ucGetWaySizeWay(_hWay);
}

ACP_tdxHandleOfWaypoint fn_hGetWayPoint(ACP_tdxHandleOfWay _hWay, tducWPIndex _ucPos)
{
 M_IA_DEBUG_ASSERT(_ucPos < M_ucWayNbrOfWP(_hWay),E_uwIAFatalWayPositionInvalid);
	return M_hGetWPAtPositionWay(_hWay,_ucPos);
}
ACP_tdxHandleOfLink fn_hGetLink(ACP_tdxHandleOfWay _hWay, tducWPIndex _ucPos)
{
 M_IA_DEBUG_ASSERT(_ucPos < M_ucWayNbrOfLink(_hWay),E_uwIAFatalWayPositionInvalid);
	return M_hGetLinkAtPositionWay(_hWay,_ucPos);
}

tducWPIndex fn_ucPositionWayPoint (ACP_tdxHandleOfWay _hWay, ACP_tdxHandleOfWaypoint _hWP)
{
	tducWPIndex ucWP;
	for (ucWP=0; ucWP<M_ucWayNbrOfWP(_hWay); ucWP++) 
  if(M_hGetWPAtPositionWay(_hWay,ucWP)==_hWP) 
   return ucWP;
	return (tducWPIndex)-1;
}

ACP_tdxHandleOfWaypoint fn_hNextWayPoint (ACP_tdxHandleOfWay _hWay)
{
	M_ucGetWayCurrentWPIndex(_hWay) = (M_ucGetWayCurrentWPIndex(_hWay)+1)%M_ucGetWaySizeWay(_hWay);
	return M_hGetWPAtPositionWay(_hWay,M_ucGetWayCurrentWPIndex(_hWay));
}

ACP_tdxHandleOfWaypoint fn_hPrevWayPoint (ACP_tdxHandleOfWay _hWay)
{
	M_ucGetWayCurrentWPIndex(_hWay) = (M_ucGetWayCurrentWPIndex(_hWay)-1)%M_ucGetWaySizeWay(_hWay);
	return M_hGetWPAtPositionWay(_hWay,M_ucGetWayCurrentWPIndex(_hWay));
}

ACP_tdxHandleOfWaypoint fn_hCurrentWayPoint (ACP_tdxHandleOfWay _hWay)
{
	return M_hGetWPAtPositionWay(_hWay,M_ucGetWayCurrentWPIndex(_hWay));
}

SCRIPT_tdeReturnValue fn_eScriptCallBackLoadWay(FILE *p_fFile, char *szAction, char *szParams[], SCRIPT_tdeAction cType)
{
#ifdef toto
	ACP_tdxHandleOfWay hWay;
	long lSizeWay;
 ACP_tdxHandleOfWaypoint hWPBefore,hWPAfter;

	switch (cType)
	{
  case C_SCRIPT_Section:
	  gs_lScriptWayCounter = 0;
	  gs_lScriptLinkCounter = 0;
	  hWay =  fn_hConstructWay ();
   lSizeWay = atol(szParams[0]);
	  fn_vAllocWay (hWay, lSizeWay);
   /* increase ref :*/
   fn_hAddRefWay(hWay);
	  SCRIPT_vSetResult ((long)hWay);		
	  break;
	  
  case C_SCRIPT_Entry:
	  hWay = (ACP_tdxHandleOfWay) SCRIPT_ulGetResult(); 
		  
	  if (strcmp(szAction,"WP")==0)
	  {
		  // load the waypoint
		  SCRIPT_vSetResultSubSection((unsigned long)NULL);
		  M_hGetWPAtPositionWay(hWay,gs_lScriptWayCounter++) = (ACP_tdxHandleOfWaypoint)(SCRIPT_ulAnalyseSection(szParams[0],szParams[1]));
	  }
/*
Link section should following scheme :
Link(LinkType,DynLinkType[,LinkTypeParam][,DynLinTypeParam])
*/
	  else if (strcmp(szAction,"Link")==0)
	  {
		  // load the line link
		  ACP_tdxHandleOfLink hLink = fn_hConstructLink ();
    /* Retrieve wp before and after :*/
#ifdef _WAY_FirstLinkIsFirstWaypoint_
    if(gs_lScriptLinkCounter)
    {
     hWPBefore = M_hGetWPAtPositionWay(hWay,gs_lScriptLinkCounter-1);
     hWPAfter = M_hGetWPAtPositionWay(hWay,gs_lScriptLinkCounter);
    }
    else
    {/* there is no origin WP */
     hWPBefore = ACP_C_InvalidWayPointHandle;
     hWPAfter = M_hGetWPAtPositionWay(hWay,gs_lScriptLinkCounter);
    }
#else /* _WAY_FirstLinkIsFirstWaypoint_ */
    hWPBefore = M_hGetWPAtPositionWay(hWay,gs_lScriptLinkCounter);
    hWPAfter = M_hGetWPAtPositionWay(hWay,gs_lScriptLinkCounter+1);
#endif /* _WAY_FirstLinkIsFirstWaypoint_ */
    /* Now all depends on param :*/
    fn_vBuildLinkFromszParams(hLink,szParams,hWPBefore,hWPAfter);
    /* add a reference to the link :*/
    fn_hAddRefLink(hLink);
    /* set the new link to the current position in the array :*/
		  M_hGetLinkAtPositionWay(hWay,gs_lScriptLinkCounter++) = hLink;
	  }
	  break;
	 case C_SCRIPT_AlreadyAnalysed :
   hWay = (ACP_tdxHandleOfWay) SCRIPT_ulGetResult();
   /* add a reference on the way :*/
   fn_hAddRefWay(hWay);
   break;
  case C_SCRIPT_EndSection:
	  break;
	}

#endif
//	if (lWayCounter!=lSizeWay) SCRIPT_vSetError(E_SCRIPT_UserError1);
//	if (lLinkCounter!=lSizeWay) SCRIPT_vSetError(E_SCRIPT_UserError2);
	return R_SCRIPT_NormalReturn;
}

/*
////////////////////////////////////////////////////////////////////////////////
Description :fnv_InitWayBeforeFollowing
Process intial parameters before following the way
////////////////////////////////////////////////////////////////////////////////
Input :
a handle on the way
a pointer to a void pointer
////////////////////////////////////////////////////////////////////////////////
Output :
None
////////////////////////////////////////////////////////////////////////////////
Error raised:
None
////////////////////////////////////////////////////////////////////////////////
Creation date : January 24,1997
Author : Albert Pais
////////////////////////////////////////////////////////////////////////////////
*/
void fnv_InitWayBeforeFollowing
(
 HIE_tdxHandleToSuperObject _p_SuperObjPerso,
 ACP_tdxHandleOfWay _hWay
)
{
#ifdef _WAY_FirstLinkIsFirstWaypoint_ 
 ACP_tdxHandleOfLink hLink;
 MTH3D_tdstVector stVector;
 
 hLink = M_hGetWayCurrentLink(_hWay);
 switch(M_eucGetLinkConnectionType(hLink))
 {
 case ACP_ConnType_ucStaticLine:
  /* Concerning the type of the way info : */
  fn_vComputeLocationWaypoint
  (
   M_hGetWayCurrentWP(_hWay),/* it is assumed that the current WP is the first one to reach */
   (M_stGetLinkConnTypeStaticVector(hLink))
  );
  /* Dynamic information :*
  POS_fn_vGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(_p_SuperObjPerso),&stVector);
  MTH3D_M_vSubVector((&stVector),(&stVector),(&M_stGetVertex(M_hGetWayCurrentWP(_hWay))));
  fn_vDynamicObject_CalculateNotSampled
  (
   M_stGetLinkConnDynTypeInfo(hLink),
   MTH3D_M_xNormVector((&stVector))
  );*/

  /*break;*//* commented in order to have the dynamic info processed for both cases :*/
 case ACP_ConnType_ucDynamicLine :
  /* Concerninf the type of the way :*/
  /* nothing to do */
  /* Dynamic information :*/
  POS_fn_vGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(_p_SuperObjPerso),&stVector);
  MTH3D_M_vSubVector((&stVector),(&stVector),(&M_stGetVertex(M_hGetWayCurrentWP(_hWay))));
  fn_vDynamicObject_CalculateNotSampled
  (
   &M_stGetLinkConnDynTypeInfo(hLink),
   MTH3D_M_xNormVector((&stVector))
  );
  break;
 
 case ACP_ConnType_ucBezier:
 case ACP_ConnType_ucCircle:
 /* unused to do it each time : 
  fn_vDynamicObject_Calculate(&M_stGetLinkConnDynTypeInfo(hLink));*/
  /* set the current sampling to 0 : */
  M_ucGetLinkCurrentSample(hLink) = 0;
  break;
 }

#endif /*_WAY_FirstLinkIsFirstWaypoint_*/
}

/*
////////////////////////////////////////////////////////////////////////////////
Description :fn_ucCurrentVertexReachedWhileFollowingWay
The current vertex of the way has been reached
////////////////////////////////////////////////////////////////////////////////
Input :
a handle on the way
a pointer to a pointer the args of the way
////////////////////////////////////////////////////////////////////////////////
Output :
None
////////////////////////////////////////////////////////////////////////////////
Error raised:
None
////////////////////////////////////////////////////////////////////////////////
Creation date : January 24,1997
Author : Albert Pais
////////////////////////////////////////////////////////////////////////////////
Rem : This function should increase the current WP count when needed.
////////////////////////////////////////////////////////////////////////////////
*/
unsigned char fn_ucCurrentVertexReachedWhileFollowingWay
(
 HIE_tdxHandleToSuperObject _p_SuperObjPerso,
 ACP_tdxHandleOfWay _hWay
)
{
 unsigned char b_ucGoToNext = 0;
 ACP_tdxHandleOfLink hLink;
 MTH3D_tdstVector stVector;
 
#ifndef _WAY_FirstLinkIsFirstWaypoint_
 if(M_ucGetWayCurrentWPIndex(_hWay))
 {
#endif /* _WAY_FirstLinkIsFirstWaypoint_ */
  
  hLink = M_hGetWayCurrentLink(_hWay);
  /* depends on current WP :*/
  switch(M_eucGetLinkConnectionType(hLink))
  {
   case ACP_ConnType_ucStaticLine:
   case ACP_ConnType_ucDynamicLine :
    /* if it was the last :*/
    if(M_bWayIsLastWayPoint(_hWay,M_ucGetWayCurrentWPIndex(_hWay)))
    {/* it is finished.....*/
      return (unsigned char)0;
    }
    /* if we 've reached the current WP, it means that it is time to go to the next WP :*/
    b_ucGoToNext = 1;
    break;
   case ACP_ConnType_ucBezier:
    /* may be it is not time to go to the next WP */
    M_ucGetLinkCurrentSample(hLink)++;
    if(M_ucGetLinkCurrentSample(hLink) > M_stGetLinkConnTypeBezierObject(hLink)->ucSamplingRate)
    {/* test wether it is the last Wp or not :*/
     if(M_bWayIsLastWayPoint(_hWay,M_ucGetWayCurrentWPIndex(_hWay)))
     {
      /* it is finished :*/
      return (unsigned char)0;
     }
     b_ucGoToNext = 1;
    }
    break;
   case ACP_ConnType_ucCircle:
    /* TODO */
    /* Certainly something like for Bezier curves : */
   default:
    M_IAFatalError(E_uwIAFatalTypeLinkInvalid);
    return (unsigned char)-1;
    break;
  }
 
#ifndef _WAY_FirstLinkIsFirstWaypoint_
 }
 else
 {
  b_ucGoToNext = 1;
 }
#endif /* _WAY_FirstLinkIsFirstWaypoint_ */

 /* if it is time to go to the next WP :*/
 if(b_ucGoToNext)
 {/* go to the next Wp :*/
  fn_hNextWayPoint(_hWay);
  hLink = M_hGetWayCurrentLink(_hWay);
  /* here we know that it is not the last :*/
  switch(M_eucGetLinkConnectionType(hLink))
  {/* concerning the connection type :*/
   case ACP_ConnType_ucStaticLine:
    fn_vComputeLocationWaypoint
    (
     M_hGetWayCurrentWP(_hWay),/* it is assumed that the current WP is the wp to reach */
     M_stGetLinkConnTypeStaticVector(hLink) /* receive the position of the WP at the moment we begin following this link */
    );
    /*break;*/ /* commented in order to process dynamic info for both cases :*/
   case ACP_ConnType_ucDynamicLine :
    /* nothing to do concerning the type*/
    /* But for the dynamic :*/
    POS_fn_vGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(_p_SuperObjPerso),&stVector);
    MTH3D_M_vSubVector((&stVector),(&stVector),(&M_stGetVertex(M_hGetWayCurrentWP(_hWay))));
    fn_vDynamicObject_CalculateNotSampled
    (
     &M_stGetLinkConnDynTypeInfo(hLink),
     MTH3D_M_xNormVector((&stVector))
    );
    break;
   case ACP_ConnType_ucBezier:
   case ACP_ConnType_ucCircle:
   /* unused to do it each time : 
    fn_vDynamicObject_Calculate(&M_stGetLinkConnDynTypeInfo(hLink));*/
    /* set the current sampling to 0 : */
    M_ucGetLinkCurrentSample(hLink) = 0;
    break;
  }
  
 }

 return (unsigned char)1;
}

/*
////////////////////////////////////////////////////////////////////////////////
Description :fn_tdxGetSpeedWay
Return the speed according to the current position of the object, the current
link dynamic type and the current WP to reach
////////////////////////////////////////////////////////////////////////////////
Input :
a handle to the super object
a handle on the way
////////////////////////////////////////////////////////////////////////////////
Output :
A MTH_tdxReal containing the speed
////////////////////////////////////////////////////////////////////////////////
Error raised:
None
////////////////////////////////////////////////////////////////////////////////
Creation date : January 23,1997
Author : Albert Pais
////////////////////////////////////////////////////////////////////////////////
*/
MTH_tdxReal fn_tdxGetSpeedWay
(
 HIE_tdxHandleToSuperObject _p_SuperObjPerso,
 ACP_tdxHandleOfWay _hWay
)
{
 ACP_tdxHandleOfLink hLink;
 MTH3D_tdstVector xPersoVertex;
 MTH_tdxReal xCurrentDist;

#ifndef _WAY_FirstLinkIsFirstWaypoint_
 /* we have one WP more than links */
 /* so if current Wp is the first return 0 :*/
 if(M_ucGetWayCurrentWPIndex(_hWay)==0)
 {
  /* the speed return is zero :*/
  return MTH_C_ZERO;
 }
#endif
 
 hLink = M_hGetWayCurrentLink(_hWay);
 
 switch(M_eucGetLinkConnectionType(hLink))
 {
  case ACP_ConnType_ucStaticLine:
  case ACP_ConnType_ucDynamicLine:
   /* dist between the perso and the WP to reach :*/
   POS_fn_vGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(_p_SuperObjPerso),&xPersoVertex);
   MTH3D_M_vSubVector((&xPersoVertex),(&xPersoVertex),(&M_stGetVertex(M_hGetWayCurrentWP(_hWay))));
   xCurrentDist = MTH3D_M_xNormVector((&xPersoVertex));
   return fn_xDynamicObject_GetSpeedNotSampled
   (
    &M_stGetLinkConnDynTypeInfo(hLink),
    xCurrentDist
   );
   break;
  
  case ACP_ConnType_ucBezier:
  case ACP_ConnType_ucCircle :
   return fn_xDynamicObject_GetSpeed
   (
    &M_stGetLinkConnDynTypeInfo(hLink),
    M_ucGetLinkCurrentSample(hLink)
   );
   break;
 }
 return MTH_C_ZERO;
}

/*
////////////////////////////////////////////////////////////////////////////////
Description :fn_vGetNextPointWay
Return the point to reach according to the current position of the object, the 
current link type and the current WP to reach
////////////////////////////////////////////////////////////////////////////////
Input :
a handle to the super object
a handle on the way
a pointer to the vector that receives the coordinates of the point to reach
a pointer to a MTH_tdxReal that contains the min dist
a pointer to the args
////////////////////////////////////////////////////////////////////////////////
Output :
None
////////////////////////////////////////////////////////////////////////////////
Error raised:
None
////////////////////////////////////////////////////////////////////////////////
Creation date : January 23,1997
Author : Albert Pais
////////////////////////////////////////////////////////////////////////////////
*/
void fn_vGetNextPointWay
(
 HIE_tdxHandleToSuperObject _p_SuperobjPerso,
 ACP_tdxHandleOfWay _hWay,
 MTH3D_tdstVector* _pstVertex,
 MTH_tdxReal* _p_stMinDist
)
{
 ACP_tdxHandleOfLink hLink;

#ifndef _WAY_FirstLinkIsFirstWaypoint_
 if(M_ucGetWayCurrentWPIndex(_hWay))
 {/* current wp is not the first wp of the way :*/
#endif /* _WAY_FirstLinkIsFirstWaypoint_ */

  hLink = M_hGetWayCurrentLink(_hWay);
  switch(M_eucGetLinkConnectionType(hLink))
  {
   case ACP_ConnType_ucStaticLine :
    /* retrive the vertex from the type information :*/
    *_pstVertex = *M_stGetLinkConnTypeStaticVector(hLink);
    break;
   case ACP_ConnType_ucDynamicLine :
    /* compute the current position of the Wp :*/
    fn_vComputeLocationWaypoint
    (
     M_hGetWPAtPositionWay(_hWay,M_ucGetWayCurrentWPIndex(_hWay)),
     _pstVertex
    );
    break;
   case ACP_ConnType_ucBezier :
    fn_vBezierObject_GetPoint
    (
     M_stGetLinkConnTypeBezierObject(hLink),
     M_ucGetLinkCurrentSample(hLink),
     _pstVertex
    );
    break;
   case ACP_ConnType_ucCircle :
    /* TODO */
    /* Certainly something like for Bezier Curves */
    break;
  }
#ifndef _WAY_FirstLinkIsFirstWaypoint_
 }
 else
 {/* current wp is the first wp of the way */
  fn_vComputeLocationWaypoint
  (
   M_hGetWPAtPositionWay(_hWay,M_ucGetWayCurrentWPIndex(_hWay)),
   _pstVertex
  );
 }
#endif /* _WAY_FirstLinkIsFirstWaypoint_ */

 *_p_stMinDist = M_xGetWPRadius(M_hGetWayCurrentWP(_hWay));
}

#ifdef __cplusplus
}
#endif /* __cplusplus */
