#include "stdafx.h"
#include <malloc.h>
#define D_Brain_StructureDefine
#include "Ai.h"
#include "Gam.h"

#include "CFast_1.hpp"
#include "CFast_2.hpp"
#include "EdIRIAGl.hpp"

#include "..\..\Ai\Aibase\DsgMemC.h"
#define CFast_szParamVarName					"CFast_g_a_stParam"

/* usefull for debugging */
//#define MessageBox(a, b, c, d)  assert(NULL)

/*
 *=================================================================================================
 *	Define
 *=================================================================================================
 */
#define C_CurrentPerso				"g_hSuperObjectPerso"
#define C_PseudoTree				"g_a_stPseudoTree"
#define	C_Mind						"p_stLocalMind0"
#define C_LengthOfOptimizedString	512
#define M_CFast_GetReferenceNodeNWithEngine(p_stEngine, indice)        ((AI_M_p_stGetAIModel(p_stEngine->h_Brain->p_stMind))->CFast_dst_RefTreeArray[indice])
#define C_RefTree					"p_stRefTree"
 /*
 *=================================================================================================
 *	Global variables
 *=================================================================================================
 */
tdstTypeOfParam				g_astParamTable[128];
long						g_lIndexInParamTable = 0; 
long						g_lIndexOfAffect = 0; 
long						g_lParameterNumber = 0;
CFast_tdstNode				*g_p_stCurrentCFastNode;
tdstEngineObject			*g_p_stEngine;		
ACP_tdxBool					g_bOperatorGetValueOfVector;
ACP_tdxBool					g_bIsGetVectorValue;
ACP_tdxBool					g_bIsAffect;
ACP_tdxBool					g_bOperatorFieldDetected;
ACP_tdxBool					g_bIsReal;
ACP_tdxBool					g_bIsFunction;
ACP_tdxBool					g_bIsPerso;		
ACP_tdxBool					g_bIsField;
ACP_tdxBool					g_bInteger;
enum tdeVariableType_		g_eTypeVar;
unsigned char				g_ucNbParameter;
char						g_szParameter[2048];
ACP_tdxBool					g_bCasNonTraite;
ACP_tdxBool         g_bPersoUseEngine = FALSE;  /* does the perso structure is a tdstEngineObject (TRUE) 
                                                   or a HIE_tdxHandleToSuperObject (FALSE) */
/*
 *=================================================================================================
 *	Global variables for declaration of vector variable
 *=================================================================================================
 */
long						g_lNumberOfVector = 0;
long						g_lMaxNumberOfVector = 0;
/*
 *=================================================================================================
 *	Global variables for declaration of Real variable
 *=================================================================================================
 */
long						g_lNumberOfReal = 0;
long						g_lMaxNumberOfReal = 0;
/*
 *=================================================================================================
 *	Global variables for declaration of p_stVector variable
 *=================================================================================================
 */
long						g_lNumberOfp_stVector = 0;
long						g_lMaxNumberOfp_stVector = 0;


ACP_tdxBool					g_bDynamReportVar = FALSE;
ACP_tdxBool					g_bDynamVar = FALSE;

/*
 *=================================================================================================
 *	Local functions
 *=================================================================================================
 */
void CFast_fn_vTreatOperator
(	char			*_p_szString,
	char			*_p_szStringPerso,
	long			*_p_lIndex,
	ACP_tdxBool		_bSetFunction
);

void CFast_fn_vGetVariableString
(
	char							*_p_szStringFunc,
	char							*_p_szStringPerso,
	long							_lIndex,
	ACP_tdxBool						_bAffect,
	AI_tdstAIModel    *_p_stAIModel);

void CFast_fn_vTreatOperatorField
(
	enum tdeFieldId_	_eFieldId,
	char				*_p_szPerso,
	char				*_p_szResultString,
	ACP_tdxBool			_bAffect,
	long				_lIndex
);

void CFast_fn_vTreatKeyWord
(
	char				*_p_szParameter,
	enum tdeKeyWordId_	_eKeyWord
);

bool CFast_fn_bIsAModelCastVar ( long index ) ;
bool CFast_fn_bTreatModelCast ( long *_p_lIndex, char *_p_szString, char *_p_szStringPerso, 
                                ACP_tdxBool _bSetFunction) ;
/*
 *=================================================================================================
 *	External functions
 *=================================================================================================
 */
extern int CFast_GetTypeReturnFunc(CFast_tdstNode *p_stParam);

/*
 *=================================================================================================
 *	Internal functions
 *=================================================================================================
 */
/* ------------------------------ */
/* ------------------------------ */
void CFast_fn_vDeclareVectorVariable
(
	char	*_p_szParameter2
)
{
	sprintf(_p_szParameter2, "&stVector%d", g_lNumberOfVector);

	g_lNumberOfVector ++;

	if (g_lNumberOfVector > g_lMaxNumberOfVector)
		g_lMaxNumberOfVector = g_lNumberOfVector;
									
}
/* ------------------------------ */
/* ------------------------------ */
void CFast_fn_vDeclarep_stVectorVariable
(
	char	*_p_szParameter2
)
{
	sprintf(_p_szParameter2, "p_stVector%d", g_lNumberOfp_stVector);

	g_lNumberOfp_stVector ++;

	if (g_lNumberOfp_stVector > g_lMaxNumberOfp_stVector)
		g_lMaxNumberOfp_stVector = g_lNumberOfp_stVector;
									
}
/* ------------------------------ */
/* ------------------------------ */
void CFast_fn_vDeclareRealVariable
(
	char	*_p_szParameter2
)
{
	sprintf(_p_szParameter2, "xReal%d", g_lNumberOfReal);

	g_lNumberOfReal ++;

	if (g_lNumberOfReal > g_lMaxNumberOfReal)
		g_lMaxNumberOfReal = g_lNumberOfReal;
									
}

