// Copyright: (c) by Crytek GmbH
#pragma once

#include "3DRenderer.h"														// C3DRenderer
#include "3DScene.h"															// C3DScene
#include "3DTargetOrientation.h"									// C3DTargetOrientation
#include "RelativeMouseInput.h"										// CRelativeMouseInput
#include "3DLight.h"															// C3DLight
#include "SplashWindow.h"											// CSplashWindow


class CAppView
{
public:

	enum eRenderMode			m_eRenderMode;			//!< the view rendermode (wireframe, textures, polybump, ..)
	C3DScene							m_Scene;						//!< all world objects (left viewport)

	string								m_OBJName;					//!< filename of the object
	bool									m_bObjectSpace;			//!< true=normal texture is in object space, false otherwise

	C3DLight *						m_pLight;						//!< pointer to the light in the scene
	C3DLight *						m_pBackLight;				//!< pointer to the light in the scene
};


// Polybump Previewer application
//
// 05/07/2002 written by Martin Mittring
//

class C3DApplication
{
public:

	//! constructor
	C3DApplication();

	//! destructor
	virtual ~C3DApplication();

	//! initialization
	//! /param inhHWND handle to the output window
	//! /param inhInstance handle to the application instance
	//! /param inszCommandLine command line as null terminated string
	//! /return true=success, false=failed
	bool Init( HWND inhHWND, HINSTANCE inhInstance, const char *inszCommandLine );

	//! deinitialize
	void DeInit();

	//! render the scene
	void Render();

	//! process the mouse movements
	void MouseMessage( DWORD indwButtons, int iniRelX , int iniRelY, int iniRelZ );

	//! reset camera (for both views)
	void Command_ViewCenter();

	//!
	void Command_ResetLighting();

	//! cycle though all the render modes
	//! /param innViewNo 0=first view or single view, 1=second view, 2=both views syncronized
	//! /param inbForward true=forward, false=backward
	void Command_CycleRendermode( DWORD innViewNo, bool inbForward );

	//! show the Input Data dialog
	void Command_InputData();

	//!
	void Command_AboutBox();

	//!
	void Command_ChangeDebugScale( const float infRelative );

	//! call the window message loop and do idle updates
	void RunMessageLoop();

	//!
	bool IsAppQuiting();

	//! reload the left and the right object
	void ReloadObjects();
	
	//!
	CAppView &GetLeftView();

	//!
	CAppView &GetRightView();

	//!
	void Command_ChooseAmbientColor();

	//!
	void Command_ChooseMainLightColor();

	//!
	void Command_ChooseBackLightColor();

	CRelativeMouseInput		m_RelMouse;						//!< for relative mouse movement

	// attributes ********************************************************************************

	//! get attribute
	bool GetSecondViewOnOff() const;

	//! set attribute
	void SetSecondViewOnOff( const bool inbValue );

	//! get attribute
	bool GetForceDirLights() const;

	//! set attribute
	void SetForceDirLights( const bool inbValue );

	//! get attribute
	bool GetVertexBaseVectorDisplay() const;

	//! set attribute
	void SetVertexBaseVectorDisplay( const bool inbValue );

	//! get attribute
	bool GetTriBaseVectorDisplay() const;

	//! set attribute
	void SetTriBaseVectorDisplay( const bool inbValue );

	//! get attribute
	bool GetNormalVectorDisplay() const;

	//! set attribute
	void SetNormalVectorDisplay( const bool inbValue );


	// ********************************************************************************


private:

	C3DRenderer						m_Renderer;						//!< renderer
	CSplashWindow					m_SplashWindow;				//!< splashwindow

	CAppView							m_View[2];						//!< [0] ist left or single, [1] is right side

	bool									m_bSplitWindowMode;		//!< are we using the splitwindow mode

	C3DTargetOrientation	m_Camera;							//!< camera for both scenes

	string								m_sExeFilePath;				//!< filepath of the exe file (for exe local files)
	HINSTANCE							m_hAppInstance;				//!< application instance handle
	HACCEL								m_hAccel;							//!< accelerators (shortcut system)
	bool									m_bAppQuiting;				//!< true=the application is about to quit, false otherwise
	bool									m_bLightInitalized;		//!< 

	HWND									m_hInputDataDialog;		//!< to open only one of it


	bool ChooseOBJFilename( string &inoutFilename ) const;

	//! open the ChooseColor dialog (choose RGB, no Alpha)
	//! /param inoutOldColor color value to be modified
	//! /return true=OK was pressed, false=user canceled the operation
	bool ChooseRGBColor( D3DXCOLOR &inoutOldColor );

	//! /param outvMid
	//! /return radius
	float GetBoundingSphere( D3DXVECTOR3 &outvMid ) const;

	void CreateLights();

	friend LRESULT CALLBACK MsgProc( HWND hwnd,	UINT uMsg, WPARAM wParam, LPARAM lParam );
	friend BOOL CALLBACK WndProcPreferencesDialog( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam );
};
