#if defined(_AI_LIB_)
	#include "AIUseCPA.h"
	
	#include "specif/AIOption.h"
	#include "AIMacros.h"	
	#include "AI_Erm.h"
	
	#include "Convert.h"
	#include "EnumProc.h"
 
	#if defined(OPTIMIZED_COMMAND) 
		#include "ProtProc.h"
	#endif
#else
	#include <string.h>
	#include "specif/AIOption.h"
	
	#include "ConvCst.h"
	#include "EnumProc.h"
	#include "ConvProc.h"
#endif /* _AI_LIB_*/
 
#define C_MAX_SIZE_PROCEDURE_EDITOR_NAME 50
#define C_MAX_SIZE_PROCEDURE_SCRIPT_NAME 40
 
#define C_MAX_PROCEDURE_NB_PARAM 8/*Ylt passage de 6 à 8 arguments*/
 
 
typedef struct tdstProcedureEntry_
{
#if defined(ACTIVE_EDITOR)
    /* Procedure string used in editor*/
    char szProcedureEditorName[C_MAX_SIZE_PROCEDURE_EDITOR_NAME+1]; 
    char szProcedureEditorName_En[C_MAX_SIZE_PROCEDURE_EDITOR_NAME+1]; 
#endif /* ACTIVE_EDITOR*/
#if defined (AI_USE_SCRIPT)
    /* Procedure string used in script*/
    char szProcedureScriptName[C_MAX_SIZE_PROCEDURE_SCRIPT_NAME+1];
#endif /* AI_USE_SCRIPT */
#if defined(_AI_LIB_)
    /* pointer on Procedure function*/
    tdp_fn_p_stProcedureFunctionPtr p_fn_p_stProcedureFunction;
#endif
#if defined (AI_USE_SCRIPT) || defined (U64_AIDEBUG)
	/* list of Procedure parameters (taken from szAutorizedTypeParam) in parameter*/
	char szProcedureTypeParam[C_MAX_PROCEDURE_NB_PARAM+1];
#endif /* AI_USE_SCRIPT */
	unsigned char bUltraProcedureFlag;
 
#ifdef PROFILE_IA
	unsigned long ulCallCtr;
	unsigned long ulTimeCtr;
	unsigned long ulOwnTimeCtr;
#endif /* PROFILE_IA*/
} tdstProcedureEntry;
 
 
#ifdef PROFILE_IA
extern unsigned long ulIndice;
extern unsigned long p_ulTime[255];
extern FILE *file;
#endif /* PROFILE_IA*/
 
 
tdstProcedureEntry a_stProcedureTable[eNbProcedure]
#if defined(OPTIMIZED_COMMAND)
=
{
#ifdef U64_AIDEBUG
	/* function pointers in Procedure.c, in params,ultra-able*/
	#define M_DEFINE_PROCEDURE(a,b,english,c,d,e,f) { d,e,f },
	#include "DefProc.h" 
}
#else /* U64_AIDEBUG*/
#if defined (AI_USE_SCRIPT)
/* Procedure initialisation*/
#if defined(_AI_LIB_)
	#if defined(ACTIVE_EDITOR)
		#define M_DEFINE_PROCEDURE(a,b,english,c,d,e,f) { b,english,c,d,e,f },
	#else
		#define M_DEFINE_PROCEDURE(a,b,english,c,d,e,f) { c,d,e,f },
	#endif /* ACTIVE_EDITOR*/
#else
	#if defined(ACTIVE_EDITOR)
		#define M_DEFINE_PROCEDURE(a,b,english,c,d,e,f) { b,english,c,e,f },
	#else
		#define M_DEFINE_PROCEDURE(a,b,english,c,d,e,f) { c,e,f },
	#endif /* ACTIVE_EDITOR*/
#endif /* _AI_LIB_*/
    #include "DefProc.h" 
	#undef M_DEFINE_PROCEDURE
}
#else /* AI_USE_SCRIPT */
/* Procedure initialisation*/
#if defined(_AI_LIB_)
	#if defined(ACTIVE_EDITOR)
		#define M_DEFINE_PROCEDURE(a,b,english,c,d,e,f) { b,english,d,f },
	#else
		#define M_DEFINE_PROCEDURE(a,b,english,c,d,e,f) { d,f },
	#endif /* ACTIVE_EDITOR*/
