// MainFrm.cpp : implementation of the CMainFrame class
//

#include "stdafx.h"
#include "PixelWhipPro.h"

#include "MainFrm.h"
#include "PixelWhipPro.h"
#include "View3DChildWindow.h"
#include "EffectListWin.h"
#include "PP2KEffectLibrary.hpp"
#include "ScaleOpt.h"
#include <MFCPlatform\MFCPlatform.hpp>
#include <MLR\MLRHeaders.hpp>
#include <GosFx\GosFx.hpp>
#include <ElementRenderer\ElementRenderer.hpp>
#include "EffectEditWin.h"
#include "CurveEditorFrame.h"


extern CPixelWhipProApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CMainFrame

IMPLEMENT_DYNAMIC(CMainFrame, CMDIFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CMDIFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_WM_CLOSE()
ON_WM_SIZE()
ON_WM_MOVE()
ON_COMMAND(ID_FILE_LOADEFFECT, OnFileLoadeffect)
ON_COMMAND(ID_FILE_SAVEEFFECT, OnFileSaveeffect)
ON_COMMAND(ID_FILE_QUICKSAVE, OnFileQuicksave)
ON_UPDATE_COMMAND_UI(ID_FILE_QUICKSAVE, OnUpdateFileQuicksave)
ON_COMMAND(ID_EDIT_NEWEFFECT_CARDCLOUD, OnEditNeweffectCardcloud)
ON_COMMAND(ID_EDIT_NEWEFFECT_PERTCLOUD, OnEditNeweffectPertcloud)
ON_COMMAND(ID_EDIT_NEWEFFECT_POINTCLOUD, OnEditNeweffectPointcloud)
ON_COMMAND(ID_EDIT_NEWEFFECT_SHAPECLOUD, OnEditNeweffectShapecloud)
ON_COMMAND(ID_EDIT_NEWEFFECT_SHARDCLOUD, OnEditNeweffectShardcloud)
ON_COMMAND(ID_FILE_NEW, OnFileNew)
ON_UPDATE_COMMAND_UI(ID_FILE_NEW, OnUpdateFileNew)
ON_COMMAND(ID_EDIT_DELETEEFFECT, OnEditDeleteeffect)
ON_COMMAND(ID_EDIT_NEWEFFECT_SINGLETON_CARD, OnEditNeweffectSingletonCard)
ON_COMMAND(ID_EDIT_NEWEFFECT_SINGLETON_SHAPE, OnEditNeweffectSingletonShape)
ON_COMMAND(ID_EDIT_NEWEFFECT_EFFECTCLOUD, OnEditNeweffectEffectcloud)
ON_COMMAND(ID_FILE_LOADLASTLIBRARY, OnFileLoadlastlibrary)
ON_COMMAND(ID_EDIT_NEWEFFECT_NULLEFFECT, OnEditNeweffectNulleffect)
ON_COMMAND(ID_EDIT_NEWEFFECT_TUBE, OnEditNeweffectTube)
ON_COMMAND(ID_EDIT_NEWEFFECT_DEBRISCLOUD, OnEditNeweffectDebriscloud)
ON_COMMAND(ID_EDIT_NEWEFFECT_POINTLIGHT, OnEditNeweffectPointlight)
ON_COMMAND(ID_FILE_IMPORT, OnFileImport)
ON_COMMAND(ID_EDIT_NEWEFFECT_BEAM, OnEditNeweffectBeam)
ON_COMMAND(ID_EDIT_NEWEFFECT_SINGLETON_FLARE, OnEditNeweffectSingletonFlare)
ON_COMMAND(ID_EDIT_NEWEFFECT_CLOUDS_SPRITECLOUD, OnEditNeweffectCloudsSpritecloud)
ON_WM_TIMER()
ON_COMMAND(ID_FILE_EXPORTCURRENTEFFECT, OnFileExportcurrenteffect)
ON_COMMAND(ID_EDIT_SCALEEFFECT, OnEditScaleeffect)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

static UINT indicators[] =
{
	ID_SEPARATOR,           // status line indicator
		ID_INDICATOR_CAPS,
		ID_INDICATOR_NUM,
		ID_INDICATOR_SCRL,
};

/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction

CMainFrame::CMainFrame()
{
	theApp.DocTitle="Untitled.effects";	
	theApp.DocPath="";
}

CMainFrame::~CMainFrame()
{
}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CMDIFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
		| CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
		!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
	{
		TRACE0("Failed to create toolbar\n");
		return -1;      // fail to create
	}
	
	if (!m_wndStatusBar.Create(this) ||
		!m_wndStatusBar.SetIndicators(indicators,
		sizeof(indicators)/sizeof(UINT)))
	{
		TRACE0("Failed to create status bar\n");
		return -1;      // fail to create
	}
	
	// TODO: Delete these three lines if you don't want the toolbar to
	//  be dockable
	m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
	EnableDocking(CBRS_ALIGN_ANY);
	DockControlBar(&m_wndToolBar);
	SetTimer(1,500,NULL);
	
	return 0;
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
	if( !CMDIFrameWnd::PreCreateWindow(cs) )
		return FALSE;
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs
	
	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics

#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
	CMDIFrameWnd::AssertValid();
}

