// EffectListWin.cpp : implementation file
//

#include "stdafx.h"
#include "PixelWhipPro.h"
#include "EffectListWin.h"
#include "EffectEditWin.h"
#include "EventProps.h"
#include <ElementRenderer\ElementRenderer.hpp>
#include <ElementRenderer\gosFXElement.hpp>
#include <GosFx\GosFx.hpp>
#include <GosFx\EffectCloud.hpp>




extern ElementRenderer::gosFXElement *EffectWrapper;
extern gosFX::Effect *CurrentEffect;
extern ElementRenderer::GroupElement *Scene;

/////////////////////////////////////////////////////////////////////////////
// CEffectListWin dialog
extern CPixelWhipProApp theApp;


CEffectListWin::CEffectListWin(CWnd* pParent /*=NULL*/)
: CDialog(CEffectListWin::IDD, pParent)
{
	//{{AFX_DATA_INIT(CEffectListWin)
	// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
 AllowRedraw=0;
Initalized=false;
}


void CEffectListWin::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CEffectListWin)
	DDX_Control(pDX, IDC_EFFECTLIST, m_EffectList);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CEffectListWin, CDialog)
//{{AFX_MSG_MAP(CEffectListWin)
ON_WM_CLOSE()
ON_NOTIFY(TVN_SELCHANGED, IDC_EFFECTLIST, OnSelchangedEffectlist)
ON_NOTIFY(TVN_ENDLABELEDIT, IDC_EFFECTLIST, OnEndlabeleditEffectlist)
ON_NOTIFY(NM_DBLCLK, IDC_EFFECTLIST, OnDblclkEffectlist)
	ON_WM_SIZE()
	ON_WM_CHAR()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CEffectListWin message handlers

void CEffectListWin::OnCancel() 
{
	
	//	CDialog::OnCancel();
}

void CEffectListWin::OnOK() 
{

	//	CDialog::OnOK();
}

void CEffectListWin::OnClose() 
{
	ShowWindow(SW_HIDE);
	
	//	CDialog::OnClose();
}


void CEffectListWin::Refresh()
{
 AllowRedraw++;
	theApp.FixEffectNameTable();

	int effnum;
	HTREEITEM CurItem=TVI_ROOT,LastItem=TVI_ROOT;
	m_EffectList.DeleteAllItems();
	gos_PushCurrentHeap(gosFX::Heap);
	gosFX::Effect::Specification **speclist=new gosFX::Effect::Specification *[gosFX::EffectLibrary::Instance->m_effects.GetLength()]; 
	gos_PopCurrentHeap();
	
	for(effnum=0;effnum<gosFX::EffectLibrary::Instance->m_effects.GetLength();effnum++)
	{
		speclist[effnum]= gosFX::EffectLibrary::Instance->m_effects[effnum];
	}
	
	
	for(effnum=0;effnum<gosFX::EffectLibrary::Instance->m_effects.GetLength();effnum++)
	{
		DeleteChildrenFromList(speclist[effnum],speclist);
	}
	
	
	for(effnum=0;effnum<gosFX::EffectLibrary::Instance->m_effects.GetLength();effnum++)
	{
		if(speclist[effnum]!=NULL)
		{
			LastItem=m_EffectList.InsertItem(speclist[effnum]->m_name,0,0,CurItem,LastItem);
			m_EffectList.SetItemData(LastItem,(DWORD)speclist[effnum]);
			AddEventToList(LastItem);
		}
	}
 AllowRedraw--;
m_EffectList.ClearPlayIcons();
	theApp.StopEffects();
	theApp.StartEffects();
	theApp.ParamWin->Refresh();
	
	delete speclist;	
}

void CEffectListWin::DeleteChildrenFromList(gosFX::Effect::Specification *spec,gosFX::Effect::Specification **speclist)
{
	
	if(spec==NULL) return;
	gosFX::Event *event;
	
	Stuff::ChainIteratorOf<gosFX::Event*> eitr(&(spec->m_events));
	
	if(spec->GetClassID()==gosFX::EffectCloudClassID)
	{
		gosFX::EffectCloud__Specification *tspec;
		tspec=Cast_Pointer(gosFX::EffectCloud__Specification *,spec);
		Check_Object(tspec);

		if(tspec->m_particleEffectID!=BADINDEX)
		{
			for(int effnum=0;effnum<gosFX::EffectLibrary::Instance->m_effects.GetLength();effnum++)
			{
				if(speclist[effnum]==gosFX::EffectLibrary::Instance->m_effects[tspec->m_particleEffectID])
					speclist[effnum]=NULL;
			}

			DeleteChildrenFromList(gosFX::EffectLibrary::Instance->m_effects[tspec->m_particleEffectID],speclist);

		}
	}
	else
	{
	
		eitr.First();
		while(NULL!=(event=eitr.ReadAndNext()))
		{
//		int testvar=1;
//		Verify(event->m_effectID!=testvar);
			
			for(int effnum=0;effnum<gosFX::EffectLibrary::Instance->m_effects.GetLength();effnum++)
			{
					if(speclist[effnum] && speclist[effnum]==gosFX::EffectLibrary::Instance->m_effects[event->m_effectID])
						speclist[effnum]=NULL;
			}
			
			DeleteChildrenFromList(gosFX::EffectLibrary::Instance->m_effects[event->m_effectID],speclist);
			
		}
		
	}
}

