#ifndef _RUNEDEV_H
#define _RUNEDEV_H

#define _WIN32_WINNT 0x0500
#define _WIN32_WINDOWS 0x0400

#define WIN32_LEAN_AND_MEAN

#define SAFE_DELETE(p)			if (p) { delete p; p=NULL; }

#include <windows.h>
#include <tchar.h>
//#include <mmsystem.h>
#include <map>
#include <list>

#include "../ErrorList/errorlist.h"						// 錯誤輸出
#include "../rge/Rune/Rune.h"							// 3D引擎
#include "../rge/DirectInput/directinput.h"				// 輸入裝置
#include "../sprite/sprite.h"							// 角色,特效
#include "../interface/interface.h"						// 界面

//#pragma comment (lib, "winmm")

// **********************************************************************************************
// Globals
class	CRuneDev;

extern	CRuneDev							*g_pRuneDev;

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

using namespace std;

typedef map<DWORD, CRoleSprite*>						RoleIndex;
typedef list< pair<RoleIndex::iterator, float> >		RoleGarbage;

class CRuneDev
{
public:
	CRuneDev();
	virtual ~CRuneDev();

	bool					RuneDevInitialize( HINSTANCE hInstance, int screenWidth, int screenHeight, bool isWindowed );
	void					RuneDevRelease();
	bool					SetScreenSize( DWORD width, DWORD height, bool isWindowed );
	bool					AdjustWindowSize( DWORD width, DWORD height );
	void					SetResourcePath( const char* pathStr );
	const char*				GetFullFilePath( const char* fileStr );
	int						Run();
	float					GetFramerate()								{ return m_fps; }

	// Fog
	void					SetFogDistance( float fmin, float fmax );

	// Glow
	void					SetGlow( bool isEnable )					{ m_isGlow = isEnable; }
	bool					IsGlow()									{ return m_isGlow; }

	// Camere
	void					DefaultCamera();
	CRuCamera*				GetCamera()									{ return m_pCamera; }
	CRuController_Camera*	GetCameraController()						{ return m_pRuCameraController; }
	float					GetCameraNearPlane()						{ return m_cameraNearPlane; }
	float					GetCameraFarPlane()							{ return m_cameraFarPlane; }
	float					GetCameraFOV()								{ return m_cameraFOV; }
	void					SetCameraFarPlane( float farPlane );
	void					SetCameraPos( CRuVector3& pos );
	void					MoveCameraPos( CRuVector3& pos );	

	// 游標
	void					SetCursorIcon( const char* fileName );
	void					SetDragCursorIcon( const char* fileName );
	void					ClearCursorIcon();
	void					ClearDragCursorIcon();
	void					RenderCursor();
	void					SetCursorVisible( bool isVisible )			{ m_isCursorVisible = isVisible; }
	bool					IsCursorVisible()							{ return m_isCursorVisible; }
	CTextureImage*			GetCursorImage()							{ return m_pCursorIcon; }
	CTextureImage*			GetDragCursorImage()						{ return m_pDragCursorIcon; }

	// 
	void					SetShowFps( bool isShow )					{ m_isShowFps = isShow; }

	// 地表
	void					ReleaseTerrain();
	bool					LoadTerrain( const char* resourceName );
	void					UpdateTerrain();
	void					RenderTerrain();
	bool					ChangeScreenPoint(int x, int y, CRuVector3& pos);
	void					SetTerrainDetailLevel(int level);

	// 取得地表
	CRuFusion_Minimap*		GetFusionMinimap()							{ return m_pRuMinimap; }

	// 環境
	void					ReleaseEnvironment();
	void					InitialEnvironment();
	void					UpdateEnvironment( CRuVector3& pos );
	void					RenderEnvironment();
	void					SetEnvironmentEnable()						{ m_isEnvironmentUpdate = true; }
	void					SetEnvironmentDisable()						{ m_isEnvironmentUpdate = false; }
	void					SetEnvironmentShow()						{ m_isEnvironmentRender = true; }
	void					SetEnvironmentHide()						{ m_isEnvironmentRender = false; }

	// 界面
	void					UpdateInterface();
	CInterface*				GetInterface()									{ return m_interface; }
	bool					SetMiniMapMask( const char* cszFile );

