// IADTrCtl.cpp : implementation file
/////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#define HieFriend

#include "IADTrCtl.hpp"

#include "IADEdtTr.hpp"
#include "IADLnkMt.hpp"
#include "_IADItrf.hpp"
#include "IADVwRst.hpp"
#include "IAD_Res.h"
#include "x:/cpa/tempgrp/tia/inc/ai_intf.hpp"
#include "x:/cpa/main/inc/_EditId.h"

// BEGIN ROMTEAM Cristi Petrescu 98-06-
#include "iadvrvw.hpp"
// END ROMTEAM Cristi Petrescu 98-06-

//External Modules
#include "OAc.h"
//End of External Modules

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

#define IAD_C_PLUS_MINUS_BITMAP_SIZE	9

#define IAD_C_STATIC_TEXT_COLOR				RGB(255,255,255)


/////////////////////////////////////////////////////////////////////////////
// IAD_TreeControl

BEGIN_MESSAGE_MAP(IAD_TreeControl, CTreeCtrl)
	//{{AFX_MSG_MAP(IAD_TreeControl)
	ON_WM_PAINT()
	ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged)
	ON_WM_CTLCOLOR_REFLECT()
	ON_NOTIFY_REFLECT(TVN_KEYDOWN, OnKeydown)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


//***************************************************************************
IAD_TreeControl::IAD_TreeControl()
{
	m_pri_clBrush.CreateSolidBrush(RGB(50,50,50));
	m_pri_clPen.CreatePen(PS_SOLID, 1, RGB(230,230,230));
	//m_pri_clPen.CreatePen(PS_DOT, 1, RGB(230,230,230));
	m_pri_cbBitmapPlus.LoadBitmap(IDB_BITMAP_PLUS);
	m_pri_cbBitmapMinus.LoadBitmap(IDB_BITMAP_MINUS);

	//BEGIN ROMTEAM Cristi Petrescu 98-05-
	m_bViewReflex = TRUE;
	m_bViewAI = TRUE;

	m_pclSelectedBehaviourNode = NULL;
	//END ROMTEAM Cristi Petrescu 98-05-
}

//***************************************************************************
IAD_TreeControl::~IAD_TreeControl()
{

}

/////////////////////////////////////////////////////////////////////////////
// IAD_TreeControl message handlers

//***************************************************************************
BOOL IAD_TreeControl::m_pub_fn_bCreate(CWnd *_pclParentWnd)
{
	BOOL bReturn = CTreeCtrl::Create(	WS_VISIBLE | WS_CHILD | WS_BORDER | TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS | TVS_SHOWSELALWAYS | TVS_DISABLEDRAGDROP,
																		CRect(0,0,0,0),
																		_pclParentWnd,
																		10069);

	return bReturn;
}

//***************************************************************************
void IAD_TreeControl::m_pub_fn_vSelectAndShowItem(HTREEITEM _hTreeItem)
{
	if ( _hTreeItem != NULL )
	{
		//Closes all
		m_pri_fn_vCollapseAllButNotThis(_hTreeItem);

		//Shows
		EnsureVisible(_hTreeItem);

		//Selects
		SelectItem(_hTreeItem);
	}
}

//***************************************************************************
void IAD_TreeControl::m_pri_fn_vCollapseAllButNotThis(HTREEITEM _hTreeItemToKeepExpanded)
{
	//Gets first parent of given Item
	HTREEITEM hFirsParent = GetParentItem(_hTreeItemToKeepExpanded);
	HTREEITEM hParentOfParent = GetParentItem(hFirsParent);
	while ( hParentOfParent != NULL )
	{
		hFirsParent = hParentOfParent;
		hParentOfParent = GetParentItem(hFirsParent);
	}

	HTREEITEM hCurrenItem = GetNextItem(NULL, TVGN_ROOT);

	while ( hCurrenItem != NULL )
	{
		if ( hCurrenItem != hFirsParent )
			Expand(hCurrenItem, TVE_COLLAPSE);

		hCurrenItem = GetNextItem(hCurrenItem, TVGN_NEXT);
	}
}