void CEffectListWin::OnSelchangedEffectlist(NMHDR* pNMHDR, LRESULT* pResult) 
{
if(AllowRedraw) return;
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	
	theApp.StopEffects();
	theApp.StartEffects();
	theApp.ParamWin->Refresh();
	m_EffectList.ClearPlayIcons();
	m_EffectList.UpdatePlayIcons();
	*pResult = 0;
}


void CEffectListWin::AddEventToList(HTREEITEM itm)
{
	if(itm==NULL) return;
	gosFX::Effect::Specification *spec,*nspec;
	gosFX::Event *event;
	spec = (gosFX::Effect::Specification *)m_EffectList.GetItemData(itm);
	HTREEITEM LastItem=TVI_LAST;
	
	Stuff::ChainIteratorOf<gosFX::Event*> eitr(&(spec->m_events));
	
	if(spec->GetClassID()==gosFX::EffectCloudClassID)
	{
		gosFX::EffectCloud__Specification *tspec;
		tspec=Cast_Pointer(gosFX::EffectCloud__Specification *,spec);
		Check_Object(tspec);

		if(tspec->m_particleEffectID!=BADINDEX)
		{
		nspec=gosFX::EffectLibrary::Instance->m_effects[tspec->m_particleEffectID];
		LastItem=m_EffectList.InsertItem(nspec->m_name,0,0,itm,LastItem);
		m_EffectList.SetItemData(LastItem,(DWORD)nspec);
		AddEventToList(LastItem);	
		}
	}
	else
	{
	eitr.First();
	while(NULL!=(event=eitr.ReadAndNext()))
	{
		nspec=gosFX::EffectLibrary::Instance->m_effects[event->m_effectID];
		LastItem=m_EffectList.InsertItem(nspec->m_name,0,0,itm,LastItem);
		m_EffectList.SetItemData(LastItem,(DWORD)nspec);
		AddEventToList(LastItem);	
	}
	}
}



void CEffectListWin::OnEndlabeleditEffectlist(NMHDR* pNMHDR, LRESULT* pResult) 
{
	TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
	// TODO: Add your control notification handler code here
	if(pTVDispInfo->item.pszText)
	{
		gosFX::Effect::Specification *spec;
		spec = (gosFX::Effect::Specification *)m_EffectList.GetItemData(m_EffectList.GetSelectedItem());
		spec->m_name=pTVDispInfo->item.pszText;
		m_EffectList.SetItemText(pTVDispInfo->item.hItem,spec->m_name);
	}
	*pResult = 0;
}

void CEffectListWin::OnDblclkEffectlist(NMHDR* pNMHDR, LRESULT* pResult) 
{
	// TODO: Add your control notification handler code here
	CEventProps propdlg;
	HTREEITEM ParItem,Cursel=m_EffectList.GetSelectedItem();
	ParItem=m_EffectList.GetParentItem(Cursel);
	gosFX::Event *tmpevent;
	
	if(Cursel!=NULL && ParItem!=NULL)
	{
		gosFX::Effect::Specification *spec=(gosFX::Effect::Specification *)m_EffectList.GetItemData(Cursel);
		gosFX::Effect::Specification *parspec=(gosFX::Effect::Specification *)m_EffectList.GetItemData(ParItem);
		Stuff::ChainIteratorOf<gosFX::Event*> eitr(&(parspec->m_events));
		
		eitr.First();
		while(NULL!=(tmpevent=eitr.ReadAndNext()) && tmpevent->m_effectID!=spec->m_effectID);
		ASSERT(tmpevent!=NULL); //Fatal Error
		
		
		propdlg.DoModal(tmpevent);
	}
	*pResult = 0;
}

void CEffectListWin::OnSize(UINT nType, int cx, int cy) 
{
	CDialog::OnSize(nType, cx, cy);
	
	CRect rct;
	GetClientRect(&rct);
	
	if(Initalized)
		m_EffectList.SetWindowPos(NULL,10,10,rct.Width()-20,rct.Height()-20,SWP_NOZORDER);
	
}

BOOL CEffectListWin::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	Initalized=true;
m_EffectList.InitImages();
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CEffectListWin::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default
	switch(nChar)
	{
	case VK_DELETE:
		m_EffectList.DeleteSelectedEffect();
		break;
	}
	CDialog::OnChar(nChar, nRepCnt, nFlags);
}