void CMainFrame::Dump(CDumpContext& dc) const
{
	CMDIFrameWnd::Dump(dc);
}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMainFrame message handlers


void CMainFrame::OnClose() 
{
	int res=IDYES;
	if(theApp.Modified)
	{
		res=MessageBox("Unsaved Data... Do you really want to Quit?","Quit Confirmation",MB_YESNO);
	}
	
	if(res==IDYES)
	{
		theApp.SaveWindowStates();
		theApp.GOSCleanUp();
		PostQuitMessage(0);
		//		CMDIFrameWnd::OnClose();
	}
}

void CMainFrame::OnSize(UINT nType, int cx, int cy) 
{
	CMDIFrameWnd::OnSize(nType, cx, cy);
	
	if(theApp.GOSActive)
		theApp.Window3D->Fix3DView();	
}

void CMainFrame::OnMove(int x, int y) 
{
	CMDIFrameWnd::OnMove(x, y);
	
	if(theApp.GOSActive)
		theApp.Window3D->Fix3DView();	
}


void CMainFrame::OnFileLoadeffect() 
{
	int res=IDYES;
	if(theApp.Modified)
	{
		res=MessageBox("Unsaved Data... Do you really want to Load?","Quit Confirmation",MB_YESNO);
	}
	
	if(res!=IDYES) return;
	
	CFileDialog dlg1(TRUE,"effects",NULL,NULL,"Effects (*.effects)|*.effects||",this);
	if(dlg1.DoModal()==IDOK)
	{
		LoadEffect(dlg1.GetPathName());
	}
	
}

void CMainFrame::OnFileSaveeffect() 
{
	CFileDialog dlg1(FALSE,"effects",theApp.DocTitle,NULL,"Effects (*.effects)|*.effects||",this);
	if(dlg1.DoModal()==IDOK)
	{
		theApp.DocPath=dlg1.GetPathName();
		theApp.DocTitle=dlg1.GetFileName();
		theApp.WriteProfileString("PixelPro2000","LastLib",theApp.DocPath);
		OnFileQuicksave();
	}	
}

void CMainFrame::OnFileQuicksave() 
{
	theApp.EListWin->m_EffectList.MakeAllNamesUnique();
	
	Stuff::FileStream gfx_file(theApp.DocPath, Stuff::FileStream::WriteOnly);
	/*
	if (!gosFX::EffectLibrary::Instance->SortSpecifications())
	{
	// >>> *** one or more events lost due to circular reference *** <<<
	}
	*/
	theApp.Modified=false;
	gosFX::EffectLibrary::Instance->Save(&gfx_file);
	
}

void CMainFrame::OnUpdateFileQuicksave(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(theApp.DocPath.GetLength()>0);	
}

void CMainFrame::OnEditNeweffectCardcloud() 
{
	theApp.EListWin->m_EffectList.NewCardCloud();
	theApp.RefreshAllWins();
	theApp.Modified=true;
}


void CMainFrame::OnEditNeweffectPertcloud() 
{
	theApp.EListWin->m_EffectList.NewPertcloud();
	theApp.RefreshAllWins();
	theApp.Modified=true;
}

void CMainFrame::OnEditNeweffectPointcloud() 
{
	theApp.EListWin->m_EffectList.NewPointCloud();
	theApp.RefreshAllWins();
	theApp.Modified=true;
}

