// EdIRBELs.cpp : implementation file
//

#include "stdafx.h"

#include "Defines.hpp"

#ifdef D_ED_IR_ACTIVE

#include "EdIRBELs.hpp"

#include "EdIRBeEn.hpp"
#include "EdIRBeha.hpp"
#include "EdIR2Eng.hpp"
#include "EdIRBis.hpp"
#include "EdIRDVLs.hpp"
#include "EdIRDvVw.hpp"
#include "EdIRFrm.hpp"
#include "EdIRIRD.hpp"
#include "EdIRStrg.hpp"

#include "ACP_Base.h"
#include "ITF.h"
#include "IncMEC.h"

#include "incAI.h"
// Shaitan => optimisation lists in the level
#include "TFA.h"
// End Shaitan => optimisation lists in the level

#include "_Actors.hpp"

#include "EDACModl.hpp"

/*#include "ai_intf.hpp"
#include "EDACInst.hpp"
#include "EDACDoc.hpp"*/
#include "x:\cpa\main\inc\_EditID.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//////////////////////////////////////////////////////////////////
// class CPA_EdIR_MainBehaviourList
//////////////////////////////////////////////////////////////////

/****************************************************************************/
CPA_EdIR_MainBehaviourList::CPA_EdIR_MainBehaviourList()
{
	m_pclOldActiveMainBehaviour	=NULL;
	m_bHasBeenModified					=FALSE;
}

/****************************************************************************/
CPA_EdIR_MainBehaviourList::CPA_EdIR_MainBehaviourList(CPA_Actor *pclModel,CPA_EdIR_MainBehaviourList *p_clMainBehaviourList)
{
	m_pclOldActiveMainBehaviour	=p_clMainBehaviourList->m_pclOldActiveMainBehaviour;
	m_bHasBeenModified					=FALSE;

	POSITION	pos=p_clMainBehaviourList->GetHeadPosition();
	while(pos!=NULL)
	{
		CPA_EdIR_MainBehaviour *pclMainBehaviour=p_clMainBehaviourList->GetNext(pos);

		AddTail(new CPA_EdIR_MainBehaviour(pclModel,*(pclMainBehaviour)));
	}
}

/****************************************************************************/
CPA_EdIR_MainBehaviourList::~CPA_EdIR_MainBehaviourList()
{
}

/****************************************************************************/
void CPA_EdIR_MainBehaviourList::m_fn_vDeleteAllMainBehaviours()
{
	POSITION	pos=GetHeadPosition();
	while(pos!=NULL)
		delete GetNext(pos);
}

/****************************************************************************/
long CPA_EdIR_MainBehaviourList::m_fn_lGetNbPages(long lLineHeight,
																									long lPageHeight,
																									BOOL bOneBehaviourOnAPage)
{
	long	lNbPages=0;

	if(bOneBehaviourOnAPage)
	{
		POSITION	pos=GetHeadPosition();
		while(pos!=NULL)
		{
			CPA_EdIR_MainBehaviour *pclMainBehaviour=GetNext(pos);

			//Gets nb pages for this behaviour and adds to the total nb pages
			lNbPages+=pclMainBehaviour->m_fn_lGetNbPages(lLineHeight,lPageHeight);
		}
	}
	else
	{
		//Computes nb lines required for printing all behaviours
		POSITION	pos=GetHeadPosition();
		long			lNbLines=0;
		while(pos!=NULL)
		{
			CPA_EdIR_MainBehaviour *pclMainBehaviour=GetNext(pos);

			lNbLines+=pclMainBehaviour->m_fn_lGetNbLines();
		}

		//Computes nb pages for printing lNbLines
		long	lNbLinesInAPage=lPageHeight/lLineHeight;
		while(lNbLines>=0)
		{
			lNbLines-=lNbLinesInAPage;
			lNbPages++;
		}
	}

	return lNbPages;
}