//***************************************************************************
void IAD_TreeControl::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	dc.SetTextColor(RGB(255,0,0));
	dc.SetBkMode(TRANSPARENT);
	dc.SelectObject(GetFont());
	
	CDC memDC;
	memDC.CreateCompatibleDC(&dc);

	//Gets current visible Rectangle for the View
	CRect crVisibleRect;
	GetClientRect(crVisibleRect);

	//Re-draws visible Items lines
	HTREEITEM hCurrentTreeItem = GetFirstVisibleItem();
	CRect crCurrentRect;
	IAD_EditorTreeNode *pclCurrentNode;
	BOOL bItemIsSelected;
	BOOL bItemIsDevelopped;
	short wX, wY;
	BOOL bMustGoOn = TRUE;

	while ( (hCurrentTreeItem != NULL) && (bMustGoOn) )
	{
		bItemIsSelected = ( (GetItemState(hCurrentTreeItem, TVIF_STATE) & TVIS_SELECTED) != 0 );

		//Gets Data
		pclCurrentNode = (IAD_EditorTreeNode *)GetItemData(hCurrentTreeItem);

		//Gets rectangle
		GetItemRect(hCurrentTreeItem, &crCurrentRect, TRUE);

		//If item is really visible
		if ( (crCurrentRect.top >= crVisibleRect.top) && (crCurrentRect.top <= crVisibleRect.bottom) )
		{
			HTREEITEM hParentItem = GetParentItem(hCurrentTreeItem);
			if ( hParentItem != NULL )
			{
				//Displays horizontal lines
				CRect crParentItemRect;
				GetItemRect(hParentItem, &crParentItemRect, TRUE);

				dc.SelectObject(&m_pri_clPen);
				
				wY = crCurrentRect.top + crCurrentRect.Height() / 2;
				dc.MoveTo(crCurrentRect.left - 1,
									wY);
				dc.LineTo(crParentItemRect.left + 3,
									wY);

				//Displays vertical line
				wX = crParentItemRect.left + 3;
				dc.MoveTo(wX,
									crCurrentRect.top + crCurrentRect.Height() / 2);
				dc.LineTo(wX,
									(short)crParentItemRect.bottom - 2);
			}

	//		if ( bMustGoOn )
	//		{
				//If Item is selected
				if ( bItemIsSelected )
					dc.FillSolidRect(&crCurrentRect, RGB(0,0,255));

				//Sets item's text
				m_pri_fn_vDisplayText(pclCurrentNode, &dc, crCurrentRect);
	//		}
		}
		else
			bMustGoOn = FALSE;

		hCurrentTreeItem = GetNextVisibleItem(hCurrentTreeItem);
	}

	//Re-draws visible Items
	hCurrentTreeItem = GetFirstVisibleItem();
	bMustGoOn = TRUE;

	while ( (hCurrentTreeItem != NULL) && (bMustGoOn) )
	{
		bItemIsDevelopped = ( (GetItemState(hCurrentTreeItem, TVIF_STATE) & TVIS_EXPANDED) != 0 );

		//Gets Data
		pclCurrentNode = (IAD_EditorTreeNode *)GetItemData(hCurrentTreeItem);

		//Gets rectangle
		GetItemRect(hCurrentTreeItem, &crCurrentRect, TRUE);

		//If item is really visible
		if ( (crCurrentRect.top >= crVisibleRect.top) && (crCurrentRect.top <= crVisibleRect.bottom) )
		{
			//Set's item's button
			//If Item has at least one child
			if ( GetChildItem(hCurrentTreeItem) != NULL )
			{
				//Draws a bitmap to represent '+' or '-' buttons
				if ( bItemIsDevelopped )
					memDC.SelectObject(&m_pri_cbBitmapMinus);
				else
					memDC.SelectObject(&m_pri_cbBitmapPlus);
				
				wX = crCurrentRect.left - GetIndent() + 3 - IAD_C_PLUS_MINUS_BITMAP_SIZE/2;
				wY = crCurrentRect.top + (crCurrentRect.Height() - IAD_C_PLUS_MINUS_BITMAP_SIZE) / 2;

				dc.BitBlt(wX,
									wY,
									IAD_C_PLUS_MINUS_BITMAP_SIZE,	//Width
									IAD_C_PLUS_MINUS_BITMAP_SIZE,	//Height
									&memDC,
									0,
									0,
									SRCCOPY);
			}
		}
		else
			bMustGoOn = FALSE;

		hCurrentTreeItem = GetNextVisibleItem(hCurrentTreeItem);
	}

	// Do not call CTreeCtrl::OnPaint() for painting messages
}

