/*---------------------------------------------------------------------------*/
/* KeyWord.c : Definition of general keyword.*/
/* auteur : Olivier Couvreur.*/
/* date   : 19/08/1997*/
/*---------------------------------------------------------------------------*/
 
#ifdef _DEBUG
extern "C" char gcGlobAleat;
#else
extern char gcGlobAleat;
#endif
 
#include "AIUseCPA.h"
 
#include "specif/AIOption.h"
#include "AIMacros.h" 
#include "AI_Erm.h"
 
#include "AI_Struc.h"
#include "StrIntel.h"
#include "Intell.h"
#include "EnumKey.h"
#include "ActConst.h"
 
#if defined(ACTIVE_AIDEBUG)
#include "specif/AID_Trac.h"
#include "AID_Erm.h"
#endif
 
 
/************************************************************************************/
/* HERE IS THE BEGINNING                                                            /
/************************************************************************************/
 
#if !defined(OPTIMIZED_COMMAND)
#if defined(__DEBUG_AI__)
tdstNodeInterpret *fn_p_stDefaultKeyWord(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
  p_SuperObjPerso=p_SuperObjPerso;
  p_stValue=p_stValue;
#if defined(__DEBUG_AI__)
  M_AIFatalError(E_uwAIFatalUnknownKeyWord);
#endif
  return(p_stTree);
}
#endif /* _DEBUG_AI__*/
#endif /* OPTIMIZED_COMMAND*/
 
#if defined(ACTIVE_EDITOR)
tdstNodeInterpret *fn_p_stMiscKeyWord(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
  p_SuperObjPerso=p_SuperObjPerso;
  p_stValue=p_stValue;
  p_stTree=p_stTree;
#if defined(__DEBUG_AI__)
  M_AIFatalError(E_uwAIFatalUnknownKeyWord);
#endif /* DEBUG_AI*/
  return(p_stTree);
}
#endif /* ACTIVE_EDITOR*/


tdstNodeInterpret *fn_p_stNoActionKeyWord(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
  M_Full_GetSetParam_Action(p_stValue, NULL);
  return(p_stTree);
}
 
tdstNodeInterpret *fn_p_stMeKeyWord(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
  M_GetSetParam_p_stEngineObjValue(p_stValue) = M_GetEngineObject(p_SuperObjPerso);
  M_GetSetParam_Type(p_stValue) = E_vt_Perso;
  return(p_stTree);
}
 
tdstNodeInterpret *fn_p_stMainActorKeyWord(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
  M_GetSetParam_p_stEngineObjValue(p_stValue) = M_GetEngineObject(MC_fn_hGetCharacterInMainCharacterNode(MC_fn_hGetFirstMainCharNode()));
  M_GetSetParam_Type(p_stValue) = E_vt_Perso;
  return(p_stTree);
}
 
/*tdstNodeInterpret *fn_p_stWorldKeyWord(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
  M_GetSetParam_p_stEngineObjValue(p_stValue) = M_GetEngineObject(g_stEngineStructure.h_WorldCaracter);
  M_GetSetParam_Type(p_stValue) = E_vt_Perso;
  return(p_stTree);
}*/

/* ANNECY OA - 13/08/99 { */
#ifndef U64
tdstNodeInterpret *fn_p_stNoSuperObjectKeyWord(HIE_tdxHandleToSuperObject p_SuperObj, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
  M_GetSetParam_p_stEngineObjValue(p_stValue) = NULL;
  M_GetSetParam_Type(p_stValue) = E_vt_SuperObject;
  return(p_stTree);
}
#endif
/* END ANNECY OA } */
 
tdstNodeInterpret *fn_p_stNobodyKeyWord(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
  M_GetSetParam_p_stEngineObjValue(p_stValue) = NULL;
  M_GetSetParam_Type(p_stValue) = E_vt_Perso;
  return(p_stTree);
}
 
tdstNodeInterpret *fn_p_stNowhereKeyWord(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
  M_Full_GetSetParam_WayPoint(p_stValue,WP_C_hWayPointInvalid);
  return(p_stTree);
}
 
tdstNodeInterpret *fn_p_stEmptyTextKeyWord(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
  M_Full_GetSetParam_hText(p_stValue, FON_C_xInvalidTextHandle);
  return(p_stTree);
}
 
/*ANNECY Bart 06/02/98 {*/
tdstNodeInterpret *fn_p_stCapsNullKeyWord(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
  M_Full_GetSetParam_Caps(p_stValue, 0);
  return(p_stTree);
}
 
tdstNodeInterpret *fn_p_stNoGraphKeyWord(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
  M_Full_GetSetParam_Graph(p_stValue, NULL); /* NULL ?*/
  return(p_stTree);
}
/*ENDANNECY Bart }*/
 