#else
	#if defined(ACTIVE_EDITOR)
		#define M_DEFINE_PROCEDURE(a,b,english,c,d,e,f) { b,english,f },
	#else
		#define M_DEFINE_PROCEDURE(a,b,english,c,d,e,f) { f },
	#endif /* ACTIVE_EDITOR*/
#endif /* _AI_LIB_*/
    #include "DefProc.h" 
	#undef M_DEFINE_PROCEDURE
}
#endif /* AI_USE_SCRIPT */
#endif /* U64_AIDEBUG*/
#endif /* OPTIMIZED_COMMAND*/
;
 
#if ! defined(OPTIMIZED_COMMAND)
void fn_vSetProcedureUltraOperator(enum tdeProcedureId_ eProcId,unsigned char bFlag)
{
  a_stProcedureTable[eProcId].bUltraProcedureFlag=bFlag;
};
#endif /* OPTIMIZED_COMMAND*/
 
unsigned char fn_ucGetProcedureUltraOperator(enum tdeProcedureId_ eProcId)
{
  return(a_stProcedureTable[eProcId].bUltraProcedureFlag);
}
 
#if defined(_AI_LIB_)
tdp_fn_p_stProcedureFunctionPtr fn_p_fn_pGetProcedureFunctionPtr(enum tdeProcedureId_ eProcedureId)
{
  return(a_stProcedureTable[eProcedureId].p_fn_p_stProcedureFunction);
}
 
 
#ifdef PROFILE_IA
 
void fn_vProcSaveTime(unsigned long ulTime, enum tdeProcedureId_ eProcedureId)
{
	/* if level != 0, then stop time count of last function*/
	if (ulIndice != 0)
	{
		p_ulTime[ulIndice - 1] = (ulTime - p_ulTime[ulIndice - 1]);
	}
	/* set time for this new function and add indice*/
	p_ulTime[ulIndice++] = ulTime;
}
 
 
void fn_vProcComputeTime(unsigned long ulCurrentTime, unsigned long ulTime, enum tdeProcedureId_ eProcedureId)
{
	/* compute total time for this function*/
	a_stProcedureTable[eProcedureId].ulCallCtr++;
	a_stProcedureTable[eProcedureId].ulTimeCtr += (ulCurrentTime - ulTime)/5;
	/* compute own time for this function*/
	ulIndice--;
	/* compute the time for this function*/
	a_stProcedureTable[eProcedureId].ulOwnTimeCtr += ((ulCurrentTime  - p_ulTime[ulIndice]) / 5);
	p_ulTime[ulIndice] = 0;
	if (ulIndice != 0)
	{
		/* level != 0, then restart previous function time*/
		p_ulTime[ulIndice-1] = ulCurrentTime - p_ulTime[ulIndice-1];
	}
}
 
 
 
void dumpProc()
{
	int i;
	char string[250];
	
	strcpy(string,"x:\\cpa\\");
	strcat(string,fn_p_szGetLevelName());
	strcat(string,".txt");
 
	file = fopen(string,"a+");
	if (file == NULL)
		return;
 
	for (i=0;i<(long)eNbProcedure;i++)
	{
		if (a_stProcedureTable[i].ulCallCtr)
		{
			fprintf(file,"%s	%i	%i	%i	%i	%i\n",
				a_stProcedureTable[i].szProcedureScriptName,
				a_stProcedureTable[i].ulCallCtr,
				a_stProcedureTable[i].ulTimeCtr,
				a_stProcedureTable[i].ulOwnTimeCtr,
				a_stProcedureTable[i].ulTimeCtr / a_stProcedureTable[i].ulCallCtr,
				a_stProcedureTable[i].ulOwnTimeCtr / a_stProcedureTable[i].ulCallCtr);
		}
		else
		{
			fprintf(file,"%s	%i	%i	%i	%i	%i\n",
				a_stProcedureTable[i].szProcedureScriptName,
				0,
				0,
				0,
				0,
				0);
		}
 
	}
	fclose(file);
}
 
 
void clearProc()
{
	int i;
	for (i=0;i<(long)eNbProcedure;i++)
	{
		a_stProcedureTable[i].ulCallCtr = 0;
		a_stProcedureTable[i].ulTimeCtr = 0;
		a_stProcedureTable[i].ulOwnTimeCtr = 0;
	}
}
#endif /* PROFILE_IA*/
 