/****************************************************************************/
void CPA_EdIR_MainBehaviourList::m_fn_vPrint(long lLineHeight,
																						 long lPageHeight,
																						 BOOL bOneBehaviourOnAPage,
																						 long lCurrentPage,
																						 CDC *pDC,CPrintInfo *pInfo)
{
	if(bOneBehaviourOnAPage)
	{
		POSITION	pos=GetHeadPosition();
		long			lCurStartPage=0;
		long			lCurEndPage=0;
		BOOL			bEnd=FALSE;
		while(pos!=NULL && !bEnd)
		{
			CPA_EdIR_MainBehaviour *pclMainBehaviour=GetNext(pos);

			lCurEndPage=lCurStartPage+pclMainBehaviour->m_fn_lGetNbPages(lLineHeight,lPageHeight);

			//Checks if this behaviour must be printed on this page
			if(lCurrentPage>=lCurStartPage &&
				 lCurrentPage<=lCurEndPage)
			{
				//Prints this behaviour
				//Substracts 5 mm to increase printer's margins
				long	lDPI=pDC->GetDeviceCaps(LOGPIXELSY);
				long	lFiveMmInDPI=long(double(5*lDPI)/25.4);
				CString	csText=pclMainBehaviour->m_fn_csGetTextToPrint(lLineHeight,pDC->GetDeviceCaps(VERTRES)-lFiveMmInDPI,lCurrentPage-lCurStartPage);

				pDC->DrawText(csText,pInfo->m_rectDraw,DT_LEFT);

				bEnd=TRUE;
			}

			lCurStartPage=lCurEndPage;
		}
	}
	else
	{
		//Computes start line number and end line number for the current page (lCurrentPage)
		long	lNbLinesInAPage=lPageHeight/lLineHeight;
		long	lStartLineNumber=(lCurrentPage-1)*lNbLinesInAPage;
		long	lEndLineNumber=lStartLineNumber+lNbLinesInAPage-1;

		POSITION	pos=GetHeadPosition();
		long			lCurStartLine=0;
		long			lCurEndLine=0;
		while(pos!=NULL)
		{
			CPA_EdIR_MainBehaviour *pclMainBehaviour=GetNext(pos);

			lCurEndLine=lCurStartLine+pclMainBehaviour->m_fn_lGetNbLines();

			//Checks if this behaviour must be printed on this page
			long	lCurStartPrintLine=lCurStartLine;
			long	lCurEndPrintLine=lCurEndLine;
			if(lCurStartLine<=lStartLineNumber &&
				 lCurEndLine>=lStartLineNumber)
				lCurStartPrintLine=lStartLineNumber;

			if(lCurEndLine>=lEndLineNumber &&
				 lCurStartLine<=lEndLineNumber)
				lCurEndPrintLine=lEndLineNumber;

			if(lCurStartPrintLine>=lStartLineNumber &&
				 lCurEndPrintLine<=lEndLineNumber)
			{
				//Prints this behaviour
				CString	csText;
				csText=pclMainBehaviour->m_fn_csGetTextBetweenLines(lCurStartPrintLine-lCurStartLine,
																														lCurEndPrintLine-lCurStartLine);

				//Computes printable rect
				CRect	crRect(0,0,pDC->GetDeviceCaps(HORZRES),0);
				crRect.top=(lCurStartPrintLine-lStartLineNumber)*lLineHeight;
				crRect.bottom=(lCurEndPrintLine-lStartLineNumber+1)*lLineHeight;
				pDC->DrawText(csText,crRect,DT_LEFT);
			}

			lCurStartLine=lCurEndLine;
		}
	}
}

/****************************************************************************/
BOOL CPA_EdIR_MainBehaviourList::m_fn_bIsInList(CString csBehaviourName)
{
	POSITION	pos=GetHeadPosition();
	BOOL			bFound=FALSE;
	while(pos!=NULL && !bFound)
	{
		bFound=(GetNext(pos)->GetName().CompareNoCase(csBehaviourName)==0);
	}

	return bFound;
}