static tdstNodeInterpret *fn_p_stSkipThenElseParameter(tdstNodeInterpret *p_stTree, tdstNodeInterpret *p_stTreeInit)
{
#if defined(OPTIMIZE_SWAP_PARAMETER)
	if(M_NodeToSkip(p_stTreeInit))/*CBOPT p_stTree*/
	{ 
		return (p_stTreeInit+M_NodeToSkip(p_stTreeInit)); /* Swap "then/else" parameter.*/
	}
	else
	{
		p_stTree = fn_p_stSwapNextParameter(p_stTree + 1); /* Swap "then/else" parameter.*/
		M_NodeToSkip(p_stTreeInit)=(unsigned short) (p_stTree-p_stTreeInit);
	}      
#else
	p_stTree++; /* Swap Then/Else node.*/
	p_stTree = fn_p_stSwapNextParameter(p_stTree); /* Swap "then/else" parameter.*/
#endif /* OPTIMIZE_SWAP_PARAMETER*/
	return p_stTree;
}
 
tdstNodeInterpret *fn_p_stThenKeyWord(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
  return fn_p_stIntelligenceEvalTreeEngine(p_SuperObjPerso, p_stTree, p_stValue);
}
 
tdstNodeInterpret *fn_p_stElseKeyWord(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
	p_stTree--; /* Fixe tree on Else Node.*/
	return fn_p_stSkipThenElseParameter(p_stTree, p_stTree);
}
 
#ifndef U64 /* AR9809*/
extern char gcGlobAleat;
 
#ifdef __DEBUG_AI__
__declspec(dllexport) char gcSimulateRelease = 0;
#else
__declspec(dllexport) char gcSimulateRelease = 1;
#endif
#else
char gcSimulateRelease = 1;
 
#endif /*U64*/
 
#ifndef U64 /* AR9809*/
__declspec(dllexport) char gcSimulateNotU64 = 0;
#else
char gcSimulateNotU64 = 1;
#endif /*U64*/
 
/************************************************************************************/
tdstNodeInterpret *fn_p_stIfDebug(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
	enum tdeKeyWordId_	eKeyId=M_eKeyWordIdInterpret(p_stTree-1);
 
	p_SuperObjPerso=p_SuperObjPerso;
	p_stValue=p_stValue;
 
	if((eKeyId == eKeyWord_IfDebug) && (gcSimulateRelease))
	{
		p_stTree = fn_p_stSkipThenElseParameter(p_stTree-1, p_stTree-1);
	}
 
	M_Full_GetSetParam_ActionReturn(p_stValue, C_ACTION_ENGINE_CONTINUE);
    return(p_stTree);
}
 
/************************************************************************************/
tdstNodeInterpret *fn_p_stIfNotU64(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
	enum tdeKeyWordId_	eKeyId=M_eKeyWordIdInterpret(p_stTree-1);
 
	p_SuperObjPerso=p_SuperObjPerso;
	p_stValue=p_stValue;
 
	if((eKeyId == eKeyWord_IfNotU64) && (gcSimulateNotU64))
	{
		p_stTree = fn_p_stSkipThenElseParameter(p_stTree-1, p_stTree-1);
	}
 
	M_Full_GetSetParam_ActionReturn(p_stValue, C_ACTION_ENGINE_CONTINUE);
    return(p_stTree);
}
 
/************************************************************************************/
tdstNodeInterpret *fn_p_stIfKeyWord(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
	tdstNodeInterpret	*p_stTreeInit=p_stTree-1; /* p_stTreeInit link to If node.*/
	char				cMax = 0;
 
	if(M_eKeyWordIdInterpret(p_stTreeInit) == eKeyWord_If)
	{
		M_EvalNextParameter(p_stValue);
	}
	else
	{
		switch(M_eKeyWordIdInterpret(p_stTreeInit))
		{
		case eKeyWord_If2:
			cMax = gcGlobAleat & 0x01;
			goto ComIf;
		case eKeyWord_If4:
			cMax = gcGlobAleat & 0x03;
			goto ComIf;
		case eKeyWord_If8:
			cMax = gcGlobAleat & 0x07;
			goto ComIf;
		case eKeyWord_If16:
			cMax = gcGlobAleat & 0x0F;
			goto ComIf;
 
ComIf:
			if(cMax)
			{
				M_GetSetParam_lValue(p_stValue) = 0;
				/*
				 * bidouille pour éviter les plantages dans le cas d'un if - cond - then avec qu'un seul
				 * noeud au milieu. 
				 * p_stTreeInit = If (profondeur n) , p_stTree = Cond (prof n+1)
				 * la ligne suivante recherche le then de même niveau que le if (p_stTree + 2)
				 */
				p_stTree = fn_p_stSkipThenElseParameter(p_stTreeInit, p_stTree);
			}
			else 
			{
				M_EvalNextParameter(p_stValue);
			}
			break;
 
		case eKeyWord_IfNot:
			M_EvalNextParameter(p_stValue);
			M_GetSetParam_lValue(p_stValue) = M_GetSetParam_lValue(p_stValue) != 0 ? 0 : 1;
			break;
/*XB(07/01/98)*/
		default:
			break;
/*End XB*/
		}
	}
 
	/* Eval the condition*/
	/*M_EvalNextParameter(p_stValue);*/
	
	if (M_GetSetParam_lValue(p_stValue) != 0)
	{	/* Condition is True.*/
#if defined(ACTIVE_AIDEBUG)
		AIDebug_M_SetKeyWord
			(
			AI_M_stGetMindOfSuperObj(p_SuperObjPerso),
			p_stValue,
			p_stTree
			);
#endif /*ACTIVE_AIDEBUG*/
		p_stTree++; /* Swap Then node.*/
		/*p_stTree = fn_p_stIntelligenceEvalTreeEngine(p_SuperObjPerso, p_stTree, p_stValue); // Eval "then" parameter.
		if (   (M_GetTypeInterpret(p_stTree) == E_ti_KeyWord)
			&& (M_eKeyWordIdInterpret(p_stTree) == eKeyWord_Else))
		{	// There is Else node.
			return fn_p_stSkipThenElseParameter(p_stTree, p_stTree);
		}*/
	}
	else
	{	/* Condition is False.*/
		if (!M_IsTheEndOfTree(p_stTree))
			p_stTree = fn_p_stSkipThenElseParameter(p_stTree, p_stTreeInit);
		
		if (M_DepthInterpret(p_stTree) == M_DepthInterpret(p_stTreeInit))
		{
			if (   (M_GetTypeInterpret(p_stTree) == E_ti_KeyWord)
				&& (M_eKeyWordIdInterpret(p_stTree) == eKeyWord_Else))
			{
#if defined(ACTIVE_AIDEBUG)
				AIDebug_M_SetKeyWord
					(
					AI_M_stGetMindOfSuperObj(p_SuperObjPerso),
					p_stValue,
					p_stTree
					);
#endif /*ACTIVE_AIDEBUG*/
				p_stTree++; /* Swap Else node.*/
			}
			/* Eval next parameter.*/
			/*M_EvalNextParameter(p_stValue);*/
		}
	}     
	M_Full_GetSetParam_ActionReturn(p_stValue, C_ACTION_ENGINE_CONTINUE);
	return(p_stTree);
}
 