//***************************************************************************
void IAD_TreeControl::m_pri_fn_vDisplayText(IAD_EditorTreeNode *_pclNode,
																						CDC *_pclDC,
																						CRect crRect)
{
	//Name
//	_pclDC->SetTextColor(RGB(255,0,0));
	long lCurrentXPos = crRect.left + 1;

	CString csName = _pclNode->m_pub_fn_csGetNodeType();

	//BEGIN ROMTEAM Cristi Petrescu 98-05-
	// do not dispaly type if shouldn't be both displayed
	if (!((csName == "R:" && m_bViewReflex == TRUE && m_bViewAI == FALSE) ||
		  (csName == "I:" && m_bViewAI == TRUE && m_bViewReflex == FALSE)))
	{
	// CG PB DEBUGGER 23/06/98 {
	#ifdef ACTIVE_AIDEBUG
		_pclDC->SetTextColor( g_a_colrefTypeColor[_pclNode->m_pub_fn_tdeGetNodeType()] );
	#endif // CG PB DEBUGGER }

	_pclDC->TextOut(lCurrentXPos, crRect.top + 1, csName);
	csName += " ";
	lCurrentXPos += _pclDC->GetTextExtent(csName).cx;
	}
	//END ROMTEAM Cristi Petrescu 98-05-

	if ( !_pclNode->m_pub_fn_csGetNodeName().IsEmpty() )
	{
		_pclDC->SetTextColor(RGB(230,255,30));
		csName = _pclNode->m_pub_fn_csGetNodeName();

		_pclDC->TextOut(lCurrentXPos, crRect.top + 1, csName);
		csName += " ";
		lCurrentXPos += _pclDC->GetTextExtent(csName).cx;
	}

	if ( !_pclNode->m_pub_fn_csGetNodeValue().IsEmpty() )
	{
		_pclDC->SetTextColor(IAD_C_STATIC_TEXT_COLOR);
		_pclDC->TextOut(lCurrentXPos, crRect.top + 1, "= ");
		lCurrentXPos += _pclDC->GetTextExtent("= ").cx;


		_pclDC->SetTextColor(RGB(80,250,155));
		csName = _pclNode->m_pub_fn_csGetNodeValue();

		_pclDC->TextOut(lCurrentXPos, crRect.top + 1, csName);
		csName += " ";
		lCurrentXPos += _pclDC->GetTextExtent(csName).cx;
	}

	if ( !_pclNode->m_pub_fn_csGetNodeReturnValue().IsEmpty() )
	{
		_pclDC->SetTextColor(IAD_C_STATIC_TEXT_COLOR);
		_pclDC->TextOut(lCurrentXPos, crRect.top + 1, "[ returns ");
		lCurrentXPos += _pclDC->GetTextExtent("[ returns ").cx;

		_pclDC->SetTextColor(RGB(0,250,215));
		csName = _pclNode->m_pub_fn_csGetNodeReturnValue();

		_pclDC->TextOut(lCurrentXPos, crRect.top + 1, csName);
		csName += " ";
		lCurrentXPos += _pclDC->GetTextExtent(csName).cx;
		
		_pclDC->SetTextColor(IAD_C_STATIC_TEXT_COLOR);
		_pclDC->TextOut(lCurrentXPos, crRect.top + 1, "]");
	}
}

