// RenderedViewWnd.cpp : implementation file
//

#include "stdafx.h"
#include "RenderedViewWnd.h"

#include <ElementRenderer\ElementRenderer.hpp>
#include <ElementRenderer\GroupElement.hpp>
#include <ElementRenderer\ListElement.hpp>
#include <ElementRenderer\StateChange.hpp>
#include <ElementRenderer\CameraElement.hpp>
#include <ElementRenderer\SwitchElement.hpp>
#include <ElementRenderer\ShapeElement.hpp>
#include <gosFX\gosFX.hpp>
#include <MLR\MLR.hpp>
#include <MLR\MLRHeaders.hpp>
#include <MFCPlatform\MFCPlatform.hpp>
#include"TctHeightField.h"

#include"Tctb.h"
extern CTCTbApp theApp;

extern DWORD RunGameOSLogic();


//extern CTCTbApp theApp;

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

/////////////////////////////////////////////////////////////////////////////
// CRenderedViewWnd

//IMPLEMENT_DYNCREATE(CRenderedViewWnd, CMDIChildWnd)
extern bool gActive;
extern bool gGotFocus;

CRenderedViewWnd::CRenderedViewWnd()
{
	texture = NULL;
	Scene = NULL;
	ActiveHField = NULL;
	Camera = NULL;
	Camera_State  =NULL;
	OverLayMapLoaded = false;
}

CRenderedViewWnd::~CRenderedViewWnd()
{


}


BEGIN_MESSAGE_MAP(CRenderedViewWnd, CMDIChildWnd)
//{{AFX_MSG_MAP(CRenderedViewWnd)
ON_WM_CLOSE()
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CRenderedViewWnd message handlers

void CRenderedViewWnd::OnClose() 
{
	//ShowWindow(SW_MINIMIZE);
	ShowWindow(SW_HIDE);
	//Don't Let it close	
	//CMDIChildWnd::OnClose();
}


LRESULT CRenderedViewWnd::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
	if(Camera_State!=NULL)
	{
		
		switch(message)
		{
		case WM_ACTIVATE: 
		case WM_CHILDACTIVATE : 
		case WM_MDIACTIVATE:  
			gActive = true;
			gGotFocus= true;
			
		case WM_MDICASCADE:  
		case WM_MDICREATE:  
		case WM_MDIDESTROY:  
		case WM_MDIGETACTIVE: 
		case WM_MDIICONARRANGE:  
		case WM_MDIMAXIMIZE:  
		case WM_MDINEXT:  
		case WM_MDIREFRESHMENU:  
		case WM_MDIRESTORE: 
		case WM_MDISETMENU:  
		case WM_MDITILE:   
		case WM_CLOSE:
			return CMDIChildWnd::WindowProc(message, wParam, lParam);
			break;
		}
		
		
		return GameOSWinProc(m_hWnd, message, wParam, lParam);
		
	}
	
	return CMDIChildWnd::WindowProc(message, wParam, lParam);
}

void CRenderedViewWnd::Fix3DView()
{
	//Fake a WM_MOVE to cause GOS to interogate the window
	GameOSWinProc(m_hWnd, WM_MOVE, NULL, NULL);
}

void CRenderedViewWnd::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
	//	Fix3DView();
	//	if(RunGameOSLogic()) PostQuitMessage(0);
	
	// Do not call CMDIChildWnd::OnPaint() for painting messages
}

