// StateTreeView.cpp : implementation file
//

#include "stdafx.h"
#include "AnimScript.h"
#include "StateTreeView.h"
#include "AnimScriptDoc.h"
#include "modifyview.h"
#include "stateparamview.h"

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

/////////////////////////////////////////////////////////////////////////////
// CStateTreeView

IMPLEMENT_DYNCREATE(CStateTreeView, CTreeView)

CStateTreeView::CStateTreeView()
{
}

CStateTreeView::~CStateTreeView()
{
}


BEGIN_MESSAGE_MAP(CStateTreeView, CTreeView)
	//{{AFX_MSG_MAP(CStateTreeView)
	ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged)
	ON_WM_CREATE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CStateTreeView drawing

void CStateTreeView::OnDraw(CDC* pDC)
{
	CDocument* pDoc = GetDocument();
	// TODO: add draw code here
}

/////////////////////////////////////////////////////////////////////////////
// CStateTreeView diagnostics

#ifdef _DEBUG
void CStateTreeView::AssertValid() const
{
	CTreeView::AssertValid();
}

void CStateTreeView::Dump(CDumpContext& dc) const
{
	CTreeView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CStateTreeView message handlers
void CStateTreeView::OnInitialUpdate() 
{
	CTreeView::OnInitialUpdate();
}

void CStateTreeView::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	
	CAnimNode *pNode = (CAnimNode *)this->GetTreeCtrl().GetItemData(this->GetTreeCtrl().GetSelectedItem());
	CAnimScriptDoc* pDoc = (CAnimScriptDoc *)GetDocument();
	pDoc->m_pSelectedNode = pNode;

	GetDocument()->UpdateAllViews(this,NULL,NULL);
	*pResult = 0;
}

BOOL CStateTreeView::PreCreateWindow(CREATESTRUCT& cs) 
{	
	cs.style |= TVS_SHOWSELALWAYS | TVS_HASLINES | TVS_LINESATROOT | TVS_DISABLEDRAGDROP | TVS_FULLROWSELECT | TVS_HASBUTTONS;
	return CTreeView::PreCreateWindow(cs);
}

void CStateTreeView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint) 
{
	if (pSender && pSender->IsKindOf(RUNTIME_CLASS(CModifyView)))
		return;

	if (lHint)
		return;

	CAnimScriptDoc* pDoc = (CAnimScriptDoc *)GetDocument();	
	CTreeCtrl *pCtrl = &this->GetTreeCtrl();
	//Check all of the Animation States
	HTREEITEM hItem = pCtrl->GetRootItem();
	while (hItem)
	{
		CAnimStateNode *pAnimNode = (CAnimStateNode *)this->GetTreeCtrl().GetItemData(hItem);
		if (pAnimNode->m_bValid)
		{
			pCtrl->SetItemState(hItem,TVIS_BOLD,TVIS_BOLD);
		}
		else
		{
			pCtrl->SetItemState(hItem,0,TVIS_BOLD);
		}
		hItem = pCtrl->GetNextItem(hItem, TVGN_NEXT);
	}

	// Check all of the transition states
	POSITION pos = pDoc->m_listTransitions.GetHeadPosition();
	while (pos)
	{
		CObject *pObj = pDoc->m_listTransitions.GetNext(pos);
		CTransStateNode *pTransNode = (CTransStateNode *)pObj;

		bool bAdd = false;
		for (int x=0;x<2;x++)
		{
			CAnimNode *pNode = NULL;
			if (0==x)
				pNode = pTransNode->m_pStartNode;
			else
				pNode = pTransNode->m_pEndNode;
			if (pNode)
			{
			//	if (pNode->m_bValid)
				{
					//pTransNode should be a child of hItem
					// Look for it, and if it's not there then add it.
					bool bFound = false;
					HTREEITEM hChild = pCtrl->GetChildItem(pNode->m_hItem);
					while (hChild)
					{
						CTransStateNode *pNode1 = (CTransStateNode *)pCtrl->GetItemData(hChild);
						if (pNode1&&pNode1->m_bValid)
							pCtrl->SetItemState(hChild,TVIS_BOLD,TVIS_BOLD);
						else
							pCtrl->SetItemState(hChild,0,TVIS_BOLD);
						if (pNode1 == pTransNode)
						{
							bFound = true;
							bool bValidX = pTransNode->m_pStartNode?pTransNode->m_pStartNode->m_bValid:1;
							bool bValidY = pTransNode->m_pEndNode?pTransNode->m_pEndNode->m_bValid:1;
							if (!(bValidX & bValidY))
							{
								if (pNode->m_hItem)
								{
									pCtrl->DeleteItem(hChild);
									CRect rc;
									pCtrl->GetItemRect(pNode->m_hItem,&rc,false);
									pCtrl->InvalidateRect(&rc);
								}
							}
							break;
						}
						hChild = pCtrl->GetNextItem(hChild,TVGN_NEXT);
					}
					/*if (bFound)
					{
						bool bValidX = pTransNode->m_pStartNode?pTransNode->m_pStartNode->m_bValid:1;
						bool bValidY = pTransNode->m_pEndNode?pTransNode->m_pEndNode->m_bValid:1;
						if (!(bValidX & bValidY))
						{
							if (pNode->m_hItem)
							{
								pCtrl->DeleteItem(pTransNode->m_hItem);
								CRect rc;
								pCtrl->GetItemRect(pNode->m_hItem,&rc,false);
								pCtrl->InvalidateRect(&rc);
							}
						}
					}
					else*/
					if (!bFound)
					{
						if (pNode->m_bValid)
						{
							bAdd = true;
							bool bValidX = pTransNode->m_pStartNode?pTransNode->m_pStartNode->m_bValid:1;
							bool bValidY = pTransNode->m_pEndNode?pTransNode->m_pEndNode->m_bValid:1;
							if (bValidX & bValidY)
							{
								// Add pTransNode to pNode (parent)
								hChild = pCtrl->InsertItem(pTransNode->GetName(),pNode->m_hItem);
								pTransNode->m_hItem = hChild;
								pCtrl->SetItemData(hChild,(DWORD)pTransNode);

								// Invalidate the rect so that the "+" and other stuff gets drawn
								CRect rc;
								pCtrl->GetItemRect(hChild,&rc,false);
								pCtrl->InvalidateRect(&rc);

								pCtrl->GetItemRect(pNode->m_hItem,&rc,false);
								pCtrl->InvalidateRect(&rc);
							}
						}
					}
				}
/*				else
				{
					if (pNode->m_hItem)
					{
						pCtrl->DeleteItem(pTransNode->m_hItem);
						CRect rc;
						pCtrl->GetItemRect(pNode->m_hItem,&rc,false);
						pCtrl->InvalidateRect(&rc);
					}
				}*/
			}
		}
	}
}

int CStateTreeView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (CTreeView::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	CTreeCtrl *pCtrl = &this->GetTreeCtrl();
	CAnimScriptDoc* pDoc = (CAnimScriptDoc *)GetDocument();

	POSITION pos = pDoc->m_listStates.GetHeadPosition();
	while (pos)
	{
		CObject *pObj = pDoc->m_listStates.GetNext(pos);
		CAnimStateNode *pNode = (CAnimStateNode *)pObj;

		HTREEITEM hItem = pCtrl->InsertItem(pNode->GetName());
		pNode->m_hItem = hItem;
		pCtrl->SetItemData(hItem,(DWORD)pNode);
	}	
	return 0;
}