/* ------------------------------ */
/* ------------------------------ */
void	CFast_fn_vVariablesDeclaration
(
	CFast_tdstComportTree	*_p_stCFastTree
)
{
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
	long			i;
	long			lChar = 0;
	char			*p_szString;
	ACP_tdxBool		bDeclaration = FALSE;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
	if (_p_stCFastTree->d_cDeclarations != NULL)
		free(_p_stCFastTree->d_cDeclarations);
	// Allocation

	_p_stCFastTree->d_cDeclarations = (char *)malloc(1024*256);
	p_szString = _p_stCFastTree->d_cDeclarations;

	// Declaration of real variables
	for (i=0; i<g_lMaxNumberOfReal; i++)
	{
		lChar += sprintf(p_szString + lChar , "  MTH_tdxReal xReal%d;\n", i);
	}

	// Declaration of vector variables
	lChar += sprintf(p_szString + lChar , "  MTH3D_tdstVector stVector%d;\n", 0);
	for (i=1; i<g_lMaxNumberOfVector; i++)
	{
		lChar += sprintf(p_szString + lChar , "  MTH3D_tdstVector stVector%d;\n", i);
	}
	// Declaration of Dynam 
	if (g_bDynamVar)
		lChar += sprintf(p_szString + lChar ,"  MS_tdxHandleToDynam h_Dynam;\n");
	
	// Declaration of Dynam Report
	if (g_bDynamReportVar)
		//lChar += sprintf(p_szString + lChar ,"DNM_tdstReport *p_stDynamReport;\n");
    lChar += sprintf(p_szString + lChar ,"  struct DNM_stDynamics *p_stDynam;\n");
    

	if (lChar == 0)
	{
		free(_p_stCFastTree->d_cDeclarations);
		_p_stCFastTree->d_cDeclarations = NULL;
	}

	if (lChar > (1024*256))
		MessageBox(NULL, "Buffer pas assez grand!!", "OPTIMISATION", MB_ICONSTOP);

}
/* ------------------------------ */
/* ------------------------------ */
void CFast_fn_vSelectSetVar
(	
 enum tdeVariableType_		_eTypeVar,
 char						*_p_szTextFunc
)
{
	switch (_eTypeVar)
	{
	case E_vt_Float:
		strcpy(_p_szTextFunc,"CFast_fn_vSetDsgVarFloat");break;
	case E_vt_Perso:
    if (g_bIsFunction || g_bPersoUseEngine) 
			strcpy(_p_szTextFunc,"CFast_fn_vSetDsgVarPersoWithEngine");
		else
			strcpy(_p_szTextFunc,"CFast_fn_vSetDsgVarPerso");
		break;
	case E_vt_Action:
		strcpy(_p_szTextFunc,"CFast_fn_vSetDsgVarAction");break;
	case E_vt_Comport:
		strcpy(_p_szTextFunc,"CFast_fn_vSetDsgVarComport");break;
	case E_vt_Vector:
		strcpy(_p_szTextFunc,"CFast_fn_vSetDsgVarVector");break;
	case E_vt_Caps:
		strcpy(_p_szTextFunc,"CFast_fn_vSetDsgVarCaps");break;	
	case E_vt_Graph:
		strcpy(_p_szTextFunc,"CFast_fn_vSetDsgVarGraph");break;
	case E_vt_WayPoint:
		strcpy(_p_szTextFunc,"CFast_fn_vSetDsgVarWayPoint");break;
	case E_vt_List:
		strcpy(_p_szTextFunc,"CFast_fn_vSetDsgVarList");break;
	case E_vt_Boolean:
		strcpy(_p_szTextFunc,"CFast_fn_vSetDsgVarBoolean");break;
	case E_vt__128To127:
		strcpy(_p_szTextFunc,"CFast_fn_vSetDsgVar_128To127");break;
	case E_vt_0To255:
		strcpy(_p_szTextFunc,"CFast_fn_vSetDsgVar0To255");break;
	case E_vt__32768To32767:
		strcpy(_p_szTextFunc,"CFast_fn_vSetDsgVar_32768To32767");break;
	case E_vt_0To65535:
		strcpy(_p_szTextFunc,"CFast_fn_vSetDsgVar0To65535");break;
	case E_vt_Integer:
		strcpy(_p_szTextFunc,"CFast_fn_vSetDsgVarInteger");break;         
	case E_vt_PositiveInteger:
		strcpy(_p_szTextFunc,"CFast_fn_vSetDsgVarPositiveInteger");break;
	case E_vt_GameMaterial:
		strcpy(_p_szTextFunc,"CFast_fn_vSetDsgVarGameMaterial");break;
	default:
		//error
		MessageBox(NULL, "La fonction SET pour ce type de variable n'existe pas!!", "OPTIMISATION", MB_ICONSTOP);
		break;
	}
}
/* ------------------------------ */
/* ------------------------------ */
void CFast_fn_vSelectGetVar
(	
 enum tdeVariableType_		_eTypeVar,
 char						*_p_szTextFunc
)
{
	switch (_eTypeVar)
	{
	case E_vt_Float:
		g_bIsReal = TRUE;
		strcpy(_p_szTextFunc,"CFast_fn_xGetDsgVarFloat");break;
	case E_vt_Perso:
    g_bPersoUseEngine = FALSE ;
		strcpy(_p_szTextFunc,"CFast_fn_hGetDsgVarPerso");break;
	case E_vt_Action:
		strcpy(_p_szTextFunc,"CFast_fn_xGetDsgVarAction");break;
	case E_vt_Comport:
		strcpy(_p_szTextFunc,"CFast_fn_xGetDsgVarComport");break;
	case E_vt_Vector:
		strcpy(_p_szTextFunc,"CFast_fn_p_stGetDsgVarVector");break;
	case E_vt_Caps:
		strcpy(_p_szTextFunc,"CFast_fn_ucGetDsgVarCaps");break;	
	case E_vt_Graph:
		strcpy(_p_szTextFunc,"CFast_fn_hGetDsgVarGraph");break;
	case E_vt_WayPoint:
		strcpy(_p_szTextFunc,"CFast_fn_hGetDsgVarWayPoint");break;
	case E_vt_List:
		strcpy(_p_szTextFunc,"CFast_fn_p_xGetDsgVarList");break;
	case E_vt_Boolean:
		strcpy(_p_szTextFunc,"CFast_fn_lGetDsgVarBoolean");g_bInteger = TRUE;break;
	case E_vt__128To127:
		strcpy(_p_szTextFunc,"CFast_fn_lGetDsgVar_128To127");g_bInteger = TRUE;break;
	case E_vt_0To255:
		strcpy(_p_szTextFunc,"CFast_fn_lGetDsgVar0To255");g_bInteger = TRUE;break;
	case E_vt__32768To32767:
		strcpy(_p_szTextFunc,"CFast_fn_lGetDsgVar_32768To32767");g_bInteger = TRUE;break;
	case E_vt_0To65535:
		strcpy(_p_szTextFunc,"CFast_fn_lGetDsgVar0To65535");g_bInteger = TRUE;break;
	case E_vt_Integer:
		strcpy(_p_szTextFunc,"CFast_fn_lGetDsgVarInteger");
		g_bInteger = TRUE;break;         
	case E_vt_PositiveInteger:
		strcpy(_p_szTextFunc,"CFast_fn_lGetDsgVarPositiveInteger");
		g_bInteger = TRUE;
		break;
	case E_vt_GameMaterial:
		strcpy(_p_szTextFunc,"CFast_fn_xGetDsgVarGameMaterial");break;
	default:
		// error
		MessageBox(NULL,  " La fonction GET pour ce type de variable n'existe pas!!","OPTIMISATION", MB_ICONSTOP);
		break;
	}
}
/* ------------------------------ */
/* ------------------------------ */
void CFast_fn_vSelectGetFuncResult
(	
 enum tdeVariableType_		_eTypeVar,
 char						*_p_szTextFunc
)
{
	switch (_eTypeVar)
	{
	case E_vt_Float:
		strcpy(_p_szTextFunc,"M_GetSetParam_xValue");
		g_bIsReal = TRUE;
		break;
	case E_vt_Perso:
		g_bIsFunction = TRUE;
		strcpy(_p_szTextFunc,"M_GetSetParam_p_stEngineObjValue");
		break;
	case E_vt_Action:
		strcpy(_p_szTextFunc,"M_GetSetParam_ActionValue");break;
	case E_vt_Comport:
		strcpy(_p_szTextFunc,"M_GetSetParam_pComport");break;
	case E_vt_Vector:
		strcpy(_p_szTextFunc,"&M_GetSetParam_stVectorValue");break;
	case E_vt_Caps:
		strcpy(_p_szTextFunc,"M_GetSetParam_CapsValue");break;	
	case E_vt_Graph:
		strcpy(_p_szTextFunc,"M_GetSetParam_GraphValue");break;
	case E_vt_WayPoint:
		strcpy(_p_szTextFunc,"M_GetSetParam_WayPointValue");break;
	case E_vt_Integer:
		strcpy(_p_szTextFunc,"M_GetSetParam_lValue");g_bInteger = TRUE;break;         
	case E_vt_PositiveInteger:
		strcpy(_p_szTextFunc,"M_GetSetParam_ulValue");g_bInteger = TRUE;break;
	case E_vt_GameMaterial:
		strcpy(_p_szTextFunc,"M_GetSetParam_hGameMaterial");break;
	default:
		// error
		MessageBox(NULL, "Variable de retour de fonction non traitee!!", "OPTIMISATION",MB_ICONSTOP);
		break;
	}
}
/* ------------------------------ */
/* ------------------------------ */
tdstEngineObject *CFast_fn_p_stGetPersoReference(long _lIndex, char *_p_szStringPerso, ACP_tdxBool _bSetFunction)
{
	tdstEngineObject *p_stEngine = NULL;

	g_astParamTable[_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation =1;
	if (g_astParamTable[_lIndex].eTypeNode == E_ti_KeyWord)
	{
    if (M_eKeyWordIdInterpret(&g_astParamTable[_lIndex].p_stCFastNode->stNode) == eKeyWord_Me)
		{
			p_stEngine = g_p_stEngine;
			strcpy(_p_szStringPerso, C_CurrentPerso);
		}
		else if (M_eKeyWordIdInterpret(&g_astParamTable[_lIndex].p_stCFastNode->stNode) == eKeyWord_MainActor)
		{
			p_stEngine = fn_pstGetMainActor();
			strcpy(_p_szStringPerso, "MC_fn_hGetCharacterInMainCharacterNode(MC_fn_hGetFirstMainCharNode())");

		}
		/*else if (M_eKeyWordIdInterpret(&g_astParamTable[_lIndex].p_stCFastNode->stNode) == eKeyWord_World)
		{
			p_stEngine = fn_pstGetWorld();
			strcpy(_p_szStringPerso," g_stEngineStructure.h_WorldCaracter");
		}*/
		else
		{
			g_bCasNonTraite = TRUE;
			MessageBox(NULL, "OPTIMISATION", "Cas non traite!!", MB_ICONSTOP);
		}
	}
	else {
    if ( !_bSetFunction )
      g_bPersoUseEngine = TRUE ;
		p_stEngine = M_p_stPersoRefInterpret(&(g_astParamTable[_lIndex].p_stCFastNode->stNode));
		sprintf(_p_szStringPerso, "M_CFast_hGetPersoRef( %d)", g_astParamTable[_lIndex].p_stCFastNode->lIndexOfRef);
	}
	return(p_stEngine);
}
/* ------------------------------ */
/* ------------------------------ */
void CFast_fn_vCancelOptimization()
{
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
	CFast_tdstNode *p_stTempCFastNode;
	long			lIndex;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
	
	lIndex = g_lIndexInParamTable;
	while (lIndex <= g_lIndexOfAffect)
	{
		p_stTempCFastNode = g_astParamTable[lIndex].p_stCFastNode;
		if (p_stTempCFastNode)
		{
			if  (p_stTempCFastNode -> d_cOptimisedNode != NULL)
			{
				free(p_stTempCFastNode -> d_cOptimisedNode);
				p_stTempCFastNode -> d_cOptimisedNode = NULL;
			}
			p_stTempCFastNode ->ucNumberOfNodeToSkipAfterOptimisation = 0;
		}
		lIndex ++;
	};
	
	g_bIsFunction = FALSE;
	g_lIndexInParamTable = 0;
}
/* ------------------------------ */
/* ------------------------------ */
void CFast_fn_vUpdateParameters
(
	long	_lIndex
)
{
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
	long			i;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */

	for (i=0; i < _lIndex; i++)
	{
		if (g_astParamTable[i].ucNumberOfParamNeeded != 255)
		{
			g_astParamTable[i].p_stCFastNode->ucNumberOfParamNeeded = g_astParamTable[i].ucNumberOfParamNeeded;
		}
	}
}
/* ------------------------------ */
/* ------------------------------ */
enum tdeVariableType_ CFast_fn_eGetFunctionTypeOutParam
(
	CFast_tdstNode *_p_stParam,
	tdeFuncId_		_eFuncId
)
{
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
	char			szTypeParam[2048];
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
	strcpy(szTypeParam,szGetFunctionTypeOutParamFromId(_eFuncId));
	if (strcmp(szTypeParam, "L")==0) 
	{
		if (CFast_GetTypeReturnFunc(_p_stParam) == 4)
			return E_vt_PositiveInteger;
		else
			return E_vt_Integer;
	}
	else if (strcmp(szTypeParam, "X")==0) return E_vt_Float;
	else if (strcmp(szTypeParam, "P")==0) return E_vt_Perso;
	else if (strcmp(szTypeParam, "V")==0) return E_vt_Vector;
	else if (strcmp(szTypeParam, "W")==0) return E_vt_WayPoint;
	else if (strcmp(szTypeParam, "K")==0) return E_vt_Mask;
	else if (strcmp(szTypeParam, "S")==0) return E_vt_String;
	else if (strcmp(szTypeParam, "C")==0) return E_vt_GameMaterial;
	else if (strcmp(szTypeParam, "#")==0) return E_vt_Caps;
	else if (strcmp(szTypeParam, "M")==0) return E_vt_Module;
	MessageBox(NULL,  "Variable de retour de fonction non traitee!!", "OPTIMISATION", MB_ICONSTOP);
	return(E_vt_None);
}

/* ------------------------------ */
/* ------------------------------ */
enum tdeVariableType_ CFast_fn_eGetDsgVarRefType
(
	tdstNodeInterpret   *_p_stNodeInterpret,
	AI_tdstAIModel      *_p_stAIModel,
	unsigned char       _ucId
)
{
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
	enum tdeDsgVarTypeId_	eVarTypeId;
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
	eVarTypeId = _p_stAIModel->p_stDsgVar->p_stDsgVarInfo[_ucId].eDsgVarTypeId ;
	g_eTypeVar = fn_GetDsgVarType(eVarTypeId);
	return (g_eTypeVar);
}

/* ------------------------------ */
/* ------------------------------ */
void CFast_fn_vTreatParameter(char *_p_szParameter2)
{
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
	long		lIndex;
	char		szVarString[2048];
	char		szFuncName[2048];
	char		szPersoRef[2048];
	char		szTempString[2048];
	long		lSaveParameterNumber;
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
	lIndex = g_lIndexInParamTable;
	switch (g_astParamTable[lIndex].eTypeNode)
	{
	case E_ti_Operator:
		{
			strcpy(szPersoRef, C_CurrentPerso);
			CFast_fn_vTreatOperator(_p_szParameter2, szPersoRef,  &lIndex, FALSE);
			g_lIndexInParamTable --;
			break;
		}
	case E_ti_WayPointRef:
		{
			sprintf(_p_szParameter2,"%s(%s+%d)","M_lWayPointInterpret",C_RefTree,g_astParamTable[(lIndex)].p_stCFastNode->lIndexOfRef);
			g_lIndexInParamTable --;		
			break;
		}
	case E_ti_PersoRef:
		{
      g_bPersoUseEngine = TRUE ;
			sprintf(_p_szParameter2,"%s(%s+%d)","M_p_stPersoRefInterpret",C_RefTree,g_astParamTable[(lIndex)].p_stCFastNode->lIndexOfRef);
			g_lIndexInParamTable --;		
			break;
		}
/*
	case E_ti_ActionRef:
		{
			sprintf(_p_szParameter2,"%s(%s+%d)","M_ActionInterpret",C_RefTree,g_astParamTable[(lIndex)].p_stCFastNode->lIndexOfRef);
			g_lIndexInParamTable --;		
			break;
		}
	case E_ti_LipsSynchroRef:
		{
			sprintf(_p_szParameter2,"%s(%s+%d)","M_hLipSynchroHandleIdInterpret",C_RefTree,g_astParamTable[(lIndex)].p_stCFastNode->lIndexOfRef);
			g_lIndexInParamTable --;		
			break;
		}

	case E_ti_SoundEventRef:
		{
			sprintf(_p_szParameter2,"%s(%s+%d)","M_SoundEventInterpret",C_RefTree,g_astParamTable[(lIndex)].p_stCFastNode->lIndexOfRef);
			g_lIndexInParamTable --;		
			break;
		}

	case E_ti_FamilyRef:
		{
			sprintf(_p_szParameter2,"%s(%s+%d)","M_hFamilyHandleIdInterpret",C_RefTree,g_astParamTable[(lIndex)].p_stCFastNode->lIndexOfRef);
			g_lIndexInParamTable --;		
			break;
		}
*/		
	case E_ti_DsgVarRef:
		{
			g_astParamTable[lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation =1;// DsgVarREf
			strcpy(szPersoRef, C_CurrentPerso);
			CFast_fn_vGetVariableString(szVarString, szPersoRef,  lIndex, FALSE, NULL);
//			sprintf(_p_szParameter2,"%s, %s)",
//								szVarString,C_Mind);
			sprintf(_p_szParameter2,"Local%s)",
								szVarString);
			g_lIndexInParamTable --;		
			break;
		}
	case E_ti_Function:
		{
			g_lParameterNumber ++;
			CFast_fn_vSelectGetFuncResult(g_astParamTable[lIndex].eTypeVar, szFuncName);
			sprintf(_p_szParameter2, "%s(%s+%d)",szFuncName,CFast_szParamVarName, g_astParamTable[lIndex].ucIndexOfEvalParam); // jawaka optimisation N64
			g_lIndexInParamTable --;
			break;
		}
	case E_ti_Constant:
		{
			g_astParamTable[lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;
			sprintf(_p_szParameter2,"%d",M_lValueInterpret((&g_astParamTable[lIndex].p_stCFastNode->stNode)));
			g_lIndexInParamTable --;
			g_bInteger = TRUE;
			break;
		}
	case E_ti_Real:
		{
			g_bIsReal = TRUE;
			g_astParamTable[lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation =1;
			sprintf(_p_szParameter2,"MTH_M_xFloatToReal(%.5ff)",M_xValueInterpret((&g_astParamTable[lIndex].p_stCFastNode->stNode)));
			g_lIndexInParamTable --;
			break;
		}
	case E_ti_Vector:
		{
			char	szElement1[2048];
			char	szElement2[2048];
			char	szElement3[2048];

			g_astParamTable[lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;
			g_lIndexInParamTable --;
			lSaveParameterNumber = g_lParameterNumber;
			g_lParameterNumber = 0;
			g_bIsReal = FALSE;
			CFast_fn_vTreatParameter(szElement3);
			if (!g_bIsReal)
			{
				sprintf(szTempString,"MTH_M_xLongToReal(%s)",szElement3);
				strcpy(szElement3, szTempString);
			}
			g_bIsReal = FALSE;
			CFast_fn_vTreatParameter(szElement2);
			if (!g_bIsReal)
			{
				sprintf(szTempString,"MTH_M_xLongToReal(%s)",szElement2);
				strcpy(szElement2, szTempString);
			}
			g_bIsReal = FALSE;
			CFast_fn_vTreatParameter(szElement1);
			if (!g_bIsReal)
			{
				sprintf(szTempString,"MTH_M_xLongToReal(%s)",szElement1);
				strcpy(szElement1, szTempString);
			}
			g_bIsReal = FALSE;
			g_astParamTable[lIndex].p_stCFastNode->ucNumberOfParamNeeded = (unsigned char)g_lParameterNumber;
			g_lParameterNumber = lSaveParameterNumber; 
			
			CFast_fn_vDeclareVectorVariable(_p_szParameter2);
			g_astParamTable[lIndex].p_stCFastNode -> d_cOptimisedNode = (char *) malloc(2048);
			sprintf(g_astParamTable[lIndex].p_stCFastNode -> d_cOptimisedNode,
									"MTH3D_M_vSetVectorElements(%s, %s, %s, %s)",
									_p_szParameter2,
									szElement1,
									szElement2,
									szElement3);
			break;
		}
	case E_ti_Field:
		{
			strcpy(szPersoRef, C_CurrentPerso);
			CFast_fn_vTreatOperatorField
			(
				M_eFieldIdInterpret(&g_astParamTable[lIndex].p_stCFastNode->stNode),
				szPersoRef,
				_p_szParameter2,
				FALSE,
				lIndex
			);
			g_lIndexInParamTable --;		
			break;
		}
	case E_ti_KeyWord:
		{
			CFast_fn_vTreatKeyWord(_p_szParameter2,M_eKeyWordIdInterpret(&g_astParamTable[lIndex].p_stCFastNode->stNode));
			g_astParamTable[lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;
			g_lIndexInParamTable --;		
			break;
    } 
  case E_ti_Graph :
  case E_ti_TextRef :
  case E_ti_Condition :
  case E_ti_ActionRef :
    g_bCasNonTraite = TRUE;
    break ;
	default:
		{
			// error
			g_bCasNonTraite = TRUE;
			MessageBox(NULL,  "Cas non traite!!", "OPTIMISATION", MB_ICONSTOP);
			break;
		}		
	}
}
/* ------------------------------ */
/* ------------------------------ */
void CFast_fn_vTreatOperatorField
(
	enum tdeFieldId_	_eFieldId,
	char				*_p_szPerso,
	char				*_p_szResultString,
	ACP_tdxBool			_bAffect,
	long				_lIndex
)
{
	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
	char	szTempVar[2048];
	long	lNbCharacter =0;
	char	*p_d_cOptimisedNode;
	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
	g_astParamTable[_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation =1;
	switch (_eFieldId)
	{
		case eField_Position:
			if (_bAffect)
			{
				MessageBox(NULL,  "Pas d'affectation possible!!", "OPTIMISATION", MB_ICONSTOP);
			}
			else
			{
				CFast_fn_vDeclareVectorVariable(_p_szResultString);
				g_astParamTable[_lIndex].p_stCFastNode -> d_cOptimisedNode = (char *) malloc(2048);
				g_astParamTable[_lIndex].p_stCFastNode ->ucNumberOfParamNeeded = 0;
        if ( g_bPersoUseEngine ) 
				  sprintf (g_astParamTable[_lIndex].p_stCFastNode -> d_cOptimisedNode,"POS_fn_vGetTranslationVector(HIE_fn_hGetSuperObjectMatrix(M_GetSuperObject(%s)), %s);", _p_szPerso, _p_szResultString);
        else
          sprintf (g_astParamTable[_lIndex].p_stCFastNode -> d_cOptimisedNode,"POS_fn_vGetTranslationVector(HIE_fn_hGetSuperObjectMatrix(%s), %s);", _p_szPerso, _p_szResultString);
			}
			break;
		case eField_Orientation:

			if (_bAffect)
			{
				MessageBox(NULL,  "Pas d'affectation possible!!", "OPTIMISATION", MB_ICONSTOP);
			}
			else
			{
					CFast_fn_vDeclareVectorVariable(_p_szResultString);
					g_astParamTable[_lIndex].p_stCFastNode -> d_cOptimisedNode = (char *) malloc(1024);
					p_d_cOptimisedNode = g_astParamTable[_lIndex].p_stCFastNode -> d_cOptimisedNode;
					g_astParamTable[_lIndex].p_stCFastNode ->ucNumberOfParamNeeded = 0;
				
					
					lNbCharacter = sprintf(p_d_cOptimisedNode, "MTH3D_M_vSetVectorElements(%s, MTH_C_ZERO, MTH_C_MinusONE, MTH_C_ZERO);\n",_p_szResultString);
					lNbCharacter += sprintf(p_d_cOptimisedNode+lNbCharacter , "POS_fn_vMulMatrixVertex(%s, HIE_fn_hGetSuperObjectGlobalMatrix(%s), %s);\n",
											_p_szResultString,
											_p_szPerso,
											_p_szResultString);
					CFast_fn_vDeclareVectorVariable(szTempVar);

					lNbCharacter += sprintf(p_d_cOptimisedNode+lNbCharacter , "POS_fn_vGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(%s), %s);\n",
											_p_szPerso,
											szTempVar);
					lNbCharacter += sprintf(p_d_cOptimisedNode+lNbCharacter , "MTH3D_M_vSubVector(%s, %s, %s);\n",
											_p_szResultString,
											_p_szResultString,
											szTempVar);
					lNbCharacter += sprintf(p_d_cOptimisedNode+lNbCharacter , "MTH3D_M_vNormalizeVector(%s, %s);\n",
											_p_szResultString,
											_p_szResultString);
					g_lNumberOfVector --; // suppression de szTempVar
			}
			break;
		case eField_Speed:
			if (_bAffect)
			{
				MessageBox(NULL,  "Pas d'affectation possible!!", "OPTIMISATION", MB_ICONSTOP);
			}
			else
			{
					g_bDynamReportVar = TRUE;
					g_astParamTable[_lIndex].p_stCFastNode -> d_cOptimisedNode = (char *) malloc(1024);
					p_d_cOptimisedNode = g_astParamTable[_lIndex].p_stCFastNode -> d_cOptimisedNode;
					CFast_fn_vDeclareVectorVariable(_p_szResultString);

          if ( g_bPersoUseEngine ) {
            lNbCharacter = sprintf(p_d_cOptimisedNode, "p_stDynam = fn_p_stDynamGetDynamicsSO(M_GetSuperObject(%s));\n",_p_szPerso);
          }
          else {
            lNbCharacter = sprintf(p_d_cOptimisedNode, "p_stDynam = fn_p_stDynamGetDynamicsSO(%s);\n",_p_szPerso);
          }
					lNbCharacter += sprintf(p_d_cOptimisedNode + lNbCharacter, "if (p_stDynam != NULL){\n");
					lNbCharacter += sprintf(p_d_cOptimisedNode + lNbCharacter, "MTH3D_M_vCopyVector(%s, DNM_M_pDynamicsGetPreviousSpeed(p_stDynam));}\n",
																				_p_szResultString);
					lNbCharacter += sprintf(p_d_cOptimisedNode + lNbCharacter, "else {MTH3D_M_vNullVector(%s);}",_p_szResultString);        
			}
			break;
		case eField_NormSpeed:
			if (_bAffect)
			{
				MessageBox(NULL,  "Pas d'affectation possible!!", "OPTIMISATION", MB_ICONSTOP);
			}
			else
			{
				CFast_fn_vDeclareRealVariable(_p_szResultString);

				g_bDynamReportVar = TRUE;
				g_astParamTable[_lIndex].p_stCFastNode -> d_cOptimisedNode = (char *) malloc(1024);
				p_d_cOptimisedNode = g_astParamTable[_lIndex].p_stCFastNode -> d_cOptimisedNode;

          if ( g_bPersoUseEngine ) {
            lNbCharacter = sprintf(p_d_cOptimisedNode, "p_stDynam = fn_p_stDynamGetDynamicsSO(M_GetSuperObject(%s));\n",_p_szPerso);
          }
          else {
            lNbCharacter = sprintf(p_d_cOptimisedNode, "p_stDynam = fn_p_stDynamGetDynamicsSO(%s);\n",_p_szPerso);
          }
					lNbCharacter += sprintf(p_d_cOptimisedNode + lNbCharacter, "if (p_stDynam != NULL){\n");
					lNbCharacter += sprintf(p_d_cOptimisedNode + lNbCharacter, "%s = MTH3D_M_xNormVector(DNM_M_pDynamicsGetPreviousSpeed(p_stDynam));}\n",
																				_p_szResultString);
					lNbCharacter += sprintf(p_d_cOptimisedNode + lNbCharacter, "else {%s=MTH_C_ZERO;}",_p_szResultString);
			}
			break;
/* ANNECY MT - 25/08/98 {
		case eField_SightAxis:
			if ((_bAffect) || (g_bOperatorGetValueOfVector))
			{
				g_astParamTable[_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;
				g_bDynamVar = TRUE;
				lNbCharacter = sprintf(_p_szResultString, "h_Dynam = M_GetMSHandle(%s,Dynam);\n",_p_szPerso);
				lNbCharacter += sprintf(_p_szResultString + lNbCharacter, "if (h_Dynam!= NULL){\n");
				lNbCharacter += sprintf(_p_szResultString + lNbCharacter,"MTH3D_M_vCopyVector(&(h_Dynam->stSightAxisSystem.SightAxis),%s);}",g_szParameter);
			}
			else
			{
				g_bDynamVar = TRUE;
				g_astParamTable[_lIndex].p_stCFastNode -> d_cOptimisedNode = (char *) malloc(1024);
				p_d_cOptimisedNode = g_astParamTable[_lIndex].p_stCFastNode -> d_cOptimisedNode;
				CFast_fn_vDeclareVectorVariable(_p_szResultString);

				lNbCharacter = sprintf(p_d_cOptimisedNode, "h_Dynam = M_GetMSHandle(%s,Dynam);\n",_p_szPerso);
				lNbCharacter += sprintf(p_d_cOptimisedNode + lNbCharacter, "if (h_Dynam!= NULL){\n");
				lNbCharacter += sprintf(p_d_cOptimisedNode + lNbCharacter, "MTH3D_M_vCopyVector(%s, fn_p_DynamGetSightAxis(h_Dynam));}\n",_p_szResultString);
				lNbCharacter += sprintf(p_d_cOptimisedNode + lNbCharacter, "else {MTH3D_M_vNullVector(%s);}",_p_szResultString);
			}
			break;
		case eField_FirstCompAxis:
			if (_bAffect)
			{

				g_bDynamVar = TRUE;
				g_astParamTable[_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;
				lNbCharacter = sprintf(_p_szResultString, "h_Dynam = M_GetMSHandle(%s,Dynam);\n",_p_szPerso);
				lNbCharacter += sprintf(_p_szResultString + lNbCharacter, "if (h_Dynam!= NULL){\n");
				lNbCharacter += sprintf(_p_szResultString + lNbCharacter,"MTH3D_M_vCopyVector(&(h_Dynam->stSightAxisSystem.FirstComplementaryAxis),%s);}",g_szParameter);
			}
			else
			{
				g_bDynamVar = TRUE;
				g_astParamTable[_lIndex].p_stCFastNode -> d_cOptimisedNode = (char *) malloc(1024);
				p_d_cOptimisedNode = g_astParamTable[_lIndex].p_stCFastNode -> d_cOptimisedNode;
				CFast_fn_vDeclareVectorVariable(_p_szResultString);

				lNbCharacter = sprintf(p_d_cOptimisedNode, "h_Dynam = M_GetMSHandle(%s,Dynam);\n",_p_szPerso);
				lNbCharacter += sprintf(p_d_cOptimisedNode + lNbCharacter, "if (h_Dynam!= NULL){\n");
				lNbCharacter += sprintf(p_d_cOptimisedNode + lNbCharacter, "MTH3D_M_vCopyVector(%s, fn_p_DynamGetFirstComplementaryAxis(h_Dynam));}\n",
																				_p_szResultString);
				lNbCharacter += sprintf(p_d_cOptimisedNode + lNbCharacter, "else {MTH3D_M_vNullVector(%s);}",_p_szResultString);

			}
			break;
		case eField_SecondCompAxis:
			if (_bAffect)
			{
				g_bDynamVar = TRUE;
				g_astParamTable[_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;
				lNbCharacter = sprintf(_p_szResultString, "h_Dynam = M_GetMSHandle(%s,Dynam);\n",_p_szPerso);
				lNbCharacter += sprintf(_p_szResultString + lNbCharacter, "if (h_Dynam!= NULL){\n");
				lNbCharacter += sprintf(_p_szResultString + lNbCharacter,"MTH3D_M_vCopyVector(&(h_Dynam->stSightAxisSystem.SecondComplementaryAxis),%s);}",g_szParameter);
  			}
			else
			{
				g_bDynamVar = TRUE;
				g_astParamTable[_lIndex].p_stCFastNode -> d_cOptimisedNode = (char *) malloc(1024);
				p_d_cOptimisedNode = g_astParamTable[_lIndex].p_stCFastNode -> d_cOptimisedNode;
				CFast_fn_vDeclareVectorVariable(_p_szResultString);

				lNbCharacter = sprintf(p_d_cOptimisedNode, "h_Dynam = M_GetMSHandle(%s,Dynam);\n",_p_szPerso);
				lNbCharacter += sprintf(p_d_cOptimisedNode + lNbCharacter, "if (h_Dynam!= NULL){\n");
				lNbCharacter += sprintf(p_d_cOptimisedNode + lNbCharacter, "MTH3D_M_vCopyVector(%s, fn_p_DynamGetSecondComplementaryAxis(h_Dynam));}\n",
																				_p_szResultString);
				lNbCharacter += sprintf(p_d_cOptimisedNode + lNbCharacter, "else {MTH3D_M_vNullVector(%s);}",_p_szResultString);
			}
			break;
END ANNECY MT } */
		case eField_AbsoluteAxisX:
			if (_bAffect)
			{
				MessageBox(NULL,  "Pas d'affectation possible!!", "OPTIMISATION", MB_ICONSTOP);
			}
			else
			{
				CFast_fn_vDeclareVectorVariable(_p_szResultString);
				CFast_fn_vDeclareVectorVariable(szTempVar);

				g_astParamTable[_lIndex].p_stCFastNode -> d_cOptimisedNode = (char *) malloc(2048);
				g_astParamTable[_lIndex].p_stCFastNode ->ucNumberOfParamNeeded = 0;
				sprintf (g_astParamTable[_lIndex].p_stCFastNode -> d_cOptimisedNode,"POS_fn_vGetRotationMatrix(HIE_fn_hGetSuperObjectGlobalMatrix(%s),%s,%s,%s);\n",
																					_p_szPerso,
																					szTempVar,
																					_p_szResultString,
																					szTempVar);
				g_lNumberOfVector --; // suppression de szTempVar				
			}
			break;
		case eField_AbsoluteAxisY:
			if (_bAffect)
			{
				MessageBox(NULL,  "Pas d'affectation possible!!", "OPTIMISATION", MB_ICONSTOP);
			}
			else
			{
				CFast_fn_vDeclareVectorVariable(_p_szResultString);
				CFast_fn_vDeclareVectorVariable(szTempVar);

				g_astParamTable[_lIndex].p_stCFastNode -> d_cOptimisedNode = (char *) malloc(2048);
				g_astParamTable[_lIndex].p_stCFastNode ->ucNumberOfParamNeeded = 0;
				sprintf (g_astParamTable[_lIndex].p_stCFastNode -> d_cOptimisedNode,"POS_fn_vGetRotationMatrix(HIE_fn_hGetSuperObjectGlobalMatrix(%s),%s,%s,%s);\n",
																					_p_szPerso,
																					szTempVar,
																					szTempVar,
																					_p_szResultString);
				g_lNumberOfVector --; // suppression de szTempVar				
			}
			break;
		case eField_AbsoluteAxisZ:
			if (_bAffect)
			{
				MessageBox(NULL,  "Pas d'affectation possible!!", "OPTIMISATION", MB_ICONSTOP);
			}
			else
			{
				CFast_fn_vDeclareVectorVariable(_p_szResultString);
				CFast_fn_vDeclareVectorVariable(szTempVar);

				g_astParamTable[_lIndex].p_stCFastNode -> d_cOptimisedNode = (char *) malloc(2048);
				g_astParamTable[_lIndex].p_stCFastNode ->ucNumberOfParamNeeded = 0;
				sprintf (g_astParamTable[_lIndex].p_stCFastNode -> d_cOptimisedNode,"POS_fn_vGetRotationMatrix(HIE_fn_hGetSuperObjectGlobalMatrix(%s),%s,%s,%s);\n",
																					_p_szPerso,
																					_p_szResultString,
																					szTempVar,
																					szTempVar);
				g_lNumberOfVector --; // suppression de szTempVar				
			}
			break;
		case eField_PrevComportIntell:
			if (_bAffect)
			{
				MessageBox(NULL,  "Pas d'affectation possible!!", "OPTIMISATION", MB_ICONSTOP);
			}
			else
			{
				// Tester l'acteur pour optimiser
				sprintf (_p_szResultString,"M_GetPrevComport(AI_M_p_stGetIntelligence(AI_M_stGetMindOfSuperObj(%s)))", _p_szPerso);
			}
			break;
		case eField_PrevComportReflex:
			if (_bAffect)
			{
				MessageBox(NULL,  "Pas d'affectation possible!!", "OPTIMISATION", MB_ICONSTOP);
			}
			else
			{
			// Tester l'acteur pour optimiser
				sprintf (_p_szResultString,"M_GetPrevComport(AI_M_p_stGetReflex(AI_M_stGetMindOfSuperObj(%s)))", _p_szPerso);
			}
			break;
		case eField_ShadowScaleX:
			g_bIsReal = TRUE;
			g_astParamTable[_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;
			if (_bAffect)
				sprintf (_p_szResultString,"fn_v3dDataSetShadowScaleXInSO(%s,%s)",_p_szPerso,g_szParameter);
			else
				sprintf (_p_szResultString,"fn_ucGetFieldShadowScaleXFromSO(%s)",_p_szPerso);
			break;
		case eField_ShadowScaleY:
			g_bIsReal = TRUE;
			g_astParamTable[_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;
			if (_bAffect)
				sprintf (_p_szResultString,"fn_v3dDataSetShadowScaleYInSO(%s,%s)",_p_szPerso, g_szParameter);
			else
				sprintf (_p_szResultString,"fn_ucGetFieldShadowScaleYFromSO(%s)",_p_szPerso);
			break;
		default:
			// error
			g_bCasNonTraite = TRUE;
			MessageBox(NULL,  "Cas non traite!!", "OPTIMISATION", MB_ICONSTOP);
			break;
	}
}
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
/*
	Depiller de n elements
*/
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
void CFast_fn_vPopParamTable
(
	unsigned char	_ucNbParameterNeeded
)
{
	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
	long						i = 0;
	unsigned char				ucNbParameters;
	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

	while ((g_lIndexInParamTable >= 0) &&(i  < _ucNbParameterNeeded))
	{
		ucNbParameters =  g_astParamTable[g_lIndexInParamTable].p_stCFastNode -> ucNumberOfParamNeeded;
		if (M_GetTypeInterpret(&g_astParamTable[g_lIndexInParamTable].p_stCFastNode->stNode) == E_ti_Function)
			ucNbParameters = 0;
		g_lIndexInParamTable --;
		if (ucNbParameters)
			CFast_fn_vPopParamTable(ucNbParameters);	
		i++;
	}
}
/*
 *================================================================================================= 
*/
/*
	Récupération d'une variable
*/
/*
 *=================================================================================================
 */
void CFast_fn_vGetVariableString
(
	char              *_p_szStringFunc,
	char              *_p_szStringPerso,
	long              _lIndex,
	ACP_tdxBool       _bAffect,
  AI_tdstAIModel    *_p_stAIModel	
)
{
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
	char			szFuncName[2048];
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

	if (_p_stAIModel == NULL)
	{
		if (_bAffect)
			CFast_fn_vSelectSetVar(CFast_fn_eGetDsgVarRefType
											(	
											&g_astParamTable[_lIndex].p_stCFastNode->stNode,
											AI_M_p_stGetAIModel(M_pstGetMindOfBrain(g_p_stEngine->h_Brain)),
											(unsigned char)M_lDsgVarIdInterpret(&g_astParamTable[_lIndex].p_stCFastNode->stNode)
											), 
									szFuncName);
		else
			CFast_fn_vSelectGetVar(CFast_fn_eGetDsgVarRefType
											(	
											&g_astParamTable[_lIndex].p_stCFastNode->stNode,
											AI_M_p_stGetAIModel(M_pstGetMindOfBrain(g_p_stEngine->h_Brain)),
											(unsigned char)M_lDsgVarIdInterpret(&g_astParamTable[_lIndex].p_stCFastNode->stNode)
											), 
									szFuncName);

		sprintf(_p_szStringFunc,"%s(%d",
						szFuncName,
						 (unsigned char)M_lDsgVarIdInterpret(&g_astParamTable[_lIndex].p_stCFastNode->stNode));

	}
	else
	{
		if (_bAffect)
			CFast_fn_vSelectSetVar(CFast_fn_eGetDsgVarRefType
											(	
											&g_astParamTable[_lIndex].p_stCFastNode->stNode,
											_p_stAIModel,
											(unsigned char)M_lDsgVarIdInterpret(&g_astParamTable[_lIndex].p_stCFastNode->stNode)
											), 
									szFuncName);
		else
			CFast_fn_vSelectGetVar(CFast_fn_eGetDsgVarRefType
											(	
											&g_astParamTable[_lIndex].p_stCFastNode->stNode,
											_p_stAIModel,
											(unsigned char)M_lDsgVarIdInterpret(&g_astParamTable[_lIndex].p_stCFastNode->stNode)
											), 
									szFuncName);

		if (g_astParamTable[_lIndex].p_stCFastNode->lIndexOfRef  < 0)
			sprintf(_p_szStringFunc,"%s(%s(%d)",
										szFuncName,
										"M_CFast_ucGetRealIndice",
										(unsigned char)M_lDsgVarIdInterpret(&g_astParamTable[_lIndex].p_stCFastNode->stNode));
		else
			sprintf(_p_szStringFunc,"%s(%s(%d)",
										szFuncName,
										"M_CFast_ucGetRealIndice",
										(unsigned char)g_astParamTable[_lIndex].p_stCFastNode->lIndexOfRef);



	}

}
/*
 *================================================================================================= 
*/
/*
	Récuperation de la valeur d'un Keyword
*/
/*
 *=================================================================================================
 */
void CFast_fn_vTreatKeyWord
(
	char				*_p_szParameter,
	enum tdeKeyWordId_	_eKeyWord
)
{
		switch (_eKeyWord)
		{
				case eKeyWord_Me:
					strcpy(_p_szParameter, C_CurrentPerso);
					break;
				case eKeyWord_MainActor:
					strcpy(_p_szParameter, "MC_fn_hGetCharacterInMainCharacterNode(MC_fn_hGetFirstMainCharNode())");
					break;
				/*case eKeyWord_World:
					strcpy(_p_szParameter, "gp_stActualWorld");
					break;*/
				case eKeyWord_Nobody:
				case eKeyWord_Nowhere:
				case eKeyWord_NoGraph:
        case eKeyWord_NoAction:
					strcpy(_p_szParameter, "NULL");
					break;
				case eKeyWord_CapsNull:
					strcpy(_p_szParameter, "0");
					break;
				case eKeyWord_True:
					strcpy(_p_szParameter, "TRUE");
					break;
				case eKeyWord_False:
					strcpy(_p_szParameter, "FALSE");
					break;
				default:
					break;
		}

}

/*
 *=================================================================================================
 */
 /*
 Traitement des operateurs Get x,y ou z d'un vecteur
 */
/*	
 *=================================================================================================
 */
void CFast_fn_vTreatOperatorGetValueOfVector
(
	char			*_p_szStringFunc,
	char			*_p_szStringPerso,
	long			*_p_lIndex,
  ACP_tdxBool _bSetFunction
)
{
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
	tdstEngineObject				*p_stEngine;
  AI_tdstAIModel          *p_stAIModel ;
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
	g_astParamTable[*_p_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation =1;	// skip eOperator_GetVectorX
	g_lIndexInParamTable--;
	(*_p_lIndex)--;
	g_bOperatorGetValueOfVector = TRUE;
	switch (g_astParamTable[*_p_lIndex].eTypeNode)
	{
	case E_ti_Operator:
		{
			switch (g_astParamTable[*_p_lIndex].eOperatorId)
			{
			case eOperator_Dot:
				{
					g_astParamTable[(*_p_lIndex)].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;
					g_lIndexInParamTable--;
					(*_p_lIndex)--;

          if ( (g_astParamTable[(*_p_lIndex)].eTypeNode == E_ti_DsgVarRef) ) {
            if ( !CFast_fn_bIsAModelCastVar((*_p_lIndex)) )
				      g_bCasNonTraite = TRUE;
            else { /* modelcast */
  					  if ( !CFast_fn_bTreatModelCast (_p_lIndex, _p_szStringFunc, _p_szStringPerso, FALSE) )
                g_bCasNonTraite = TRUE;
            }
          }
					else
					{
						p_stEngine = CFast_fn_p_stGetPersoReference((*_p_lIndex)-1, _p_szStringPerso, _bSetFunction);
            p_stAIModel = AI_M_p_stGetAIModel(M_pstGetMindOfBrain(p_stEngine->h_Brain)) ;

						CFast_fn_vGetVariableString(_p_szStringFunc,_p_szStringPerso,*_p_lIndex, FALSE, p_stAIModel);
						g_astParamTable[(*_p_lIndex)].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;	// skip E_ti_Operator, E_ti_DsgVarRef, E_ti_PersoRef
					}
					g_lIndexInParamTable--;
					break;
				}
			default:
				g_bCasNonTraite = TRUE;
				MessageBox(NULL, "Cas non traite!!", "OPTIMISATION", MB_ICONSTOP);
				break;

			}
			break;
		}
	case E_ti_DsgVarRef:
		{
			g_astParamTable[*_p_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation =1;	// skip E_ti_DsgVarRef

			strcpy(_p_szStringPerso, C_CurrentPerso);

			CFast_fn_vGetVariableString(_p_szStringFunc,_p_szStringPerso,*_p_lIndex, FALSE, NULL);
			break;
		}
	case E_ti_Field:
		{
			g_bIsField = TRUE;
			CFast_fn_vTreatOperatorField
			(
				M_eFieldIdInterpret(&g_astParamTable[*_p_lIndex].p_stCFastNode->stNode),
				C_CurrentPerso,
				_p_szStringFunc,			
				FALSE,
				*_p_lIndex
			);
			break;
		}
	default:
		{
		g_bCasNonTraite = TRUE;
		MessageBox(NULL, "Cas non traite!!", "OPTIMISATION", MB_ICONSTOP);
		break;
		}
	}
}

/*
 *=================================================================================================
 */
 /*
 Traitement de l'operateur Array
 */
/*	
 *=================================================================================================
 */
void CFast_fn_vTreatOperatorArray
(
	char		*_p_szString, 
	char		*_p_szStringPerso, 
	long		*_p_lIndex,
	ACP_tdxBool	_bSetFunction
)
{
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
	char						szStringIndice[2048]; 
	char						szIndexString[2048];
	char						szVarString[2048];
	char						szPersoRef[2048];
	char						szFuncName[2048];
//	HIE_tdxHandleToSuperObject	hPerso;
	unsigned char				ucArrayVarIndex = 0;
	tdstArray					*p_stArray;
	tdstEngineObject			*p_stEngine;
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

	g_astParamTable[(*_p_lIndex)].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;
	// Index in array
	g_lIndexInParamTable--;
	(*_p_lIndex)--;
	switch (g_astParamTable[*_p_lIndex].eTypeNode)
	{
	case E_ti_Constant:
		{
			g_astParamTable[*_p_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation =1;	// skip E_ti_Constant
			sprintf(szIndexString, "%d", M_lValueInterpret((&g_astParamTable[(*_p_lIndex)].p_stCFastNode->stNode)));
			break;
		}
	case E_ti_Function:
		{
			g_lParameterNumber ++;
			sprintf(szIndexString, "M_tduGetSetParam_ulValue(%s+%d)",CFast_szParamVarName, g_astParamTable[*_p_lIndex].ucIndexOfEvalParam); // jawaka optimisation N64
			break;
		}
	case E_ti_DsgVarRef:
		{
			g_astParamTable[*_p_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation =1;	// skip E_ti_DsgVarRef

			strcpy(_p_szStringPerso, C_CurrentPerso);
			CFast_fn_vGetVariableString(szVarString, _p_szStringPerso,  *_p_lIndex, FALSE, NULL);

//			sprintf(szIndexString,"%s, %s)",
//								szVarString,C_Mind);
			sprintf(szIndexString,"Local%s)",
								szVarString);
			break;
		}
	case E_ti_Operator:
		{
			switch (g_astParamTable[*_p_lIndex].eOperatorId)
			{
			case eOperator_Dot:
			{
				CFast_fn_vTreatOperator(szIndexString, szPersoRef, _p_lIndex, FALSE);
				break;
			}
			case eOperator_Array:
			{
				CFast_fn_vTreatOperatorArray(szIndexString, szPersoRef, _p_lIndex, FALSE);
				break;
			}
			default:
				g_bCasNonTraite = TRUE;
				MessageBox(NULL, "Cas non traite!!", "OPTIMISATION",  MB_ICONSTOP);
				break;
			}

			break;
		}
	default:
		g_bCasNonTraite = TRUE;
		MessageBox(NULL,  "Cas non traite!!", "OPTIMISATION", MB_ICONSTOP);
		break;
	}	

	g_lIndexInParamTable--;
	(*_p_lIndex)--;
	//  Array
	if (g_astParamTable[*_p_lIndex].eTypeNode == E_ti_Operator)
	{
		g_astParamTable[*_p_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation =1;

		if ((g_astParamTable[(*_p_lIndex)-1].eTypeNode == E_ti_DsgVarRef)
			||
			(g_astParamTable[(*_p_lIndex)-1].eTypeNode == E_ti_Operator)/*ModelCast*/)
		{
			g_bCasNonTraite = TRUE;
		}
		else
		{	
			p_stEngine =CFast_fn_p_stGetPersoReference((*_p_lIndex)-1, _p_szStringPerso, _bSetFunction);

			ucArrayVarIndex =(unsigned char) M_lDsgVarIdInterpret(&M_CFast_GetReferenceNodeNWithEngine(p_stEngine,(unsigned char)M_lDsgVarIdInterpret(&g_astParamTable[(*_p_lIndex)].p_stCFastNode->stNode)));

			if (g_astParamTable[(*_p_lIndex)].p_stCFastNode->lIndexOfRef  < 0)
				sprintf(szStringIndice, "%s(%d)",
											"M_CFast_ucGetRealIndice",
											(unsigned char)g_astParamTable[(*_p_lIndex)].p_stCFastNode->lIndexOfRef);
			else
				sprintf(szStringIndice, "%s(%d)",
											"M_CFast_ucGetRealIndice",
											ucArrayVarIndex);

			g_astParamTable[*_p_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation =1;
			g_lIndexInParamTable--;
			(*_p_lIndex)--;
		}
	}
	else
	{
		strcpy(_p_szStringPerso, C_CurrentPerso);

		p_stEngine =g_p_stEngine;

		ucArrayVarIndex = (unsigned char)M_lDsgVarIdInterpret(&g_astParamTable[(*_p_lIndex)].p_stCFastNode->stNode);
		g_astParamTable[*_p_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation =1;	// skip E_ti_DsgVarR

		sprintf(szStringIndice, "%d", ucArrayVarIndex);
	}

	p_stArray=(tdstArray*)M_GetDsgVarAddrInit(p_stEngine->h_Brain->p_stMind,ucArrayVarIndex);
	if (_bSetFunction)
	{
		switch (M_ARRAY_TYPE(p_stArray))
		{
		case eDsgVarType_Perso:
      if ( g_bPersoUseEngine ) {
        strcpy(szFuncName,"CFast_fn_vSetDsgVarPersoArrayWithEngine");
      }
      else {
			  strcpy(szFuncName,"CFast_fn_vSetDsgVarPersoArray");
      }
			break;
		case eDsgVarType_Vector:
			strcpy(szFuncName,"CFast_fn_vSetDsgVarVectorArray");
      g_eTypeVar = E_vt_Vector;
			break;
		case eDsgVarType_Float:	
			strcpy(szFuncName,"CFast_fn_vSetDsgVarFloatArray");
      g_eTypeVar = E_vt_Float;
			break;
		case eDsgVarType_Integer:
			strcpy(szFuncName,"CFast_fn_vSetDsgVarIntegerArray");
			break;
		case eDsgVarType_WayPoint:
			strcpy(szFuncName,"CFast_fn_vSetDsgVarWayPointArray");
			break;
		case eDsgVarType_Text:
			strcpy(szFuncName,"CFast_fn_vSetDsgVarTextArray");
			break;
		default:
			g_bCasNonTraite = TRUE;
			MessageBox(NULL, "Cas non traite!!", "OPTIMISATION", MB_ICONSTOP);
			break;
		}
		if (p_stEngine == g_p_stEngine)
			sprintf(_p_szString,"%s(%s,%s,%s,",
				szFuncName,
				szStringIndice,
				C_Mind,
				szIndexString);
		else
			sprintf(_p_szString,"%s(%s,AI_M_stGetMindOfSuperObj(%s),%s,",
				szFuncName,
				szStringIndice,
				_p_szStringPerso,
				szIndexString);
	}
	else
	{
		switch (M_ARRAY_TYPE(p_stArray))
		{
		case eDsgVarType_Perso:
			strcpy(szFuncName,"CFast_fn_hGetDsgVarPersoArray");
			break;
		case eDsgVarType_Vector:
			strcpy(szFuncName,"CFast_fn_p_stGetDsgVarVectorArray");
			break;
		case eDsgVarType_Float:	
			strcpy(szFuncName,"CFast_fn_xGetDsgVarFloatArray");
			break;
		case eDsgVarType_Integer:
			strcpy(szFuncName,"CFast_fn_lGetDsgVarIntegerArray");
			break;
		case eDsgVarType_WayPoint:
			strcpy(szFuncName,"CFast_fn_hGetDsgVarWayPointArray");
			break;
		case eDsgVarType_Text:
			strcpy(szFuncName,"CFast_fn_p_szGetDsgVarTextArray");
			break;
		default:
			g_bCasNonTraite = TRUE;
			MessageBox(NULL, "Cas non traite!!", "OPTIMISATION", MB_ICONSTOP);
			break;
		}
		if (p_stEngine == g_p_stEngine)
			sprintf(_p_szString,"%s(%s,%s,%s)",
				szFuncName,
				szStringIndice,
				C_Mind,
				szIndexString);
		else
			sprintf(_p_szString,"%s(%s,AI_M_stGetMindOfSuperObj(%s),%s)",
				szFuncName,
				szStringIndice,
				_p_szStringPerso,
				szIndexString);
	}
			


}
 /*
 *=================================================================================================
 */
 /*
 Traitements de tous les operateurs
 */
 /*	
 *=================================================================================================
 */
void CFast_fn_vTreatOperation
(
	char			*_p_szString,
	char			*_p_OpFloat,
	char			*_p_OpInteger,
	long			*_p_lIndex

)
{
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
	char							szFirstParameter[2048];
	char							szSecondParameter[2048];
	char							szTempString[2048];
	ACP_tdxBool						bFirstParameterIsReal;
	ACP_tdxBool						bSecondParameterIsReal;
	long							lSaveParameterNumber;
	long							lSaveIndex;
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 

	g_astParamTable[*_p_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;	
	lSaveIndex = *_p_lIndex;
	lSaveParameterNumber = g_lParameterNumber;
	g_lParameterNumber = 0;
		
	g_lIndexInParamTable--;
	(*_p_lIndex)--;
	g_bIsReal = FALSE;
	CFast_fn_vTreatParameter(szSecondParameter);
	bSecondParameterIsReal = g_bIsReal;
	g_bIsReal = FALSE;
	CFast_fn_vTreatParameter(szFirstParameter);
	bFirstParameterIsReal = g_bIsReal;		
	g_astParamTable[lSaveIndex].ucNumberOfParamNeeded = (unsigned char)g_lParameterNumber;
	g_lParameterNumber = lSaveParameterNumber;
	if (bSecondParameterIsReal || bFirstParameterIsReal)
	{
		g_bIsReal = TRUE;
		if (!bSecondParameterIsReal)
		{
			sprintf(szTempString,"MTH_M_xLongToReal(%s)",szSecondParameter);
			strcpy(szSecondParameter, szTempString);
		}
		if (!bFirstParameterIsReal)
		{
			sprintf(szTempString,"MTH_M_xLongToReal(%s)",szFirstParameter);
			strcpy(szFirstParameter, szTempString);
		}
		sprintf(_p_szString,"%s(%s,%s)", _p_OpFloat, szFirstParameter, szSecondParameter);
	}
	else
	{
		g_bIsReal = FALSE;
		sprintf(_p_szString,"(%s %s %s)", szFirstParameter, _p_OpInteger ,szSecondParameter);
	}
	g_lIndexInParamTable++;
	*_p_lIndex= g_lIndexInParamTable;
}
/*
======================================================
======================================================
*/
void CFast_fn_vTreatOperator
(
	char			*_p_szString,
	char			*_p_szStringPerso,
	long			*_p_lIndex,
	ACP_tdxBool		_bSetFunction
)
{
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
	char							szFuncName[2048];
	char							szFirstParameter[2048];
	char							szSecondParameter[2048];
	char							szTempParameter[2048];
	char							*p_szText;
	ACP_tdxBool						bSecondParameterIsReal;
	tdstEngineObject				*p_stEngine;
	long							lSaveParameterNumber;
	long							lSaveIndex;
  AI_tdstAIModel    *p_stAIModel ;
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
	switch (g_astParamTable[*_p_lIndex].eOperatorId)
	{
		case eOperator_Dot:
			{
				g_astParamTable[(*_p_lIndex)].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;
				g_lIndexInParamTable--;
				(*_p_lIndex)--;

        /* model cast */
        if ( (g_astParamTable[(*_p_lIndex)].eTypeNode == E_ti_DsgVarRef) 
           && CFast_fn_bIsAModelCastVar((*_p_lIndex)) ) {
          if ( !CFast_fn_bTreatModelCast (_p_lIndex, _p_szString, _p_szStringPerso, _bSetFunction) ) {
            g_bCasNonTraite = TRUE;
          }
        }
        /* variable designer (sauf tableaux !)*/
        else if (g_astParamTable[*_p_lIndex].eTypeNode == E_ti_DsgVarRef) {
          p_stEngine =CFast_fn_p_stGetPersoReference((*_p_lIndex)-1, _p_szStringPerso, _bSetFunction);
          p_stAIModel = AI_M_p_stGetAIModel(M_pstGetMindOfBrain(p_stEngine->h_Brain)) ;
          
          CFast_fn_vGetVariableString(szFuncName,_p_szStringPerso, *_p_lIndex, _bSetFunction, p_stAIModel );
          strcat(szFuncName, ",");
          sprintf( _p_szString,"%s AI_M_stGetMindOfSuperObj(%s)",
                   szFuncName,
                   _p_szStringPerso);
          
          if (_bSetFunction)
            strcat(_p_szString,",");
          else
            strcat(_p_szString,")");
          g_astParamTable[(*_p_lIndex)].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;	
        }
        /* field */
        else if (g_astParamTable[*_p_lIndex].eTypeNode == E_ti_Field) {
          long lIndex ;
          
          lIndex = *_p_lIndex ;
          g_lIndexInParamTable--;
          (*_p_lIndex)--;
          CFast_fn_vTreatParameter(_p_szStringPerso);
          
          g_bOperatorFieldDetected = TRUE;
          CFast_fn_vTreatOperatorField (
            M_eFieldIdInterpret(&g_astParamTable[lIndex].p_stCFastNode->stNode),
            _p_szStringPerso,
            _p_szString,			
            _bSetFunction,
            *_p_lIndex
            );
          g_lIndexInParamTable+=2; /* !!! */
          (*_p_lIndex)+=2;
        }
        else {
          /* tableaux */
          g_bCasNonTraite = TRUE;
        }
		    g_lIndexInParamTable--;
        (*_p_lIndex)--;
				break;
			}
		case eOperator_GetVectorX:
			{
				g_bIsField = FALSE;
				g_astParamTable[(*_p_lIndex)].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;	
				CFast_fn_vTreatOperatorGetValueOfVector(szFuncName,_p_szStringPerso,_p_lIndex, _bSetFunction);
				if (g_bIsField)
					sprintf(_p_szString,"(%s)->xX",
									szFuncName);
				else
				{
					if (strcmp(_p_szStringPerso, C_CurrentPerso) == 0)
						sprintf(_p_szString,"Local%s)->xX",
										szFuncName);
					else
						sprintf(_p_szString,"%s, AI_M_stGetMindOfSuperObj(%s))->xX",
										szFuncName,
										_p_szStringPerso);
				}
				g_bIsGetVectorValue = TRUE;
				g_bIsReal = TRUE;
				break;
			}
		case eOperator_GetVectorY:
			{
				g_bIsField = FALSE;
				g_astParamTable[(*_p_lIndex)].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;	
				CFast_fn_vTreatOperatorGetValueOfVector(szFuncName,_p_szStringPerso,_p_lIndex, _bSetFunction);

				if (g_bIsField)
					sprintf(_p_szString,"(%s)->xY",
									szFuncName);
				else
				{
					if (strcmp(_p_szStringPerso, C_CurrentPerso) == 0)
						sprintf(_p_szString,"Local%s)->xY",
										szFuncName);
					else
						sprintf(_p_szString,"%s, AI_M_stGetMindOfSuperObj(%s))->xY",
									szFuncName,
									_p_szStringPerso);
				}
				
				g_bIsGetVectorValue = TRUE;
				g_bIsReal = TRUE;
				break;
			}
		case eOperator_GetVectorZ:
			{
				g_bIsField = FALSE;
				g_astParamTable[(*_p_lIndex)].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;	
				CFast_fn_vTreatOperatorGetValueOfVector(szFuncName,_p_szStringPerso,_p_lIndex, _bSetFunction);
				if (g_bIsField)
					sprintf(_p_szString,"(%s)->xZ",
									szFuncName);
				else
				{
					if (strcmp(_p_szStringPerso, C_CurrentPerso) == 0)
						sprintf(_p_szString,"Local%s)->xZ",
										szFuncName);
					else
						sprintf(_p_szString,"%s, AI_M_stGetMindOfSuperObj(%s))->xZ",
									szFuncName,
									_p_szStringPerso);
				}
				g_bIsGetVectorValue = TRUE;
				g_bIsReal = TRUE;
				break;
			}
		case eOperator_Array:
			{
				CFast_fn_vTreatOperatorArray(_p_szString, _p_szStringPerso, _p_lIndex, _bSetFunction);			
				break;
			}
		case eOperator_ScalarPlusScalar:
			{
/*				g_astParamTable[*_p_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;	
				lSaveIndex = *_p_lIndex;
				lSaveParameterNumber = g_lParameterNumber;
				g_lParameterNumber = 0;
				
				g_lIndexInParamTable--;
				(*_p_lIndex)--;
				g_bIsReal = FALSE;
				CFast_fn_vTreatParameter(szSecondParameter);
				bSecondParameterIsReal = g_bIsReal;
				g_bIsReal = FALSE;
				CFast_fn_vTreatParameter(szFirstParameter);
				bFirstParameterIsReal = g_bIsReal;		
				g_astParamTable[lSaveIndex].ucNumberOfParamNeeded = (unsigned char)g_lParameterNumber;
				g_lParameterNumber = lSaveParameterNumber;
				if (bSecondParameterIsReal || bFirstParameterIsReal)
				{
					g_bIsReal = TRUE;
					if (!bSecondParameterIsReal)
					{
						sprintf(szTempString,"MTH_M_xLongToReal(%s)",szSecondParameter);
						strcpy(szSecondParameter, szTempString);
					}
					else if (!bFirstParameterIsReal)
					{
						sprintf(szTempString,"MTH_M_xLongToReal(%s)",szSecondParameter);
						strcpy(szSecondParameter, szTempString);
					}
					sprintf(_p_szString,"MTH_M_xAdd(%s,%s)", szFirstParameter, szSecondParameter);
				}
				else
				{
					sprintf(_p_szString,"(%s + %s)", szFirstParameter, szSecondParameter);
				}
				g_lIndexInParamTable++;
				*_p_lIndex= g_lIndexInParamTable;
*/
				CFast_fn_vTreatOperation(_p_szString,"MTH_M_xAdd", "+",_p_lIndex);
				break;
			}
		case eOperator_ScalarMinusScalar:
			{
/*
				g_astParamTable[*_p_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;	
				lSaveIndex = *_p_lIndex;
				lSaveParameterNumber = g_lParameterNumber;
				g_lParameterNumber = 0;
				
				g_lIndexInParamTable--;
				(*_p_lIndex)--;
				g_bIsReal = FALSE;
				CFast_fn_vTreatParameter(szSecondParameter);
				bSecondParameterIsReal = g_bIsReal;
				g_bIsReal = FALSE;
				CFast_fn_vTreatParameter(szFirstParameter);		
				bFirstParameterIsReal = g_bIsReal;		

				g_astParamTable[lSaveIndex].ucNumberOfParamNeeded = (unsigned char)g_lParameterNumber;
				g_lParameterNumber = lSaveParameterNumber;
				if (bSecondParameterIsReal || bFirstParameterIsReal)
				{
					g_bIsReal = TRUE;					
					sprintf(_p_szString,"MTH_M_xSub(%s,%s)", szFirstParameter, szSecondParameter);
				}
				else
				{
					sprintf(_p_szString,"(%s - %s)", szFirstParameter, szSecondParameter);
				}
				g_lIndexInParamTable++;
				*_p_lIndex = g_lIndexInParamTable;
*/
				CFast_fn_vTreatOperation(_p_szString,"MTH_M_xSub", "-",_p_lIndex);
				break;
			}
		case eOperator_ScalarMulScalar:
			{
/*
				g_astParamTable[*_p_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;	
				lSaveIndex = *_p_lIndex;
				lSaveParameterNumber = g_lParameterNumber;
				g_lParameterNumber = 0;
				
				g_lIndexInParamTable--;
				(*_p_lIndex)--;
				CFast_fn_vTreatParameter(szSecondParameter);
				CFast_fn_vTreatParameter(szFirstParameter);
				
				g_astParamTable[lSaveIndex].ucNumberOfParamNeeded = (unsigned char)g_lParameterNumber;
				g_lParameterNumber = lSaveParameterNumber;

				if (g_bIsReal)
					sprintf(_p_szString,"MTH_M_xMul(%s,%s)", szFirstParameter, szSecondParameter);
				else
					sprintf(_p_szString,"(%s * %s)", szFirstParameter, szSecondParameter);
				g_lIndexInParamTable++;
				*_p_lIndex= g_lIndexInParamTable;
*/
				CFast_fn_vTreatOperation(_p_szString,"MTH_M_xMul", "*",_p_lIndex);
				break;
			}
		case eOperator_ScalarDivScalar:
			{
/*
				g_astParamTable[*_p_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;	
				lSaveIndex = *_p_lIndex;
				lSaveParameterNumber = g_lParameterNumber;
				g_lParameterNumber = 0;
				
				g_lIndexInParamTable--;
				(*_p_lIndex)--;
				CFast_fn_vTreatParameter(szSecondParameter);
				CFast_fn_vTreatParameter(szFirstParameter);
				
				g_astParamTable[lSaveIndex].ucNumberOfParamNeeded = (unsigned char)g_lParameterNumber;
				g_lParameterNumber = lSaveParameterNumber;

				if (g_bIsReal)
					sprintf(_p_szString,"MTH_M_xDiv(%s,%s)", szFirstParameter, szSecondParameter);
				else
					sprintf(_p_szString,"(%s/%s)", szFirstParameter, szSecondParameter);
				g_lIndexInParamTable++;
				*_p_lIndex= g_lIndexInParamTable;
*/
				CFast_fn_vTreatOperation(_p_szString,"MTH_M_xDiv", "/",_p_lIndex);

				break;
			}
		case eOperator_ScalarUnaryMinus:
			{
				g_astParamTable[*_p_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;	
				lSaveIndex = *_p_lIndex;
				lSaveParameterNumber = g_lParameterNumber;
				g_lParameterNumber = 0;
				
				g_lIndexInParamTable--;
				(*_p_lIndex)--;
				CFast_fn_vTreatParameter(szFirstParameter);
				
				g_astParamTable[lSaveIndex].ucNumberOfParamNeeded = (unsigned char)g_lParameterNumber;
				g_lParameterNumber = lSaveParameterNumber;

				if (g_bIsReal)
					sprintf(_p_szString,"MTH_M_xNeg(%s)", szFirstParameter);
				else
					sprintf(_p_szString,"(- %s)", szFirstParameter);

				g_lIndexInParamTable++;
				*_p_lIndex = g_lIndexInParamTable;
				break;
			}
		case eOperator_VectorPlusVector:
			{
				g_astParamTable[*_p_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;	
				g_astParamTable[g_lIndexInParamTable].p_stCFastNode -> d_cOptimisedNode = (char *) malloc(2048);
				p_szText = g_astParamTable[g_lIndexInParamTable].p_stCFastNode-> d_cOptimisedNode;
				lSaveIndex = *_p_lIndex;
				lSaveParameterNumber = g_lParameterNumber;
				g_lParameterNumber = 0;
				
				g_lIndexInParamTable--;
				(*_p_lIndex)--;
				CFast_fn_vTreatParameter(szSecondParameter);
        g_bPersoUseEngine = FALSE ;
				CFast_fn_vTreatParameter(szFirstParameter);
				
				g_astParamTable[lSaveIndex].ucNumberOfParamNeeded = (unsigned char)g_lParameterNumber;
				g_lParameterNumber = lSaveParameterNumber;

				g_lIndexInParamTable++;
				CFast_fn_vDeclareVectorVariable(_p_szString);
				sprintf(p_szText,"MTH3D_M_vAddVector(%s, %s,%s)", _p_szString, szFirstParameter, szSecondParameter);
				*_p_lIndex = g_lIndexInParamTable;
				break;
			}
		case eOperator_VectorMinusVector:
			{
				g_astParamTable[*_p_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;	
				g_astParamTable[g_lIndexInParamTable].p_stCFastNode -> d_cOptimisedNode = (char *) malloc(2048);
				p_szText = g_astParamTable[g_lIndexInParamTable].p_stCFastNode-> d_cOptimisedNode;
				lSaveIndex = *_p_lIndex;
				lSaveParameterNumber = g_lParameterNumber;
				g_lParameterNumber = 0;
				
				g_lIndexInParamTable--;
				(*_p_lIndex)--;
				CFast_fn_vTreatParameter(szSecondParameter);
        g_bPersoUseEngine = FALSE ;
				CFast_fn_vTreatParameter(szFirstParameter);
				
				g_astParamTable[lSaveIndex].ucNumberOfParamNeeded = (unsigned char)g_lParameterNumber;
				g_lParameterNumber = lSaveParameterNumber;

				g_lIndexInParamTable++;
				CFast_fn_vDeclareVectorVariable(_p_szString);
				sprintf(p_szText,"MTH3D_M_vSubVector(%s, %s,%s)", _p_szString, szFirstParameter, szSecondParameter);
				*_p_lIndex = g_lIndexInParamTable;
				break;
			}
		case eOperator_VectorMulScalar:
			{
				g_astParamTable[*_p_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;	
				g_astParamTable[g_lIndexInParamTable].p_stCFastNode -> d_cOptimisedNode = (char *) malloc(2048);
				p_szText = g_astParamTable[g_lIndexInParamTable].p_stCFastNode-> d_cOptimisedNode;
				lSaveIndex = *_p_lIndex;
				lSaveParameterNumber = g_lParameterNumber;
				g_lParameterNumber = 0;
				
				g_lIndexInParamTable--;
				(*_p_lIndex)--;
				g_bIsReal = FALSE;
				g_bInteger = FALSE;
				CFast_fn_vTreatParameter(szSecondParameter);
				if (g_bInteger)
				{
					sprintf(szTempParameter,"MTH_M_xLongToReal(%s)",szSecondParameter);
					bSecondParameterIsReal = TRUE;
					strcpy(szSecondParameter, szTempParameter);
				}	
				else
				{
					bSecondParameterIsReal = g_bIsReal;
				}
				g_bInteger = FALSE;
        g_bPersoUseEngine = FALSE ;
				CFast_fn_vTreatParameter(szFirstParameter);
				if (g_bInteger)
				{
					sprintf(szTempParameter,"MTH_M_xLongToReal(%s)",szFirstParameter);
					strcpy(szFirstParameter, szTempParameter);
				}	

				g_astParamTable[lSaveIndex].ucNumberOfParamNeeded = (unsigned char)g_lParameterNumber;
				g_lParameterNumber = lSaveParameterNumber;

				g_lIndexInParamTable++;
				CFast_fn_vDeclareVectorVariable(_p_szString);
				if (bSecondParameterIsReal)
					sprintf(p_szText,"MTH3D_M_vMulScalarVector(%s, %s,%s)", _p_szString, szSecondParameter, szFirstParameter);
				else
					sprintf(p_szText,"MTH3D_M_vMulScalarVector(%s, %s,%s)", _p_szString, szFirstParameter, szSecondParameter);

				*_p_lIndex = g_lIndexInParamTable;
				break;
			}
		case eOperator_VectorDivScalar:
			{
				g_astParamTable[*_p_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;	

				g_astParamTable[g_lIndexInParamTable].p_stCFastNode -> d_cOptimisedNode = (char *) malloc(2048);
				p_szText = g_astParamTable[g_lIndexInParamTable].p_stCFastNode-> d_cOptimisedNode;
				lSaveIndex = *_p_lIndex;
				lSaveParameterNumber = g_lParameterNumber;
				g_lParameterNumber = 0;
				
				g_lIndexInParamTable--;
				(*_p_lIndex)--;
				g_bInteger = FALSE;
				CFast_fn_vTreatParameter(szSecondParameter);
				if (g_bInteger)
				{
					sprintf(szTempParameter,"MTH_M_xLongToReal(%s)",szSecondParameter);
					strcpy(szSecondParameter, szTempParameter);
				}
        g_bPersoUseEngine = FALSE ;
				CFast_fn_vTreatParameter(szFirstParameter);
				
				g_astParamTable[lSaveIndex].ucNumberOfParamNeeded = (unsigned char)g_lParameterNumber;
				g_lParameterNumber = lSaveParameterNumber;

				g_lIndexInParamTable++;
				CFast_fn_vDeclareVectorVariable(_p_szString);
				sprintf(p_szText,"MTH3D_M_vDivScalarVector(%s, %s,%s)", _p_szString, szFirstParameter, szSecondParameter);
				*_p_lIndex = g_lIndexInParamTable;
				break;
			}
		case eOperator_VectorUnaryMinus:
			{
				g_astParamTable[*_p_lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1;	
				g_astParamTable[g_lIndexInParamTable].p_stCFastNode -> d_cOptimisedNode = (char *) malloc(2048);
				p_szText = g_astParamTable[g_lIndexInParamTable].p_stCFastNode-> d_cOptimisedNode;
				lSaveIndex = *_p_lIndex;
				lSaveParameterNumber = g_lParameterNumber;
				g_lParameterNumber = 0;
				
				g_lIndexInParamTable--;
				(*_p_lIndex)--;
				CFast_fn_vTreatParameter(szFirstParameter);

				g_astParamTable[lSaveIndex].ucNumberOfParamNeeded = (unsigned char)g_lParameterNumber;
				g_lParameterNumber = lSaveParameterNumber;
				
				g_lIndexInParamTable++;
				CFast_fn_vDeclareVectorVariable(_p_szString);
				sprintf(p_szText,"MTH3D_M_vNegVector(%s,%s)", _p_szString, szFirstParameter);
				*_p_lIndex = g_lIndexInParamTable;
				break;
			}

		case eOperator_Ultra:
			{
				// A REVOIR
				g_lParameterNumber += 2;
				g_lIndexInParamTable--;
				(*_p_lIndex)--;
				break;
			}

		default:
			g_bCasNonTraite = TRUE;
			MessageBox(NULL, "OPTIMISATION", "Cas non traite!!", MB_ICONSTOP);
			break;
		}
}
/*
 *=================================================================================================
 *	
 *=================================================================================================
 */
char CFast_fn_cOptimizeAffectPlusOP(char _cOperation, ACP_tdxBool	_bTwoParameter)
/*
	_cOperation 
		1		=> Add
		2		=> Sub
		3		=> Mul
		4		=> Div
*/
{
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
	long			lIndex;
	long			lSave_IndexInParamTable;
	char			szParameter2[512];
	char			szGetParameter[512];
	char			szSetParameter[512];
	char			szVarString[2048];
	char			szOperationName[2048];
	char			szPersoRef[2048];
	char			szTempString[2048];
	ACP_tdxBool		bSecondParameterIsReal = FALSE;
	ACP_tdxBool		bSecondParameterIsInteger = FALSE;
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	g_p_stCurrentCFastNode->d_cOptimisedNode = (char *)malloc(C_LengthOfOptimizedString);

	g_bIsReal = FALSE;
	g_bInteger = FALSE;
	if (_bTwoParameter)
	{
		///////////////////////////////////////
		// second Parameter 
		///////////////////////////////////////
		CFast_fn_vTreatParameter(szParameter2);
		bSecondParameterIsReal = g_bIsReal;
		bSecondParameterIsInteger = g_bInteger;
	}
	if (g_bCasNonTraite)
	{
		CFast_fn_vCancelOptimization();
		return 0;
	}

	lSave_IndexInParamTable = g_lIndexInParamTable;
	lIndex = g_lIndexInParamTable;
	g_bIsGetVectorValue = FALSE;
	switch (g_astParamTable[lIndex].eTypeNode)
	{
	case E_ti_Operator:
		{
			g_bOperatorFieldDetected = FALSE;
			CFast_fn_vTreatOperator(szGetParameter, szPersoRef, &lIndex, FALSE);

			if (g_bCasNonTraite)
			{
				CFast_fn_vCancelOptimization();
				return 0;
			}
			if (g_bOperatorFieldDetected)
			{
				long  lSave = g_lIndexInParamTable;
				long lChar = 0;
				// cas du field
				g_lIndexInParamTable  = lSave_IndexInParamTable - 1; // skip dot
				lIndex = g_lIndexInParamTable;
				CFast_fn_vDeclareVectorVariable(g_szParameter);

				switch (_cOperation)
				{
					case 1:
						{
							lChar+=sprintf(g_p_stCurrentCFastNode->d_cOptimisedNode,"%s(%s,%s,%s)",
											"MTH3D_M_vAddVector",
											g_szParameter,
											szGetParameter,
											szParameter2);
							break;
						}
					case 2:
						{
							lChar+=sprintf(g_p_stCurrentCFastNode->d_cOptimisedNode,"%s(%s,%s,%s)",
											"MTH3D_M_vSubVector",
											g_szParameter,
											szGetParameter,
											szParameter2);

							break;
						}
					case 3:
						{
							lChar+=sprintf(g_p_stCurrentCFastNode->d_cOptimisedNode,"%s(%s,%s,%s)",
											"MTH3D_M_vMulScalarVector",
											g_szParameter,
											szParameter2,
											szGetParameter);

							break;
						}
					case 4:
						{
							lChar+=sprintf(g_p_stCurrentCFastNode->d_cOptimisedNode,"%s(%s,%s,%s)",
											"MTH3D_M_vDivScalarVector",
											g_szParameter,
											szGetParameter,
											szParameter2);

								break;
						}
					}
					CFast_fn_vTreatOperatorField
					(
						M_eFieldIdInterpret(&g_astParamTable[lIndex].p_stCFastNode->stNode),
						szPersoRef,
						szSetParameter,			
						TRUE,
						lIndex
					);
					if (g_bCasNonTraite)
					{
						CFast_fn_vCancelOptimization();
						return 0;
					}
					sprintf(g_p_stCurrentCFastNode->d_cOptimisedNode + lChar,"\n%s",szSetParameter);
					g_lIndexInParamTable = lSave;
					return 1;
			}
			else
			{
				g_lIndexInParamTable  = lSave_IndexInParamTable;
				lIndex = g_lIndexInParamTable;
				CFast_fn_vTreatOperator(szSetParameter, szPersoRef, &lIndex, TRUE);
				if (g_bCasNonTraite)
				{
					CFast_fn_vCancelOptimization();
					return 0;
				}
			}
			break;
		}
	case E_ti_DsgVarRef:
		{
			g_astParamTable[lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation =1;// DsgVarREf
			strcpy(szPersoRef, C_CurrentPerso);
			CFast_fn_vGetVariableString(szVarString,szPersoRef, lIndex, FALSE, NULL);
//			sprintf(szGetParameter,"%s, %s)",
//								szVarString, C_Mind);	
			sprintf(szGetParameter,"Local%s)",
								szVarString);

			g_lIndexInParamTable  = lSave_IndexInParamTable;
			CFast_fn_vGetVariableString(szVarString,szPersoRef, lIndex, TRUE, NULL);

//			sprintf(szSetParameter,"%s, %s,",
//								szVarString, C_Mind);
			sprintf(szSetParameter,"Local%s, ",
								szVarString);
			break;
		}
	case E_ti_Field:
		{
			char lChar = 0;

			CFast_fn_vTreatOperatorField
			(
				M_eFieldIdInterpret(&g_astParamTable[lIndex].p_stCFastNode->stNode),
				C_CurrentPerso,
				szGetParameter,			
				FALSE,
				lIndex
			);
			CFast_fn_vDeclareVectorVariable(g_szParameter);
			switch (_cOperation)
			{
			case 1:
				{
					lChar+=sprintf(g_p_stCurrentCFastNode->d_cOptimisedNode,"%s(%s,%s,%s)",
									"MTH3D_M_vAddVector",
									g_szParameter,
									szGetParameter,
									szParameter2);
					break;
				}
			case 2:
				{
					lChar+=sprintf(g_p_stCurrentCFastNode->d_cOptimisedNode,"%s(%s,%s,%s)",
									"MTH3D_M_vSubVector",
									g_szParameter,
									szGetParameter,
									szParameter2);

					break;
				}
			case 3:
				{
					lChar+=sprintf(g_p_stCurrentCFastNode->d_cOptimisedNode,"%s(%s,%s,%s)",
									"MTH3D_M_vMulScalarVector",
									g_szParameter,
									szParameter2,
									szGetParameter);

					break;
				}
			case 4:
				{
					lChar+=sprintf(g_p_stCurrentCFastNode->d_cOptimisedNode,"%s(%s,%s,%s)",
									"MTH3D_M_vDivScalarVector",
									g_szParameter,
									szGetParameter,
									szParameter2);

						break;
				}
			}
			CFast_fn_vTreatOperatorField
			(
				M_eFieldIdInterpret(&g_astParamTable[lIndex].p_stCFastNode->stNode),
				C_CurrentPerso,
				szSetParameter,			
				TRUE,
				lIndex
			);
			sprintf(g_p_stCurrentCFastNode->d_cOptimisedNode + lChar,"\n%s",szSetParameter);
			return 1;
		}
	default:
		g_bCasNonTraite = TRUE;
		MessageBox(NULL, "Cas non traite!!", "OPTIMISATION", MB_ICONSTOP);
		break;

	}

	if (g_bCasNonTraite)
	{
		CFast_fn_vCancelOptimization();
		return 0;
	}
	if (g_bIsGetVectorValue)
		g_eTypeVar = E_vt_Float;

	switch (g_eTypeVar)
	{
	case E_vt_Float:
		{
			if (!_bTwoParameter) 
			{
				strcpy(szParameter2, "MTH_C_ONE");
			}
			switch (_cOperation)
			{
			case 1:
				strcpy(szOperationName,"MTH_M_xAdd");break;
			case 2:
				strcpy(szOperationName,"MTH_M_xSub");break;
			case 3:
				strcpy(szOperationName,"MTH_M_xMul");break;
			case 4:
				strcpy(szOperationName,"MTH_M_xDiv");break;
			}

			if (bSecondParameterIsInteger)
			{
				sprintf(szTempString,"MTH_M_xLongToReal(%s)",szParameter2);
				strcpy(szParameter2, szTempString);
			}
			if ( g_bIsGetVectorValue)		
			{
				sprintf(g_p_stCurrentCFastNode->d_cOptimisedNode,"%s = %s(%s,%s)",
								szSetParameter,
								szOperationName,
								szGetParameter,
								szParameter2);
			}
			else
			{
				sprintf(g_p_stCurrentCFastNode->d_cOptimisedNode,"%s%s(%s,%s))",
								szSetParameter,
								szOperationName,
								szGetParameter,
								szParameter2);
			}	
			break;
		}
	case E_vt_Vector:
		{
			switch (_cOperation)
			{
			case 1:
				{
					sprintf(g_p_stCurrentCFastNode->d_cOptimisedNode,"%s(%s,%s,%s)",
									"MTH3D_M_vAddVector",
									szGetParameter,
									szGetParameter,
									szParameter2);
					break;
				}
			case 2:
				{
					sprintf(g_p_stCurrentCFastNode->d_cOptimisedNode,"%s(%s,%s,%s)",
									"MTH3D_M_vSubVector",
									szGetParameter,
									szGetParameter,
									szParameter2);

					break;
				}
			case 3:
				{
					if (bSecondParameterIsInteger)
					{
						sprintf(szTempString,"MTH_M_xLongToReal(%s)",szParameter2);
						strcpy(szParameter2, szTempString);
					}
					sprintf(g_p_stCurrentCFastNode->d_cOptimisedNode,"%s(%s,%s,%s)",
									"MTH3D_M_vMulScalarVector",
									szGetParameter,
									szParameter2,
									szGetParameter);

					break;
				}
			case 4:
				{
					if (bSecondParameterIsInteger)
					{
						sprintf(szTempString,"MTH_M_xLongToReal(%s)",szParameter2);
						strcpy(szParameter2, szTempString);
					}
					sprintf(g_p_stCurrentCFastNode->d_cOptimisedNode,"%s(%s,%s,%s)",
									"MTH3D_M_vDivScalarVector",
									szGetParameter,
									szGetParameter,
									szParameter2);

						break;
				}
			}
			break;
		}
	default:
		{
			if (!_bTwoParameter)
			{
				strcpy(szParameter2, "1");
			}

			switch (_cOperation)
			{
			case 1:
				strcpy(szOperationName,"+");break;
			case 2:
				strcpy(szOperationName,"-");break;
			case 3:
				strcpy(szOperationName,"*");break;
			case 4:
				strcpy(szOperationName,"/");break;
			}

			if (bSecondParameterIsReal)
			{
				sprintf(szTempString,"MTH_M_xRealToLong(%s)",szParameter2);
				strcpy(szParameter2, szTempString);
			}
			sprintf(g_p_stCurrentCFastNode->d_cOptimisedNode,"%s(%s%s%s))",
							szSetParameter,
							szGetParameter,
							szOperationName,
							szParameter2);
			break;
		}
	}
	return 1;
}
/*
 *=================================================================================================
 *	
 *=================================================================================================
 */
char CFast_fn_cOptimizeAffectVectorValue(long _lFuncIndex)
/*
	eOperator_SetVectorZ:
	eOperator_SetVectorY:
	eOperator_SetVectorX:
*/
{
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
	long			lIndex;
	char			szParameter2[512];
	char			szParameter1[512];
	char			szVarString[2048];
	char			szPersoRef[2048];
	ACP_tdxBool		bSecondParameterIsInteger = FALSE;
	char			szTempString[2048];
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	g_p_stCurrentCFastNode->d_cOptimisedNode = (char *)malloc(C_LengthOfOptimizedString);

	g_bInteger = FALSE;
	///////////////////////////////////////
	// second Parameter 
	///////////////////////////////////////
	CFast_fn_vTreatParameter(szParameter2);
	bSecondParameterIsInteger = g_bInteger;
	if (g_bCasNonTraite)
	{
		CFast_fn_vCancelOptimization();
		return 0;
	}
	lIndex = g_lIndexInParamTable;
	///////////////////////////////////////
	// first Parameter 
	///////////////////////////////////////
	switch (g_astParamTable[lIndex].eTypeNode)
	{
	case E_ti_Operator:
		{
			CFast_fn_vTreatOperator(szParameter1, szPersoRef, &lIndex, FALSE);
			break;
		}
	case E_ti_DsgVarRef:
		{
			g_astParamTable[lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation =1;// DsgVarREf
			strcpy(szPersoRef, C_CurrentPerso);
			CFast_fn_vGetVariableString(szVarString,szPersoRef, lIndex, FALSE, NULL);
//			sprintf(szParameter1,"%s, %s)",
//								szVarString, C_Mind);	
			sprintf(szParameter1,"Local%s)",
								szVarString);	
			break;
		}
	default:
		g_bCasNonTraite = TRUE;
		MessageBox(NULL, "OPTIMISATION", "Cas non traite!!", MB_ICONSTOP);
		break;

	}
	if (g_bCasNonTraite)
	{
		CFast_fn_vCancelOptimization();
		return 0;
	}

	if (bSecondParameterIsInteger)
	{
		sprintf(szTempString,"MTH_M_xLongToReal(%s)",szParameter2);
		strcpy(szParameter2, szTempString);
	}

	switch (_lFuncIndex)
	{
	case 1:
		sprintf(g_p_stCurrentCFastNode->d_cOptimisedNode,"(%s)->xX = %s",szParameter1,szParameter2);	
		break;
	case 2:
		sprintf(g_p_stCurrentCFastNode->d_cOptimisedNode,"(%s)->xY = %s",szParameter1,szParameter2);	
		break;
	case 3:
		sprintf(g_p_stCurrentCFastNode->d_cOptimisedNode,"(%s)->xZ= %s",szParameter1,szParameter2);	
		break;
	}
	return 1;
}

/*
 *=================================================================================================
 *	
 *=================================================================================================
 */
char CFast_fn_cOptimizeAffect()
{
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
	long		lIndex;
	char		szParameter1[512];
	char		szVarString[2048];
	char		szPersoRef[2048];
	char			szTempString[2048];
	ACP_tdxBool		bSecondParameterIsReal = FALSE;
	ACP_tdxBool		bSecondParameterIsInteger = FALSE;
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	g_bIsAffect = TRUE;
	g_p_stCurrentCFastNode->d_cOptimisedNode = (char *)malloc(C_LengthOfOptimizedString);
	g_bIsFunction = FALSE;
	/////////////////////////////////////// 
	// second Parameter 
	///////////////////////////////////////
	g_bIsReal = FALSE;
	g_bInteger = FALSE;
	CFast_fn_vTreatParameter(g_szParameter);
	if (g_bCasNonTraite)
	{
		CFast_fn_vCancelOptimization();
		return 0;
	}
	bSecondParameterIsReal = g_bIsReal;
	bSecondParameterIsInteger = g_bInteger;
	g_bIsReal = FALSE;
	g_bInteger = FALSE;

	lIndex = g_lIndexInParamTable;
  if ( lIndex < 0) {
		CFast_fn_vCancelOptimization();
		return 0;
  }
	///////////////////////////////////////
	// first Parameter 
	///////////////////////////////////////
	g_bOperatorGetValueOfVector = FALSE;
	g_bOperatorFieldDetected = FALSE;
	switch (g_astParamTable[lIndex].eTypeNode)
	{
	case E_ti_Operator:
		{
			CFast_fn_vTreatOperator(szParameter1, szPersoRef, &lIndex, TRUE);
			break;
		}
	case E_ti_DsgVarRef:
		{
			g_astParamTable[lIndex].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation =1;// DsgVarREf
			CFast_fn_vGetVariableString(szVarString,C_CurrentPerso, lIndex, TRUE, NULL);
//			sprintf(szParameter1,"%s, %s,",
//								szVarString, C_Mind);	
			sprintf(szParameter1,"Local%s, ",
								szVarString);	
			break;
		}
	case E_ti_Field:
		{
			g_bOperatorFieldDetected = TRUE;
			CFast_fn_vTreatOperatorField
			(
				M_eFieldIdInterpret(&g_astParamTable[lIndex].p_stCFastNode->stNode),
				C_CurrentPerso,
				szParameter1,			
				TRUE,
				lIndex
			);
			break;
		}
	case E_ti_BeginMacro:
	case E_ti_EndMacro:
  case E_ti_EndTree :
			break;
	default:
			g_bCasNonTraite = TRUE;
			MessageBox(NULL, "OPTIMISATION", "Cas non traite!!", MB_ICONSTOP);
			break;
	}

	if (g_bCasNonTraite)
	{
		CFast_fn_vCancelOptimization();
		return 0;
	}
	if (g_bOperatorFieldDetected)
	{
			strcpy(g_p_stCurrentCFastNode->d_cOptimisedNode, szParameter1);
			return 1;
	}
	if (g_bOperatorGetValueOfVector)
	{
		if (bSecondParameterIsInteger)
		{
				sprintf(szTempString,"MTH_M_xLongToReal(%s)",g_szParameter);
				strcpy(g_szParameter, szTempString);
		}
		sprintf(g_p_stCurrentCFastNode->d_cOptimisedNode,"%s = %s",szParameter1,g_szParameter);	
	}
  else 
  {
		if (g_bIsReal)
		{
			if (bSecondParameterIsInteger)
			{
					sprintf(szTempString,"MTH_M_xLongToReal(%s)",g_szParameter);
					strcpy(g_szParameter, szTempString);
			}
		}
		else if (g_bInteger)
		{
			if (bSecondParameterIsReal)
			{
					sprintf(szTempString,"MTH_M_xRealToLong(%s)",g_szParameter);
					strcpy(g_szParameter, szTempString);
			}
		}
    sprintf(g_p_stCurrentCFastNode->d_cOptimisedNode,"%s%s)",szParameter1,g_szParameter);	
	}

	return 1;
}
/*
 *=================================================================================================
 *	
 *=================================================================================================
 */
void CFast_fn_vPassTwo
(
	CFast_tdstComportTree		*_p_stCFastTree,
	tdstEngineObject			*_p_stEngineObject,
	unsigned short				_uwNbNode
)
{
	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
	tdstNodeInterpret			*p_stNodeInterpret;
	enum tdeTypeInterpret_		eTypeInterpret;
	enum tdeOperatorId_		    eOperatorId;
	long						i;
	long						lIdFunc=0;
	// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
	g_lNumberOfReal = 0;
	g_lMaxNumberOfReal = 0;
	g_lNumberOfVector = 0;
	g_lMaxNumberOfVector = 0;
	/* Init */
	g_lIndexInParamTable = -1;
	g_p_stCurrentCFastNode = _p_stCFastTree -> p_stCFastNode;
	//g_hSuperObject = _hSuperObject;
	g_p_stEngine = _p_stEngineObject;

	g_bDynamReportVar = FALSE;
	g_bDynamVar = FALSE;

	for(i=0;i<(long)(_uwNbNode - 1);i++)
	{
		p_stNodeInterpret=&(g_p_stCurrentCFastNode->stNode);
		eTypeInterpret = M_GetTypeInterpret(&g_p_stCurrentCFastNode->stNode);
		g_bIsReal = FALSE;
		g_bIsAffect = FALSE;
		g_bCasNonTraite = FALSE;
    g_bPersoUseEngine = FALSE ;
		lIdFunc = 0;
		switch(eTypeInterpret)
		{
		case E_ti_Operator:
		{
				switch((eOperatorId=M_eOperatorIdInterpret(&g_p_stCurrentCFastNode->stNode)))
				{
					case eOperator_ScalarUnaryMinus:
						{
							if (g_astParamTable[g_lIndexInParamTable].eTypeNode == E_ti_Real)
							{
							  M_GetSetParam_xValue((&g_astParamTable[g_lIndexInParamTable].p_stCFastNode->stNode)) = - M_GetSetParam_xValue((&g_astParamTable[g_lIndexInParamTable].p_stCFastNode->stNode)) ;
							  g_p_stCurrentCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1 ;
							}
							else if (g_astParamTable[g_lIndexInParamTable].eTypeNode == E_ti_Constant)
							{
							  M_GetSetParam_lValue((&g_astParamTable[g_lIndexInParamTable].p_stCFastNode->stNode)) = - M_GetSetParam_lValue((&g_astParamTable[g_lIndexInParamTable].p_stCFastNode->stNode)) ;
							  g_p_stCurrentCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 1 ;
							}
							else
							{
								g_lIndexInParamTable ++;
							g_astParamTable[g_lIndexInParamTable].eTypeNode = eTypeInterpret;
							g_astParamTable[g_lIndexInParamTable].eOperatorId = eOperatorId;
								g_astParamTable[g_lIndexInParamTable].eTypeVar = E_vt_None;
								g_astParamTable[g_lIndexInParamTable].p_stCFastNode = g_p_stCurrentCFastNode;
								g_astParamTable[g_lIndexInParamTable].ucNumberOfParamNeeded	= g_p_stCurrentCFastNode -> ucNumberOfParamNeeded;
							}
						}
						break;
					case eOperator_Affect:
						{						
							g_lParameterNumber = 0;
							g_lIndexOfAffect = g_lIndexInParamTable + 1;
							g_astParamTable[g_lIndexOfAffect].p_stCFastNode = g_p_stCurrentCFastNode;
							if (CFast_fn_cOptimizeAffect())
							{
								CFast_fn_vPopParamTable(g_p_stCurrentCFastNode -> ucNumberOfParamNeeded);	
								if (g_lParameterNumber < g_p_stCurrentCFastNode -> ucNumberOfParamNeeded)
									g_p_stCurrentCFastNode -> ucNumberOfParamNeeded = (unsigned char)g_lParameterNumber;

								CFast_fn_vUpdateParameters(g_lIndexOfAffect);
							}
							g_lNumberOfVector = 0;
							break;
						}
					case eOperator_SetVectorZ:
						lIdFunc++; 
					case eOperator_SetVectorY:
						lIdFunc++; 
					case eOperator_SetVectorX:
						{
							lIdFunc++; 
							g_lParameterNumber = 0;
							g_lIndexOfAffect = g_lIndexInParamTable + 1;
							g_astParamTable[g_lIndexOfAffect].p_stCFastNode = g_p_stCurrentCFastNode;
							if (CFast_fn_cOptimizeAffectVectorValue(lIdFunc))
							{
								CFast_fn_vPopParamTable(g_p_stCurrentCFastNode -> ucNumberOfParamNeeded);	
								if (g_lParameterNumber < g_p_stCurrentCFastNode -> ucNumberOfParamNeeded)
									g_p_stCurrentCFastNode -> ucNumberOfParamNeeded = (unsigned char) g_lParameterNumber;

								CFast_fn_vUpdateParameters(g_lIndexOfAffect);
							}
							g_lNumberOfVector = 0;
							break;						
						}
					case eOperator_PlusPlusAffect:
						{				
							g_lParameterNumber = 0;
							g_lIndexOfAffect = g_lIndexInParamTable + 1;
							g_astParamTable[g_lIndexOfAffect].p_stCFastNode = g_p_stCurrentCFastNode;
							if (CFast_fn_cOptimizeAffectPlusOP(1, FALSE))
							{
								CFast_fn_vPopParamTable(g_p_stCurrentCFastNode -> ucNumberOfParamNeeded);	
								if (g_lParameterNumber < g_p_stCurrentCFastNode -> ucNumberOfParamNeeded)
									g_p_stCurrentCFastNode -> ucNumberOfParamNeeded = (unsigned char)g_lParameterNumber;

								CFast_fn_vUpdateParameters(g_lIndexOfAffect);
							}
							g_lNumberOfVector = 0;
							break;
						}
					case eOperator_MinusMinusAffect:
						{				
							g_lParameterNumber = 0;
							g_lIndexOfAffect = g_lIndexInParamTable + 1;
							g_astParamTable[g_lIndexOfAffect].p_stCFastNode = g_p_stCurrentCFastNode;
							if (CFast_fn_cOptimizeAffectPlusOP(2, FALSE))
							{
								CFast_fn_vPopParamTable(g_p_stCurrentCFastNode -> ucNumberOfParamNeeded);	
								if (g_lParameterNumber < g_p_stCurrentCFastNode -> ucNumberOfParamNeeded)
									g_p_stCurrentCFastNode -> ucNumberOfParamNeeded = (unsigned char)g_lParameterNumber;

								CFast_fn_vUpdateParameters(g_lIndexOfAffect);
							}
							g_lNumberOfVector = 0;
							break;
						}
					case eOperator_PlusAffect:
						{				
							g_lParameterNumber = 0;
							g_lIndexOfAffect = g_lIndexInParamTable + 1;
							g_astParamTable[g_lIndexOfAffect].p_stCFastNode = g_p_stCurrentCFastNode;
							if (CFast_fn_cOptimizeAffectPlusOP(1, TRUE))
							{
								CFast_fn_vPopParamTable(g_p_stCurrentCFastNode -> ucNumberOfParamNeeded);	
								if (g_lParameterNumber < g_p_stCurrentCFastNode -> ucNumberOfParamNeeded)
									g_p_stCurrentCFastNode -> ucNumberOfParamNeeded = (unsigned char)g_lParameterNumber;
		
								CFast_fn_vUpdateParameters(g_lIndexOfAffect);

							}
							g_lNumberOfVector = 0;
							break;
						}
					case eOperator_MinusAffect:
						{				
							g_lParameterNumber = 0;
							g_lIndexOfAffect = g_lIndexInParamTable + 1;
							g_astParamTable[g_lIndexOfAffect].p_stCFastNode = g_p_stCurrentCFastNode;
							if (CFast_fn_cOptimizeAffectPlusOP(2, TRUE))
							{
								CFast_fn_vPopParamTable(g_p_stCurrentCFastNode -> ucNumberOfParamNeeded);	
								if (g_lParameterNumber < g_p_stCurrentCFastNode -> ucNumberOfParamNeeded)
									g_p_stCurrentCFastNode -> ucNumberOfParamNeeded = (unsigned char)g_lParameterNumber;

								CFast_fn_vUpdateParameters(g_lIndexOfAffect);
							}
							g_lNumberOfVector = 0;
							break;
						}
					case eOperator_MulAffect:
						{				
							g_lParameterNumber = 0;
							g_lIndexOfAffect = g_lIndexInParamTable + 1;
							g_astParamTable[g_lIndexOfAffect].p_stCFastNode = g_p_stCurrentCFastNode;
							if (CFast_fn_cOptimizeAffectPlusOP(3, TRUE))
							{
								CFast_fn_vPopParamTable(g_p_stCurrentCFastNode -> ucNumberOfParamNeeded);	
								if (g_lParameterNumber < g_p_stCurrentCFastNode -> ucNumberOfParamNeeded)
									g_p_stCurrentCFastNode -> ucNumberOfParamNeeded = (unsigned char)g_lParameterNumber;

								CFast_fn_vUpdateParameters(g_lIndexOfAffect);
							}
							g_lNumberOfVector = 0;
							break;
						}
					case eOperator_DivAffect:
						{				
							g_lParameterNumber = 0;
							g_lIndexOfAffect = g_lIndexInParamTable + 1;
							g_astParamTable[g_lIndexOfAffect].p_stCFastNode = g_p_stCurrentCFastNode;
							if (CFast_fn_cOptimizeAffectPlusOP(4, TRUE))
							{
								CFast_fn_vPopParamTable(g_p_stCurrentCFastNode -> ucNumberOfParamNeeded);	
								if (g_lParameterNumber < g_p_stCurrentCFastNode -> ucNumberOfParamNeeded)
									g_p_stCurrentCFastNode -> ucNumberOfParamNeeded = (unsigned char)g_lParameterNumber;

								CFast_fn_vUpdateParameters(g_lIndexOfAffect);
							}
							g_lNumberOfVector = 0;
							break;
						}
					default:
						{
							g_lParameterNumber = 0;
							g_lNumberOfVector = 0;
							g_lIndexInParamTable ++;
							g_astParamTable[g_lIndexInParamTable].eTypeNode = eTypeInterpret;
							g_astParamTable[g_lIndexInParamTable].eOperatorId = eOperatorId;
							g_astParamTable[g_lIndexInParamTable].p_stCFastNode = g_p_stCurrentCFastNode;
							g_astParamTable[g_lIndexInParamTable].ucNumberOfParamNeeded	= 255;
						}
						break;
				}//switch((eOperatorId=M_eOperatorIdInterpret(&g_p_stCurrentCFastNode->stNode)))
				break;
		}
		case E_ti_KeyWord:
			{
				enum tdeKeyWordId_ eKeyWord;
				switch((eKeyWord=M_eKeyWordIdInterpret(&g_p_stCurrentCFastNode->stNode)))
				{
				case eKeyWord_If:
				case eKeyWord_IfNot:
				case eKeyWord_If2:
				case eKeyWord_If4:
				case eKeyWord_If8:
				case eKeyWord_If16:
				case eKeyWord_Then:
				case eKeyWord_Else:
					{
						if (g_p_stCurrentCFastNode -> ucNumberOfParamNeeded != 0)
						{
							CFast_fn_vPopParamTable(g_p_stCurrentCFastNode -> ucNumberOfParamNeeded);
						}
						break;
					}
				case eKeyWord_Me:
				case eKeyWord_MainActor:
				case eKeyWord_Nobody:
				//case eKeyWord_World:
				case eKeyWord_Nowhere:
				case eKeyWord_CapsNull:
				case eKeyWord_NoGraph:
				case eKeyWord_Vector:
				case eKeyWord_True:
				case eKeyWord_False:
        case eKeyWord_NoAction:
					{
						g_lIndexInParamTable ++;
						g_astParamTable[g_lIndexInParamTable].eTypeNode = eTypeInterpret;
						g_astParamTable[g_lIndexInParamTable].p_stCFastNode = g_p_stCurrentCFastNode;
						g_astParamTable[g_lIndexInParamTable].ucNumberOfParamNeeded	= 255;
						break;
					}
				default:
					//MessageBox(NULL, "OPTIMISATION", "KeyWord non traite!!", MB_ICONSTOP);
					break;
				}//switch((eOperatorId=M_eOperatorIdInterpret(&g_p_stCurrentCFastNode->stNode)))
				break;
			}
		case E_ti_Function:
			{
				if (g_p_stCurrentCFastNode -> ucNumberOfParamNeeded != 0)
				{
					CFast_fn_vPopParamTable(g_p_stCurrentCFastNode -> ucNumberOfParamNeeded);
				}			
				g_lIndexInParamTable ++;
				g_astParamTable[g_lIndexInParamTable].eTypeNode = eTypeInterpret;
				g_astParamTable[g_lIndexInParamTable].eTypeVar = CFast_fn_eGetFunctionTypeOutParam(g_p_stCurrentCFastNode, M_eFuncIdInterpret(&g_p_stCurrentCFastNode->stNode));
				g_astParamTable[g_lIndexInParamTable].ucIndexOfEvalParam = g_p_stCurrentCFastNode->ucIndexOfEvalParam;
				g_astParamTable[g_lIndexInParamTable].p_stCFastNode = g_p_stCurrentCFastNode;
				g_astParamTable[g_lIndexInParamTable].ucNumberOfParamNeeded	= 255;
				break;
			}
		case E_ti_Procedure:
		case E_ti_MetaAction:
			{
				if (g_p_stCurrentCFastNode -> ucNumberOfParamNeeded != 0)
				{
					CFast_fn_vPopParamTable(g_p_stCurrentCFastNode -> ucNumberOfParamNeeded);
				}
				break;
			}
		case E_ti_Condition:
			{
				if (g_p_stCurrentCFastNode -> ucNumberOfParamNeeded != 0)
				{
					CFast_fn_vPopParamTable(g_p_stCurrentCFastNode -> ucNumberOfParamNeeded);
				}
				g_lIndexInParamTable ++;
				g_astParamTable[g_lIndexInParamTable].eTypeNode = eTypeInterpret;
				g_astParamTable[g_lIndexInParamTable].eTypeVar = E_vt_Integer;
				g_astParamTable[g_lIndexInParamTable].ucIndexOfEvalParam = g_p_stCurrentCFastNode->ucIndexOfEvalParam;
				g_astParamTable[g_lIndexInParamTable].p_stCFastNode = g_p_stCurrentCFastNode;
				g_astParamTable[g_lIndexInParamTable].ucNumberOfParamNeeded	= 255;
				break;
			}
		default:
			{
				g_lIndexInParamTable ++;
				g_astParamTable[g_lIndexInParamTable].eTypeNode = eTypeInterpret;
				g_astParamTable[g_lIndexInParamTable].eTypeVar = E_vt_None;
				g_astParamTable[g_lIndexInParamTable].p_stCFastNode = g_p_stCurrentCFastNode;
				g_astParamTable[g_lIndexInParamTable].ucNumberOfParamNeeded	= 255;
				break;
			}
		}//switch(eTypeInterpret)
		if (g_lIndexInParamTable >= 128)
			MessageBox(NULL, "OPTIMISATION", "Ah pas bon du tout!!", MB_ICONSTOP);
		g_p_stCurrentCFastNode ++;
	}// for

	// Management of variables declaration
	CFast_fn_vVariablesDeclaration(_p_stCFastTree);

	
}


bool CFast_fn_bIsAModelCastVar ( long lIndex ) {
  if ( g_astParamTable[lIndex-1].eTypeNode == E_ti_Operator &&
       g_astParamTable[lIndex-1].eOperatorId == eOperator_ModelCast )
       return TRUE ;
  return FALSE ;
}

extern struct AI_tdstMind_ *gp_stCurrentMind;
AI_tdstAIModel *CFast_fn_p_stGetModelReference (long lIndex) {
  AI_tdstAIModel            *p_stAIModel ;
  tdstNodeInterpret         *p_stIntNode ;
  struct tdstNodeInterpret_ *p_stRefTree = gp_stCurrentMind->p_stAIModel->CFast_dst_RefTreeArray;

  p_stIntNode = p_stRefTree + g_astParamTable[lIndex].p_stCFastNode->lIndexOfRef ;

  p_stAIModel = M_p_stModelInterpret(p_stIntNode) ;
  return (p_stAIModel) ;
}

/*
 * CFast_fn_bTraitModelCast :
 * index     : dsgvar/persodot
 * index - 1 : modelcast
 * index - 2 : dsgvar
 * index - 3 : modelref
 */

bool CFast_fn_bTreatModelCast ( long *_p_lIndex, char *_p_szString, char *_p_szStringPerso, 
                                ACP_tdxBool _bSetFunction) {
  tdstTypeOfParam  *p_stDsgVarPerso ;
  tdstTypeOfParam  *p_stModelCast ;
  tdstTypeOfParam  *p_stDsgVar ;
  tdstTypeOfParam  *p_stModelRef ;
  long             lIndex = (*_p_lIndex) ;
  AI_tdstAIModel	 *p_stAIModel=NULL;
  char             szFuncName[2048];
  char             szCast[128] ;
  tdeDsgVarTypeId  eDsgVarType ;
  struct tdstNodeInterpret_ *p_stRefTree = gp_stCurrentMind->p_stAIModel->CFast_dst_RefTreeArray;
  long             lIsPersoRef=0 ;
    

  p_stDsgVar      = &g_astParamTable[lIndex] ;
  p_stModelCast   = &g_astParamTable[lIndex-1] ;
  p_stDsgVarPerso = &g_astParamTable[lIndex-2] ;
  p_stModelRef    = &g_astParamTable[lIndex-3] ;

  if ( p_stDsgVarPerso->eTypeNode != E_ti_DsgVarRef ||
       p_stModelCast->eTypeNode   != E_ti_Operator  ||
       p_stDsgVar->eTypeNode      != E_ti_DsgVarRef ||
       p_stModelRef->eTypeNode    != E_ti_ModelRef )
    return (FALSE) ;

  if (p_stDsgVarPerso->p_stCFastNode->lIndexOfRef > -1 )
    sprintf ( _p_szStringPerso, "(HIE_tdxHandleToSuperObject *)M_GetDsgVarAddr(p_stLocalMind0, M_CFast_ucGetRealIndice(%d))", 
              p_stDsgVarPerso->p_stCFastNode->lIndexOfRef);
  else
    sprintf ( _p_szStringPerso, "(HIE_tdxHandleToSuperObject *)M_GetDsgVarAddr(p_stLocalMind0, %d)", 
              M_lDsgVarIdInterpret(&p_stDsgVarPerso->p_stCFastNode->stNode));

	p_stAIModel = CFast_fn_p_stGetModelReference(lIndex-3) ;
	if ( p_stDsgVar->p_stCFastNode->lIndexOfRef > -1 ) {
	  eDsgVarType = p_stAIModel->p_stDsgVar->p_stDsgVarInfo[M_CFast_ucGetRealIndice(p_stDsgVar->p_stCFastNode->lIndexOfRef)].eDsgVarTypeId ;    
	}
	else {
	  eDsgVarType = p_stAIModel->p_stDsgVar->p_stDsgVarInfo[M_lDsgVarIdInterpret(&p_stDsgVar->p_stCFastNode->stNode)].eDsgVarTypeId ;
	}
  switch(eDsgVarType){
  case eDsgVarType_Perso :
    strcpy ( szCast, "(HIE_tdxHandleToSuperObject)" ) ;
    lIsPersoRef = 1 ;
    break ;
  case eDsgVarType_Float:
    strcpy ( szCast, "(MTH_tdxReal *)" ) ;
    break ;
  case eDsgVarType_Vector:
    strcpy ( szCast, "(MTH3D_tdstVector *)" ) ;
    break ;
  case eDsgVarType_Boolean:			
  case eDsgVarType__128To127:
  case eDsgVarType_0To255:
    strcpy ( szCast, "(char *)" ) ;
    break ;
  case eDsgVarType__32768To32767:
  case eDsgVarType_0To65535:	
    strcpy ( szCast, "(short *)" ) ;
    break ;
  case eDsgVarType_Integer:
  case eDsgVarType_PositiveInteger:	
    strcpy ( szCast, "(long *)" ) ;
    break ;
  default :
//    ::MessageBox ( NULL, "bad dsgvar type, cast in (long *) !! ", "modelcast", MB_ICONSTOP ) ;
    strcpy ( szCast, "(long *)" ) ;
    break ;
  }
  if ( _bSetFunction ) {
  //CFast_fn_vGetVariableString(szFuncName,_p_szStringPerso, lIndex, _bSetFunction, p_stAIModel );
	//strcat(szFuncName, ",");
   
/*
    CFast_fn_vSelectSetVar( CFast_fn_eGetDsgVarRefType ( &g_astParamTable[lIndex].p_stCFastNode->stNode,
											                                   p_stAIModel,
											                                   (unsigned char)M_lDsgVarIdInterpret(&g_astParamTable[lIndex].p_stCFastNode->stNode)), 
                            szFuncName );
*/
    CFast_fn_vSelectSetVar( fn_GetDsgVarType(eDsgVarType), szFuncName );


    if ( lIsPersoRef && (g_bIsFunction || g_bPersoUseEngine) ){
      if ( !strstr ( szFuncName, "WithEngine" ) ) 
        strcat ( szFuncName, "WithEngine" ) ;
    }
    if ( p_stDsgVar->p_stCFastNode->lIndexOfRef < 0 ) {
      sprintf ( _p_szString, "%s ( %d, (M_GetMSHandle( (*(%s)), Brain)->p_stMind), ", szFuncName, 
                M_lDsgVarIdInterpret(&p_stDsgVar->p_stCFastNode->stNode), 
                _p_szStringPerso );
    }
    else {
      sprintf ( _p_szString, "%s ( M_CFast_ucGetRealIndice(%d), (M_GetMSHandle( (*(%s)), Brain)->p_stMind), ", szFuncName, 
                p_stDsgVar->p_stCFastNode->lIndexOfRef, 
                _p_szStringPerso );
    }
  }
  else if ( eDsgVarType == eDsgVarType_Vector) {
 	  sprintf( _p_szString,"(%s(M_GetDsgVarAddr((M_GetMSHandle( (*(%s)), Brain))->p_stMind, %d)))",
             szCast,
				  	 _p_szStringPerso, 
             M_lValueInterpret(&p_stDsgVar->p_stCFastNode->stNode));

  }
  else if ( lIsPersoRef ) {
 	  sprintf( _p_szString,"(%s(M_GetDsgVarAddr((M_GetMSHandle( (*(%s)), Brain))->p_stMind, %d)))",
             szCast,
				  	 _p_szStringPerso, 
             M_lValueInterpret(&p_stDsgVar->p_stCFastNode->stNode));

  }
  else {
 	  sprintf( _p_szString,"(*(%s(M_GetDsgVarAddr((M_GetMSHandle( (*(%s)), Brain))->p_stMind, %d))) )",
             szCast,
				  	 _p_szStringPerso, 
             M_lValueInterpret(&p_stDsgVar->p_stCFastNode->stNode));
  }
	g_astParamTable[lIndex-3].p_stCFastNode->ucNumberOfNodeToSkipAfterOptimisation = 5;	
  g_lIndexInParamTable -= 2;
	(*_p_lIndex)-=3;
  return (TRUE) ;
}