/****************************************************************************/
long CPA_EdIR_MainBehaviourList::m_fn_lGetIndexOfABehaviour(CString csBehaviourName)
{
	POSITION	pos=GetHeadPosition();
	long			lIndex=0;
	BOOL			bFound=FALSE;
	while(pos!=NULL && !bFound)
	{
		bFound=(GetNext(pos)->GetName().CompareNoCase(csBehaviourName)==0);

		lIndex++;
	}

	return lIndex-1;
}

/****************************************************************************/
CPA_EdIR_MainBehaviour *CPA_EdIR_MainBehaviourList::m_fn_pclGetMainBehaviour(CString csBehaviourName)
{
	POSITION								pos=GetHeadPosition();
	CPA_EdIR_MainBehaviour	*pclMainBehaviour=NULL;
	while(pos!=NULL && pclMainBehaviour==NULL)
	{
		if(GetAt(pos)->GetName().CompareNoCase(csBehaviourName)==0)
			pclMainBehaviour=GetAt(pos);

		GetNext(pos);
	}

	return pclMainBehaviour;
}

/****************************************************************************/
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Method : CPA_EdIR_MainBehaviourList::m_fn_csGetRules
// Date   : 98.03
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Description :
// Author      : Cristi Petrescu
//////////////////////////////////////////////////////////////////////////////////////////////////////
// Modification :
// Date         :
// By           :
//////////////////////////////////////////////////////////////////////////////////////////////////////
CString CPA_EdIR_MainBehaviourList::m_fn_csGetRules(CString csBehaviourName)
{
	CPA_EdIR_MainBehaviour *pclMainBehaviour = m_fn_pclGetMainBehaviour (csBehaviourName);
	
	return pclMainBehaviour -> m_pclBehaviour -> m_fn_csGetRules ();
}

/****************************************************************************/
BOOL CPA_EdIR_MainBehaviourList::m_fn_bCheckIA(tdeTypeText eTypeText, BOOL ForProcess)
{
	POSITION	pos=GetHeadPosition();
	BOOL			bNoError=TRUE;
	while(pos!=NULL && bNoError)
	{
		CPA_EdIR_MainBehaviour	*pclMainBehaviour=GetNext(pos);
		CPA_EdIR_Behaviour			*pclBehaviour=pclMainBehaviour->m_pclBehaviour;

		bNoError= (pclBehaviour ? pclBehaviour->m_fn_bCheckIA(eTypeText) : TRUE);
	}

	return bNoError;
}