void CRenderedViewWnd::PostGOSInit()
{
	//
	//------------------------
	// Set up the texture pool
	//------------------------
	//
#ifdef _DEBUG
#undef new 
#endif
	
	pool = new TGAFilePool(theApp.TexturePath);
	Register_Object(pool);
	MLRTexturePool::Instance = new MLRTexturePool(pool);
	Check_Object(MLRTexturePool::Instance);
	Register_Object(MLRTexturePool::Instance);

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
	
	/*	
	texture = MLRTexturePool::Instance->Add("Grass");
	Check_Object(texture);
	state.SetTexture(texture->GetTextureHandle());
	state.SetRenderDeltaMask(MLRState::TextureMask);
	state.SetZBufferCompareOn();
	state.SetZBufferWriteOn();
	state.SetFilterMode(MLRState::TriLinearFilterMode);
	state.SetPriority(MLRState::DefaultPriority);
	
	  state2 = state;
	  state2.SetZBufferWriteOff();
	  state2.SetAlphaMode(MLRState::OneOneMode);
	  state2.SetPriority(MLRState::DefaultPriority + 1);
	*/	
	//
	//-------------------------------------------------------------------
	// Build the scene root and a shifting node for testing element types
	//-------------------------------------------------------------------
	//
#ifdef _DEBUG
#undef new 
#endif
	
	Scene = new ElementRenderer::ListElement;
	Register_Object(Scene);
	Scene->SetSize(2);
	Scene->SetName("Scene");
	LinearMatrix4D matrix=LinearMatrix4D::Identity;
	matrix.BuildTranslation(Point3D(0.0f, 0.0f, 0.0f));
	Scene->SetLocalToParent(matrix);
	
	//
	//---------------
	// Build a camera
	//---------------
	//
	Camera_State = new ElementRenderer::StateChange();
	Register_Object(Camera_State);
	Camera_State->EnableBackfaceCulling();
	Camera_State->EnableDithering();
	Camera_State->EnablePerspectiveCorrection();
	Camera_State->EnableZBufferWrite();
	Camera_State->EnableZBufferCompare();
	Camera_State->DisableFog();
	Camera_State->SetFog(RGBAColor(0.3f, 0.3f, 0.3f, 1.0f),0.0,300.0,350.0);
	//	Camera_State->OverrideFogStart(100.0f);
	//	Camera_State->OverrideFogEnd(350.0f);
	Camera = new ElementRenderer::CameraElement(Camera_State);
	Register_Object(Camera);
	Scene->AttachIndexedChild(1, Camera);
	Camera->SetPerspective(1.0f, 350.0f, Pi_Over_3);
	Camera->SetScene(Scene);
	LinearMatrix4D origin;
	origin.BuildRotation(EulerAngles(0.0f,0.0f,0.0f));
	Camera->SetLocalToParent(origin);

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
	
	
	if(ActiveHField) delete ActiveHField;
	ActiveHField=new TCTHeightField;
	ActiveHField->Attach(Scene,0);
	
	Scene->Sync();
	
	
}

void CRenderedViewWnd::UpdateCamera(CameraInfo &CamInfo)
{
	LinearMatrix4D origin = LinearMatrix4D::Identity;
	Stuff::Point3D p3d;
	Stuff::Vector3D v3d;
	
	CamInfo.UpdateCPos();
	
	if(CamInfo.TarATrkFlg)
	{
		CamInfo.TargetLoc.y=ActiveHField->GetHeight(CamInfo.TargetLoc.x,CamInfo.TargetLoc.z)+CamInfo.TarTrackAlt;
		CamInfo.UpdateCPos();
	}
	
	if(CamInfo.CamATrkFlg)
		CamInfo.Loc.y=ActiveHField->GetHeight(CamInfo.Loc.x,CamInfo.Loc.z)+CamInfo.CamTrackAlt;
	
	
	p3d=CamInfo.Loc;
	v3d=CamInfo.Dir;
	
	// Set the camera matrix
	Stuff::Scalar yaw,pitch;
	
	if(v3d.z==0) 
	{
		if(v3d.x>=0) yaw=0; else yaw=Stuff::Pi;
	}
	else
	{
		yaw=(float)atan(v3d.x/v3d.z); 
		if(v3d.z<0.0f) yaw+=Stuff::Pi;
	}
	
	pitch=(float)asin(-v3d.y);
	
	origin.BuildRotation(EulerAngles(pitch,yaw,0.0f));
	origin.BuildTranslation(Point3D(p3d.x,p3d.y,p3d.z));
	
	Camera->SetPerspective(CamInfo.NearClip,CamInfo.FarClip,CamInfo.FOV);
	Camera->SetLocalToParent(origin);
	*Camera_State=CamInfo.State;
	Scene->Sync();
	
}

void CRenderedViewWnd::ReDraw(CameraInfo &CamInfo)
{
	gActive = true;
	gGotFocus= true;
	
	UpdateCamera(CamInfo);
	if(Camera) Camera->DrawScene();
}



void CRenderedViewWnd::UpdateHField(TCTHeightField &tdat)
{
	if(ActiveHField) ActiveHField->Clone(tdat);
	ActiveHField->SetState(theApp.TData.BaseTexture.State,0);
	ActiveHField->SetState(theApp.TData.DetailTexture.State,1);
	
	//if(RunGameOSLogic()) PostQuitMessage(0);
}





void CRenderedViewWnd::PreGosCleanUp()
{
	if(ActiveHField)
	{
		delete ActiveHField;
		ActiveHField=NULL;
	}

	if(Scene)
	{
	Unregister_Object(Scene);
	delete Scene;
	}

	Camera_State=NULL;

}