tdstNodeInterpret *fn_p_stEngineGotoKeyWord(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
	char szForErrorString[200];
	tdstNodeInterpret *p_stTempTree;
	long lValue;
	
	M_EvalNextParameter(p_stValue);
	lValue = M_ReturnParam_lValue(p_stValue);
 
	M_Full_GetSetParam_ActionReturn(p_stValue, C_ACTION_ENGINE_CONTINUE);
 
	if (lValue == 0)
	{
		sprintf(szForErrorString,"parameter zero in %s", AI_M_szGetSuperObjectName(p_SuperObjPerso));
		M_AIWarningErrorAndNeverStopForDebug(E_uwAIWarningEngineGoto,C_ucErmOpenInfoWindow,szForErrorString);
	}
	else
		if (lValue < 0)
		{
			tdstNodeInterpret *p_stBeginTree = M_GetNodeInterpret(M_GetRuleN(g_p_stIntelligence, g_ucNRule));
			p_stTempTree = p_stTree+lValue;
			if (p_stTempTree < p_stBeginTree)
			{
				sprintf(szForErrorString,"out of interpret tree (negative) in %s", AI_M_szGetSuperObjectName(p_SuperObjPerso));
				M_AIWarningErrorAndNeverStopForDebug(E_uwAIWarningEngineGoto,C_ucErmOpenInfoWindow,szForErrorString);
			}
			else
				return p_stTempTree;
		}
		else
			/* lValue > 0*/
		{
			long i;
			p_stTempTree = p_stTree;
			for (i = 0; i < lValue; i++)
			{
				if (M_IsTheEndOfTree(p_stTempTree))
				{
					sprintf(szForErrorString,"out of interpret tree (positive) in %s", AI_M_szGetSuperObjectName(p_SuperObjPerso));
					M_AIWarningErrorAndNeverStopForDebug(E_uwAIWarningEngineGoto,C_ucErmOpenInfoWindow,szForErrorString);
					return p_stTree;
				}
				else
					p_stTempTree++;
			}	
			return p_stTempTree;
 
		}
		return(p_stTree);
}
 
/************************************************************************************/
/* HERE IS THE END                                                                  */
/************************************************************************************/
 
/****************************************************************************************/
/* to call once before anything else related to KeyWord                              */
/****************************************************************************************/
#if !defined(OPTIMIZED_COMMAND)
#include "Convert.h"
#include "ProtCond.h"
 
void fn_vInitKeyWordEntries(void)
{
/* Init*/
#if defined(__DEBUG_AI__)
  fn_vInitKeyWordTable(fn_p_stDefaultKeyWord);
#endif
 
/* KeyWord definition*/
  #define M_DEFINE_KEYWORD(a,b,english,c,d,e,f) fn_vDefineKeyWordEntry(M_KEYWORD_ENTRY(a,b,english,c,d,e,f));
  #include "DefKey.h"
  #undef M_DEFINE_KEYWORD
        
/* Check*/
#if defined(__DEBUG_AI__)
  fn_vCheckKeyWordTable(fn_p_stDefaultKeyWord);
#endif /* __DEBUG_AI__*/
 
}
#endif /* OPTIMIZED_COMMAND*/
 