	// 角色
	void					SetSpriteVisible( bool isVisible )				{ m_isSprite_Render = isVisible; }
	bool					IsSpriteVisible()								{ return m_isSprite_Render; }
	void					SetSpriteEnable( bool isEnable )				{ m_isSprite_Update = isEnable; }
	bool					IsSpriteEnable()								{ return m_isSprite_Update; }
	CRoleSprite*			CreateRoleSprite( int ID, int lastID );
	CRoleSprite*			FindRoleSprite( int ID );
	void					DeleteRoleSprite( int ID );
	void					ClearRoleSprite();
	CRoleSprite*			GetTopRoleSprite( int x, int y, int exclude=-1 );	
	void					SetHighlightSprite( CRoleSprite* sprite );
	void					ResetRoleSpriteWidget();
	const RoleIndex*		GetRoleMap()									{ return &m_roleIndex; }
	virtual void			SendCreateRoleSprite( CRoleSprite* pRoleSprite ) {}
	virtual void			SendDeleteRoleSprite( CRoleSprite* pRoleSprite ) {}
protected:	
	//CRoleSprite*			RecycleRoleSprite( int ID );
	void					UpdateRoleSprite();
	void					RenderSprite();

public:	
	void					Exit()										{ m_isExit = TRUE; }
	HWND					GetWnd()									{ return m_hFrameWnd; }
	bool					IsWindowed()								{ return m_isWindowed; }
	float					GetElapsedTime()							{ return m_elapsedTime; }
	float					GetFrameTime()								{ return m_frameTime; }
	TCHAR*					GetResourceRootDir()						{ return m_resourceRootDirectoryStr; }	
	RECT					GetBoundsRect()								{ return m_clientRect; }
	int						GetScreenWidth()							{ return m_xScreen; }
	int						GetScreenHeight()							{ return m_yScreen; }
	void					LockCursorPos()								{ m_isCursorLock = true; }
	void					UnlockCursorPos()							{ m_isCursorLock = false; }
	void					SetStableFrame(bool isStable)				{ m_isStableFrame = isStable; }
	bool					GetStableFrame()							{ return m_isStableFrame; }
	
	IRuSwapChain*			GetRuSwapChain()							{ return m_pRuSwapChain; }	
	CRuPerformanceTimer*	GetRuTimer()								{ return m_pRuTimer; }

	void					SetPlayerAnchor( CRuVector3& pos )			{ m_playerPos = pos; }

	void					CreateWidgetGrid(CRuVector3 pos, bool isLock, float halfSize, float spacing);
	void					ReleaseWidgetGrid();

	virtual void			Init()										{}
	virtual void			Release()									{}	
	virtual void			Update();
	virtual LRESULT			WndProc( HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam );

	// 格線測試用
	CRuEntity_Widget_Grid*	m_pRuWidgetGrid;
	CRuVector3				m_gridPos;
	bool					m_isGridLock;
	float					m_gridHalfSize;
	float					m_gridSpacing;

protected:	
	bool					CreateWnd( HINSTANCE hInstance, int screenWidth, int screenHeight );
	bool					AdjustWindowForChange();	
	bool					FrameLoop();

protected:

	HINSTANCE				m_hInstance;
	HWND					m_hFrameWnd;
	bool					m_isWindowed;
	bool					m_isExit;
	bool					m_isActived;
	bool					m_isStableFrame;
	DWORD					m_windowStyle;
	RECT					m_clientRect;
	RECT					m_windowRect;
	DWORD					m_xScreen;
	DWORD					m_yScreen;	
	float					m_frameTime;
	float					m_elapsedTime;
	float					m_fps;	
	TCHAR					m_resourceRootDirectoryStr[MAX_PATH];
	bool					m_isHardwaveCursor;
	int						m_xCursor, m_yCursor;
	bool					m_isCursorVisible;
	int						m_isCursorLock;
	bool					m_isRuneRelease;

	CRuFusion_AudioLibrary*	m_pRuAudioLibrary;
	IRuSwapChain*			m_pRuSwapChain;
	CRuPerformanceTimer*	m_pRuTimer;
	CRuCamera*				m_pCamera;
	CRuEntity_Environment*	m_pRuWorldEnvironment;
	IRuTexture*				m_pBlurTexture1;
	IRuTexture*				m_pBlurTexture2;
	CRuOptimalTerrain*		m_pRuTerrain;
	CRuFusion_Minimap*		m_pRuMinimap;
	CRuGaia_Base*			m_pRuGaiaObject;
	CRuController_Camera*	m_pRuCameraController;
	CInputCOM*				m_pInputCOM;
	CInputDevice*			m_pKeyboard;
	CInputDevice*			m_pMouse;
	CTextureImage*			m_pCursorIcon;
	CTextureImage*			m_pDragCursorIcon;
	CRuFontType*			m_pSysFontType;	

	// 界面
	CInterface*				m_interface;
	float					m_UIWidth;
	float					m_UIHeight;

	// 角色
	CRuController_Highlighter*	m_pRuHighlighter;
	RoleIndex				m_roleIndex;
	RoleGarbage				m_roleGarbage;	
	CRuVector3				m_playerPos;	

	// 攝影機控制
	bool					m_isCameraFollowRole;			// 攝影機是否自動跟隨角色移動
	float					m_cameraNearPlane;
	float					m_cameraFarPlane;
	float					m_cameraFOV;
	float					m_cameraBackdropNearPlane;		// 鏡頭背景近距
	float					m_cameraBackdropFarPlane;		// 鏡頭背景遠距

	bool					m_isSprite_Render;
	bool					m_isSprite_Update;
	bool					m_isShowFps;
	bool					m_isGlow;
	bool					m_isEnvironmentUpdate;
	bool					m_isEnvironmentRender;

	float					m_fogMin;
	float					m_fogMax;

	// Memory tracking
	INT32					m_memoryBookmark;
};

#endif //_RUNEDEV_H