#endif /* _AI_LIB_*/
 
 
#ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */
enum tdeProcedureId_ fn_eGetNbProcedure()
{
  return(eNbProcedure);
}
#endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */
 
 
#if defined(__DEBUG_AI__) || defined(ACTIVE_EDITOR) || defined(U64_AIDEBUG)
char *szGetProcedureTypeInParamFromId(enum tdeProcedureId_ eProcedureId)
{
    return(a_stProcedureTable[eProcedureId].szProcedureTypeParam);
}
#endif /* __DEBUG_AI__ ACTIVE_EDITOR*/
 
#if defined(ACTIVE_EDITOR)
char *szGetProcedureTypeOutParamFromId(enum tdeProcedureId_ eProcedureId)
{
    eProcedureId=eProcedureId;
    return(USE_NO_PARAM);
}
 
enum tdeProcedureId_ fn_eFindProcedureIdFromEditorName(char *szProcedure)
{
    short wProcedureEntry;
    for(wProcedureEntry=0;wProcedureEntry<fn_eGetNbProcedure();wProcedureEntry++)
    {
        if (!stricmp(a_stProcedureTable[wProcedureEntry].szProcedureEditorName,szProcedure))
        {
			return((enum tdeProcedureId_) wProcedureEntry);
        }
    }
    return(fn_eGetNbProcedure());
}
 
char *szFindProcedureEditorNameFromId(enum tdeProcedureId_ eProcedureId)
{
    return(a_stProcedureTable[eProcedureId].szProcedureEditorName);
}
#endif /* ACTIVE_EDITOR*/
 
#if defined (AI_USE_SCRIPT)
char *szFindProcedureScriptNameFromId(enum tdeProcedureId_ eProcedureId)
{
    return(a_stProcedureTable[eProcedureId].szProcedureScriptName);
}
#endif /* AI_USE_SCRIPT */
 
#if defined (AI_USE_SCRIPT)
enum tdeProcedureId_ fn_eFindProcedureIdFromScriptName(char *szProcedure)
{
    short wProcedureEntry;
    for(wProcedureEntry=0;wProcedureEntry<fn_eGetNbProcedure();wProcedureEntry++)
    {
        if (!stricmp(a_stProcedureTable[wProcedureEntry].szProcedureScriptName,szProcedure))
        {
			return((enum tdeProcedureId_) wProcedureEntry);
        }
    }
    return(fn_eGetNbProcedure());
}
#endif /* AI_USE_SCRIPT */
 
#if !defined(OPTIMIZED_COMMAND)
#if defined(ACTIVE_EDITOR)
void fn_vDefineProcedureEntry(enum tdeProcedureId_ eProcedureId,char *szProcedureEditorName,char *szProcedureEditorName_En,char *szProcedureScriptName,tdp_fn_p_stProcedureFunctionPtr p_fn_p_stProcedureFunction,char *szProcedureTypeParam)				
#else
void fn_vDefineProcedureEntry(enum tdeProcedureId_ eProcedureId,char *szProcedureScriptName,tdp_fn_p_stProcedureFunctionPtr p_fn_p_stProcedureFunction,char *szProcedureTypeParam)				
#endif /* ACTIVE_EDITOR*/
{
    if (
        (eProcedureId<fn_eGetNbProcedure())
#if defined(ACTIVE_EDITOR)
        &&(strlen(szProcedureEditorName)<=C_MAX_SIZE_PROCEDURE_EDITOR_NAME)
#endif /* ACTIVE_EDITOR*/
        &&(strlen(szProcedureScriptName)<=C_MAX_SIZE_PROCEDURE_SCRIPT_NAME)
        &&(strlen(szProcedureTypeParam)<=C_MAX_PROCEDURE_NB_PARAM)
        &&(fn_ucCheckTypeParam(szProcedureTypeParam))
        )
    {
#if defined(ACTIVE_EDITOR)
        strcpy(a_stProcedureTable[eProcedureId].szProcedureEditorName,szProcedureEditorName);
#endif /* ACTIVE_EDITOR*/
        strcpy(a_stProcedureTable[eProcedureId].szProcedureScriptName,szProcedureScriptName);
        a_stProcedureTable[eProcedureId].p_fn_p_stProcedureFunction=p_fn_p_stProcedureFunction;
        strcpy(a_stProcedureTable[eProcedureId].szProcedureTypeParam,szProcedureTypeParam);
    }
    else
    {
       char str[C_MAX_LENGTH_STRING];
  	   sprintf(str,"Error while defining %s procedure in %s\n",szProcedureScriptName,__FILE__);
       M_AIFatalErrorMsg(E_uwAIFatalNotValidProcedure,str);
    }
}
#endif /* OPTIMIZED_COMMAND*/
 