void CMainFrame::OnEditNeweffectShapecloud() 
{
	theApp.EListWin->m_EffectList.NewShapeCloud();
	theApp.RefreshAllWins();
	theApp.Modified=true;
	
}

void CMainFrame::OnEditNeweffectShardcloud() 
{
	theApp.EListWin->m_EffectList.NewShardCloud();
	theApp.RefreshAllWins();
	theApp.Modified=true;
}


void CMainFrame::OnEditNeweffectSingletonCard() 
{
	theApp.EListWin->m_EffectList.NewSingletonCard();
	theApp.RefreshAllWins();
	theApp.Modified=true;
	
}

void CMainFrame::OnEditNeweffectSingletonShape() 
{
	theApp.EListWin->m_EffectList.NewSingletonShape();
	theApp.RefreshAllWins();
	theApp.Modified=true;
	
}

void CMainFrame::OnEditNeweffectSingletonFlare() 
{
	theApp.EListWin->m_EffectList.NewSingletonFlare();
	theApp.RefreshAllWins();
	theApp.Modified=true;
}


void CMainFrame::OnEditNeweffectEffectcloud() 
{
	
	theApp.EListWin->m_EffectList.NewEffectCloud();
	theApp.RefreshAllWins();
	theApp.Modified=true;
	
}

void CMainFrame::OnEditNeweffectTube() 
{
	theApp.EListWin->m_EffectList.NewTube();
	theApp.RefreshAllWins();
	theApp.Modified=true;
}


void CMainFrame::OnEditNeweffectDebriscloud() 
{
	theApp.EListWin->m_EffectList.NewDebrisCloud();
	theApp.RefreshAllWins();
	theApp.Modified=true;
	
}

void CMainFrame::OnEditNeweffectPointlight() 
{
	theApp.EListWin->m_EffectList.NewPointLight();
	theApp.RefreshAllWins();
	theApp.Modified=true;
	
}

void CMainFrame::OnFileNew() 
{
	int res=IDYES;
	if(theApp.Modified)
	{
		res=MessageBox("Unsaved Data... Do you really want New?","Quit Confirmation",MB_YESNO);
	}
	
	if(res!=IDYES) return;
	
	theApp.StopEffects();
	
	theApp.ClearEffects();
	theApp.DocTitle="Untitled.effects";	
	theApp.DocPath="";
	
	theApp.RefreshAllWins();
	theApp.StartEffects();
}


void CMainFrame::OnUpdateFileNew(CCmdUI* pCmdUI) 
{
}

BOOL CMainFrame::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) 
{
	
	return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
}

void CMainFrame::OnEditDeleteeffect() 
{
	
	theApp.StopEffects();
	theApp.EListWin->m_EffectList.DeleteSelectedEffect();
	theApp.EListWin->Refresh();
	theApp.StartEffects();
	theApp.Modified=true;
	
}


void CMainFrame::OnFileLoadlastlibrary() 
{
	int res=IDYES;
	if(theApp.Modified)
	{
		res=MessageBox("Unsaved Data... Do you really want to Load?","Quit Confirmation",MB_YESNO);
	}
	
	if(res!=IDYES) return;
	
	CString LastLib=theApp.GetProfileString("PixelPro2000","LastLib");
	if(LastLib.GetLength()>0)
		LoadEffect(LastLib);
	
}


void CMainFrame::OnEditNeweffectNulleffect() 
{
	theApp.EListWin->m_EffectList.NewNullEffect();
	theApp.RefreshAllWins();
	theApp.Modified=true;
}