//***************************************************************************
void IAD_TreeControl::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult) 
{
	if ( !g_pclInterface->m_clDocument.m_pub_bIsDeletingTree )
	{
		NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;

		//Re-draws unselected and newly selected Items
		CRect crRectToInvalidate;
		GetItemRect(pNMTreeView->itemOld.hItem, &crRectToInvalidate, TRUE);
		InvalidateRect(crRectToInvalidate);
		GetItemRect(pNMTreeView->itemNew.hItem, &crRectToInvalidate, TRUE);
		InvalidateRect(crRectToInvalidate);

		if ( ( GetItemState(pNMTreeView->itemNew.hItem, TVIF_STATE) & LVIS_SELECTED) != 0 )
		{
			// BEGIN ROMTEAM Cristi Petrescu 98-06-
			//Gets corresponding Editor Node
			IAD_EditorTreeNode *pclSelectedNode = (IAD_EditorTreeNode *)GetItemData(pNMTreeView->itemNew.hItem);

// CG PB DEBUGGER 23/06/98 {
#ifdef ACTIVE_AIDEBUG
			if (pclSelectedNode -> m_pub_fn_tdeGetNodeType () == AIDebug_E_SecTyp_EngineLoop &&
				! pclSelectedNode -> m_bSubtreeBuilded)
			{
				// build subtree
				// get the brain
				AI_tdstMind *p_stMind = M_pstGetMindOfBrain (((tdstEngineObject *) pclSelectedNode -> m_pub_fn_pclGetParentActor () -> GetStruct ()) -> h_Brain);
				// get the trace
				AIDebug_tdstTrace *p_stTrace = AI_M_p_stGetTrace (p_stMind);
				
				if (pclSelectedNode -> m_uwSubtreeTraceIndex >=0)
				{
					// use the the Engine Trace from the proper place
					AIDebug_M_uwGetExplIndex (p_stTrace) = pclSelectedNode -> m_uwSubtreeTraceIndex;

					// preparations done, so go for the subtree
					((IAD_ResultView *) GetParent ()) -> m_fn_vBuildSubtree (pclSelectedNode);//, pNMTreeView->itemNew.hItem);

					pclSelectedNode -> m_bSubtreeBuilded = TRUE;
					pclSelectedNode -> m_uwSubtreeTraceIndex = -1;
				}
			}
#endif 
// CG PB DEBUGGER
			// END ROMTEAM Cristi Petrescu 98-06-

			if ( g_pclInterface->m_clDocument.m_pclResultView->m_bMustSynchronize )
			{
				//BEGIN ROMTEAM Cristi Petrescu 98-05-
				// send info to the IA editor

				if (pclSelectedNode)
				{
					IAD_EditorTreeNode *pclBehaviourSelectedNode = pclSelectedNode -> m_fn_pclGetBehaviourParentNode ();
					
					if (pclBehaviourSelectedNode)
					{
						if (!(pclBehaviourSelectedNode == m_pclSelectedBehaviourNode && 
						  pclBehaviourSelectedNode -> m_pub_fn_pclGetParentActor () == m_pclSelectedBehaviourNode -> m_pub_fn_pclGetParentActor ()))
					{
						CString csBehaviourName;

						// clear the old executed nodes
						if (m_pclSelectedBehaviourNode)
						{
							csBehaviourName = m_pclSelectedBehaviourNode -> m_pub_fn_csGetNodeName ();
							m_pclSelectedBehaviourNode -> m_pub_fn_pclGetParentActor() -> m_fn_vClearExecutedNodes (csBehaviourName);
						}
		
						// add the new ones
						pclBehaviourSelectedNode -> m_fn_vAddExecutedNodes ();

						// remind the current selected behaviour
						m_pclSelectedBehaviourNode = pclBehaviourSelectedNode;
					}

					// CG PB DEBUGGER 23/06/98 {
						#ifdef ACTIVE_AIDEBUG

						// show the proper IA behaviour
						if (pclSelectedNode -> m_pub_fn_tdeGetNodeType () == AIDebug_E_SecTyp_ReflexOrAI)
						{
							// behaviour node
							pclSelectedNode -> m_pub_fn_pclGetParentActor() -> m_fn_vShowBehaviour (pclSelectedNode -> m_pub_fn_csGetNodeName ());
						}
						else
						{
							// regular node
							pclSelectedNode -> m_pub_fn_pclGetParentActor() -> m_fn_vShowBehaviour (pclSelectedNode -> m_pub_fn_p_stGetMotorNode());
						}
					#endif // CG PB DEBUGGER }

					}
				}
				//END ROMTEAM Cristi Petrescu 98-05-

				/*
				//Gets IA DLL
				CPA_DLLBase *p_clDll = g_pclInterface->GetMainWorld()->GetToolDLLWithName(C_szDLLAIEditorName);
				if ( p_clDll != NULL )
				{
					tdstActorsIACom tdstCom;
					tdstCom.pvThis = (void *)pclSelectedNode->m_pub_fn_pclGetParentActor();
					tdstCom.pvData = (void *)pclSelectedNode->m_pub_fn_p_stGetMotorNode();

					p_clDll->OnQueryAction(g_pclInterface, C_uiAI_ShowBehaviour, (long)(&tdstCom));
				}
				*/
			}

			// BEGIN ROMTEAM Cristi Petrescu 98-06-
			// Update the variable view
			IAD_EditorTreeNode *pclEngineLoop = pclSelectedNode -> m_fn_pclGetEngineLoopParentNode ();
	
			g_pclInterface -> m_clDocument . m_pclVariableView -> m_fn_vUpdateVariables (pclEngineLoop); 
			// END ROMTEAM Cristi Petrescu 98-06-
		}
	}
	
	*pResult = 0;
}

//***************************************************************************
HBRUSH IAD_TreeControl::CtlColor(CDC* pDC, UINT nCtlColor) 
{
	// TODO: Change any attributes of the DC here
	
	// TODO: Return a non-NULL brush if the parent's handler should not be called
	return HBRUSH(m_pri_clBrush);
	//return NULL;
}

//BEGIN ROMTEAM Cristi Petrescu 98-05-
//***************************************************************************
void IAD_TreeControl::m_fn_vSetViewAI (BOOL bViewAI)
{
	m_bViewAI = bViewAI;
}

//***************************************************************************
void IAD_TreeControl::m_fn_vSetViewReflex (BOOL bViewReflex)
{
	m_bViewReflex = bViewReflex;
}
//END ROMTEAM Cristi Petrescu 98-05-

// BEGIN ROMTEAM Cristi Petrescu 98-08-
void IAD_TreeControl::OnKeydown(NMHDR* pNMHDR, LRESULT* pResult) 
{
	TV_KEYDOWN* pTVKeyDown = (TV_KEYDOWN*)pNMHDR;
	
	switch (pTVKeyDown -> wVKey)
	{
	case VK_F10:
		((IAD_ResultView *) GetParent ()) -> OnButtonNextLine ();

		// and regain the focus, yet is lost afterwards...
		//m_pri_pclTreeControl -> SetFocus ();

		*pResult = 0;
		break;

	default:
		*pResult = 0;
	}
}
// END ROMTEAM Cristi Petrescu 98-08-