#if !defined(OPTIMIZED_COMMAND)
#if defined(__DEBUG_AI__)
void fn_vInitProcedureTable(tdp_fn_p_stProcedureFunctionPtr fn_p_stDefaultProcedureFunctionPointer)
{
  short wProcedureEntry;
  for(wProcedureEntry=0;wProcedureEntry<fn_eGetNbProcedure();wProcedureEntry++)
  {
	fn_vDefineProcedureEntry(M_PROCEDURE_ENTRY((enum tdeProcedureId_) wProcedureEntry,"","","",fn_p_stDefaultProcedureFunctionPointer,USE_NO_PARAM));
	/* ULTRA OPERATOR USAGE : FALSE AS A DEFAULT*/
    fn_vSetProcedureUltraOperator((enum tdeProcedureId_) wProcedureEntry,NOT_ULTRA_ABLE);
  }
}
 
void fn_vCheckProcedureTable(tdp_fn_p_stProcedureFunctionPtr fn_p_stDefaultProcedureFunctionPointer)
{
  short wProcedureEntry;
  char str[C_MAX_LENGTH_STRING];
  size_t lLen;
  size_t lMaxLengthScriptName=0;
#if defined(ACTIVE_EDITOR)
  size_t lMaxLengthEditorName=0;
#endif /* ACTIVE_EDITOR*/
  size_t lMaxLengthParam=0;
  for(wProcedureEntry=0;wProcedureEntry<fn_eGetNbProcedure();wProcedureEntry++)
  {
     if (fn_p_fn_pGetProcedureFunctionPtr((enum tdeProcedureId_) wProcedureEntry)==fn_p_stDefaultProcedureFunctionPointer)
	 {
  	   sprintf(str,"Error while defining %s procedure in %s\n",a_stProcedureTable[wProcedureEntry].szProcedureScriptName,__FILE__);
	   M_AIFatalErrorMsg(E_uwAIFatalNotValidProcedure,str);
	 }
	 if ((lLen=strlen(a_stProcedureTable[wProcedureEntry].szProcedureScriptName))>lMaxLengthScriptName)
	 {
	   lMaxLengthScriptName=lLen;
	 }
#if defined(ACTIVE_EDITOR)
	 if ((lLen=strlen(a_stProcedureTable[wProcedureEntry].szProcedureEditorName))>lMaxLengthEditorName)
	 {
	   lMaxLengthEditorName=lLen;
	 }
#endif /* ACTIVE_EDITOR*/
	 if ((lLen=strlen(a_stProcedureTable[wProcedureEntry].szProcedureTypeParam))>lMaxLengthParam)
	 {
        lMaxLengthParam=lLen;
	 }
  }	
#if !defined(U64)
  {
	if (lMaxLengthScriptName<C_MAX_SIZE_PROCEDURE_SCRIPT_NAME)
	{
		sprintf(str,"*** AI : You should reduce C_MAX_SIZE_PROCEDURE_SCRIPT_NAME in %s to %d\n",__FILE__,lMaxLengthScriptName);
		OutputDebugString(str);
	}
#if defined(ACTIVE_EDITOR)
	if (lMaxLengthEditorName<C_MAX_SIZE_PROCEDURE_EDITOR_NAME)
	{
		sprintf(str,"*** AI : You should reduce C_MAX_SIZE_PROCEDURE_EDITOR_NAME in %s to %d\n",__FILE__,lMaxLengthEditorName);
		OutputDebugString(str);
	}
#endif /* ACTIVE_EDITOR*/
	if (lMaxLengthParam<C_MAX_PROCEDURE_NB_PARAM)
	{
		sprintf(str,"*** AI : You should reduce C_MAX_PROCEDURE_NB_PARAM in %s to %d\n",__FILE__,lMaxLengthParam);
		OutputDebugString(str);
	}
  }
#endif /* U64*/
}
#endif /* __DEBUG_AI__*/
 
#endif /* OPTIMIZED_COMMAND*/
 