void CMainFrame::LoadEffect(CString &pathname)
{
	CString wdir;
	wdir=pathname.Left(pathname.ReverseFind('\\'));
	SetCurrentDirectory(wdir);

	theApp.StopEffects();
	
	theApp.ClearEffects();
	theApp.DocPath=pathname;
	theApp.DocTitle=pathname.Right(pathname.GetLength()-pathname.ReverseFind('\\'));
	
	theApp.WriteProfileString("PixelPro2000","LastLib",theApp.DocPath);
	
	if(gosFX::EffectLibrary::Instance) 
	{
		Unregister_Object(gosFX::EffectLibrary::Instance);
		delete gosFX::EffectLibrary::Instance;
	}
	
	gos_PushCurrentHeap(gosFX::Heap);
	gosFX::EffectLibrary::Instance = new PP2KEffectLibrary;
	Register_Object(gosFX::EffectLibrary::Instance);
	
	
	//----------------------
	// Read it in from disk
	//----------------------
	if(theApp.fx_stream!=NULL) delete theApp.fx_stream;
	
	Check_Object(Stuff::FileStreamManager::Instance);
	theApp.fx_stream=new Stuff::FileStream((LPCSTR)theApp.DocPath);
	
	gosFX::EffectLibrary::Instance->Load(theApp.fx_stream);
	
	
	gos_PopCurrentHeap();
	theApp.Modified=false;
	
	theApp.RefreshAllWins();
	MidLevelRenderer::MLRTexturePool::Instance->LoadImages();
	theApp.TranslateTextureNames();
	
	
	//Fix Effects if Bad
	int effnum;
	for(effnum=0;effnum<gosFX::EffectLibrary::Instance->m_effects.GetLength();effnum++)
	{
		gosFX::EffectLibrary::Instance->m_effects[effnum]->IsDataValid(true);
	}
	
	theApp.VerifyEffectLib();
	theApp.StartEffects();
	
}



void CMainFrame::OnFileImport() 
{
	CFileDialog dlg1(TRUE,"effects",NULL,NULL,"Effects (*.effects)|*.effects||",this);
	if(dlg1.DoModal()==IDOK)
	{
		ImportEffects(dlg1.GetPathName());
	}
	
	
}

void CMainFrame::ImportEffects(CString &pathname)
{
	theApp.StopEffects();
	
	
	Verify(gosFX::EffectLibrary::Instance); 
	gos_PushCurrentHeap(gosFX::Heap);
	Check_Object(Stuff::FileStreamManager::Instance);
	Stuff::FileStream *gfx_file=new Stuff::FileStream((LPCSTR)pathname);
	gosFX::EffectLibrary::Instance->Load(gfx_file);
	gos_PopCurrentHeap();
	
	
	theApp.VerifyEffectLib();
	
	
	theApp.Modified=true;
	theApp.RefreshAllWins();
	MidLevelRenderer::MLRTexturePool::Instance->LoadImages();
	
	
	theApp.StartEffects();
	
}

void CMainFrame::OnEditNeweffectBeam() 
{
	theApp.EListWin->m_EffectList.NewBeam();
	theApp.RefreshAllWins();
	theApp.Modified=true;
	
}


void CMainFrame::OnEditNeweffectCloudsSpritecloud() 
{
	theApp.EListWin->m_EffectList.NewSpriteCloud();
	theApp.RefreshAllWins();
	theApp.Modified=true;
}

void CMainFrame::OnTimer(UINT nIDEvent) 
{
	if(theApp.EListWin)
		theApp.EListWin->m_EffectList.UpdatePlayIcons();
	
	CMDIFrameWnd::OnTimer(nIDEvent);
}

void CMainFrame::OnFileExportcurrenteffect() 
{
	CFileDialog dlg1(FALSE,"effects","export.effects",NULL,"Effects (*.effects)|*.effects||",this);
	
	gos_PushCurrentHeap(gosFX::Heap);
	
	if(dlg1.DoModal()==IDOK)
	{
		gosFX::EffectLibrary *templib=new PP2KEffectLibrary;
		
		theApp.EListWin->m_EffectList.MakeAllNamesUnique();
		theApp.EListWin->m_EffectList.CopySelectedIntoLib(templib);
		
		Stuff::FileStream gfx_file((char *)(LPCSTR)dlg1.GetPathName(), Stuff::FileStream::WriteOnly);
		templib->Save(&gfx_file);
		templib->m_effects.SetLength(0);	
		delete templib;
	}
	
	gos_PopCurrentHeap();
	
}

void CMainFrame::OnEditScaleeffect() 
{
	CScaleOpt dlg;
	
	if(dlg.DoModal()==IDOK)
	{
		if(dlg.ScaleAll)
		{
			theApp.EListWin->m_EffectList.ScaleAllEffects(dlg.m_SFact,dlg.Brightness);
		}
		else
		{
			theApp.EListWin->m_EffectList.ScaleSelectedEffect(dlg.m_SFact,dlg.m_Recurse?true:false,dlg.Brightness);
		}
		
	if(theApp.ParamWin) theApp.ParamWin->Refresh();
	if(theApp.CurveWin) theApp.CurveWin->m_wndView.Refresh();
	}
	
}