/****************************************************************************/
BOOL CPA_EdIR_MainBehaviourList::m_fn_bProcessIA(BOOL bProcessAll,BOOL bCreateControl,
																								 AI_tdstMind *pstMind,tdstComport *pstComport,
																								 tdeTypeText eTypeText,CPA_EdIR_DebugInfoList *pclDebugInfoList)
{
	POSITION	pos=GetHeadPosition();
	BOOL			bNoError=TRUE;
	long			lCurrentBehaviour=0;

	if(eTypeText == CRRGeneration)
	{
		while(pos!=NULL)
		{
			CPA_EdIR_MainBehaviour	*pclMainBehaviour=GetNext(pos);
			CPA_EdIR_Behaviour		*pclBehaviour=pclMainBehaviour->m_pclBehaviour;
			pclBehaviour->m_fn_bProcessIA(TRUE,FALSE,NULL,NULL,NULL,CRRGeneration, pclDebugInfoList);
		}
	}

	//BEGIN ROMTEAM Cristi Petrescu 98-04-
	struct tdstMacro_ *pstSubr;
	if (eTypeText == SubrText)
	{
		pstSubr = ((tdstListOfMacro	*) pstComport) -> p_stMacro;
	}
	//END ROMTEAM Cristi Petrescu 98-04-

	while(pos!=NULL && bNoError)
	{
		CPA_EdIR_MainBehaviour	*pclMainBehaviour=GetNext(pos);
// Shaitan => optimisation lists in the level
		CList<CPA_BaseObject *,CPA_BaseObject *>	clListOfOldDependencies;
		clListOfOldDependencies.RemoveAll();

		BOOL bMustCheckDependancies = pclMainBehaviour->m_fn_bHasBeenModified();
// End Shaitan => optimisation lists in the level

		//Remove old dependences
		POSITION	p=pclMainBehaviour->m_clListOfDependencies.GetHeadPosition();
		while(p!=NULL)
		{
			CPA_BaseObject	*pclChild=pclMainBehaviour->m_clListOfDependencies.GetNext(p);

			g_oCoherenceManager.m_fn_vRemoveALink(pclMainBehaviour,pclChild);
// Shaitan => optimisation lists in the level
			clListOfOldDependencies.AddTail(pclChild);
// End Shaitan => optimisation lists in the level
		}
		pclMainBehaviour->m_clListOfDependencies.RemoveAll();

		//BEGIN ROMTEAM Cristi Petrescu 98-05-
		CPA_EdIR_DebugInfoList *pclGlobalDebugInfoList = pclDebugInfoList;
		pclDebugInfoList = & pclMainBehaviour -> m_clDebugInfoList;
		// do not destroy because this is just a duplicate list.
		// destroyng is done for the whole Brain list
		pclDebugInfoList -> RemoveAll ();
		//END ROMTEAM Cristi Petrescu 98-05-

		//Applies IA
		CPA_EdIR_Behaviour			*pclBehaviour=pclMainBehaviour->m_pclBehaviour;

		//BEGIN ROMTEAM Cristi Petrescu 98-04-
		if (eTypeText == SubrText)
		{
			CPA_Actor	*pclModel=(CPA_Actor *)pclMainBehaviour->GetOwner();
			CString		csFamilyName=pclModel->m_fn_csGetFamilyName();
			CString		csModelName=pclModel->GetName();
			CString		csBehaviourName=pclMainBehaviour->GetName();
			CString		csBehaviourRefName=csFamilyName+"\\"+csModelName+"\\"+csModelName+g_c_csAIRulFileExtension+"^"+
																	 g_c_csRulSectionName+"^"+g_c_csBehavSectionName+":"+csBehaviourName;
			strcpy(M_GetNameMacro(pstSubr),M_MAKECHAR(csBehaviourRefName));
			// perhaps some debug integration here... do it later.
			bNoError=pclBehaviour->m_fn_bProcessIA(bProcessAll,bCreateControl,pstMind,pstComport,(tdstTreeInterpret *) pstSubr,eTypeText,pclDebugInfoList);

			pstSubr ++;
		}
		else if(!pclBehaviour->m_bDeclaration && eTypeText != Macro_2_Text)
		//END ROMTEAM Cristi Petrescu 98-04-
		{
			long		lNbRules=fn_lGetNbRules(pclBehaviour->m_fn_csGetRules());

			tdstTreeInterpret	*pstRule;

			pstRule=fn_p_stAllocRule((unsigned char)lNbRules);
                      
			M_GetComportRules(pstComport)=pstRule;
			M_GetComportNbRules(pstComport)=(unsigned char)lNbRules;

			//Sets behaviour name (debug information for engine)
			CPA_Actor	*pclModel=(CPA_Actor *)pclMainBehaviour->GetOwner();
			CString		csFamilyName=pclModel->m_fn_csGetFamilyName();
			CString		csModelName=pclModel->GetName();
			CString		csBehaviourName=pclMainBehaviour->GetName();
			CString		csBehaviourRefName=csFamilyName+"\\"+csModelName+"\\"+csModelName+g_c_csAIRulFileExtension+"^"+
																	 g_c_csRulSectionName+"^"+g_c_csBehavSectionName+":"+csBehaviourName;

			strcpy(M_GetNameComport(pstComport),M_MAKECHAR(csBehaviourRefName));

			bNoError=pclBehaviour->m_fn_bProcessIA(bProcessAll,bCreateControl,pstMind,pstComport,pstRule,eTypeText,pclDebugInfoList);

			pstComport++;
		}
		else
		{
			bNoError=pclBehaviour->m_fn_bProcessIA(bProcessAll,bCreateControl,pstMind,NULL,NULL,eTypeText,pclDebugInfoList);
		}

		//BEGIN ROMTEAM Cristi Petrescu 98-05-

		//Update the global debug list
		POSITION pos = pclDebugInfoList -> GetHeadPosition ();
		CPA_EdIR_DebugInfo *pclDebugInfo;
		while (pos)
		{
			pclDebugInfo = pclDebugInfoList -> GetNext (pos);
			pclGlobalDebugInfoList -> AddTail (pclDebugInfo);
		}
		pclDebugInfoList = pclGlobalDebugInfoList;
		//END ROMTEAM Cristi Petrescu 98-05-

// Shaitan => optimisation lists in the level
		if (bMustCheckDependancies)
		{
			// first check if there are new dependancies in the behaviour
			POSITION pos1 = pclMainBehaviour->m_clListOfDependencies.GetHeadPosition();
			while (pos1)
			{
				CPA_BaseObject	*pclChild = pclMainBehaviour->m_clListOfDependencies.GetNext(pos1);
				if (pclChild->GetType() == C_szActionTypeName)
				{
					if (!clListOfOldDependencies.Find(pclChild))
						((CPA_Family *) pclChild->GetOwner())->mfn_vSetModifiedStateList();
				}
				else if (pclChild->GetType() == C_szObjectTableTypeName)
				{
					if (!clListOfOldDependencies.Find(pclChild))
						((CPA_Family *) pclChild->GetOwner())->mfn_vSetModifiedPOList();
				}
			}
			// then check if the old dependancies are still valid
			pos1 = clListOfOldDependencies.GetHeadPosition();
			while (pos1)
			{
				CPA_BaseObject	*pclChild = clListOfOldDependencies.GetNext(pos1);
				if (pclChild->GetType() == C_szActionTypeName)
				{
					if (!pclMainBehaviour->m_clListOfDependencies.Find(pclChild))
						((CPA_Family *) pclChild->GetOwner())->mfn_vSetModifiedStateList();
				}
				else if (pclChild->GetType() == C_szObjectTableTypeName)
				{
					if (!pclMainBehaviour->m_clListOfDependencies.Find(pclChild))
						((CPA_Family *) pclChild->GetOwner())->mfn_vSetModifiedPOList();
				}
			}
		}
// End Shaitan => optimisation lists in the level

		lCurrentBehaviour++;
	}

	if (bCreateControl)
	{
		// update control list
		CPA_DLLBase						*pclActorDLL						=(CPA_DLLBase*)(g_pclAIInterface->GetMainWorld()->GetObjectDLLWithName(C_szDLLActorName));
		CPA_EdIR_DesignerVariablesView	*pclDsgVarView						=(CPA_EdIR_DesignerVariablesView *)pclActorDLL->OnQueryAction(g_pclAIInterface,C_uiActor_GetDesignerVariablesView,0);
		CPA_EdIR_Frame					*pclIRMainFrame						=g_pclAIInterface->m_pclIRMainFrame;
		CPA_Actor						*pclModel							=pclIRMainFrame->m_fn_pclGetModel();
		CTL_Editor_ControlList			*pclListOfDesignerVariableControl	=&(((EdActors_EditorActorModel *)pclModel->m_fn_pclGetEditorActor())->m_clListOfDesignerVariableControl);

		pclDsgVarView->m_fn_vUpdateControls(pclListOfDesignerVariableControl);
	}

	return bNoError;
}

/****************************************************************************/
BOOL CPA_EdIR_MainBehaviourList::m_fn_bHasBeenModified()
{
	POSITION	pos=GetHeadPosition();
	BOOL			bHasBeenModified=FALSE;
	while(pos!=NULL && !bHasBeenModified)
		bHasBeenModified=bHasBeenModified || GetNext(pos)->m_fn_bHasBeenModified();

	return (m_bHasBeenModified||bHasBeenModified);
}

/****************************************************************************/
void CPA_EdIR_MainBehaviourList::m_fn_vSetModified(BOOL bIsModified)
{
	POSITION	pos=GetHeadPosition();
	while(pos!=NULL)
		GetNext(pos)->m_fn_vSetModified(bIsModified);

	m_bHasBeenModified=bIsModified;
}

#endif //D_ED_IR_ACTIVE
