#ifndef __DX8DEVICEC_H__
#define __DX8DEVICEC_H__

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <d3d8.h>

// forward declaration

namespace PajaSystem {
	class DX8DeviceC;
};

#include "PajaTypes.h"
#include "BBox2C.h"
#include "ColorC.h"
#include "Vector2C.h"
#include "DeviceInterfaceI.h"
#include "GraphicsDeviceI.h"
#include "DX8ViewportC.h"
#include "DX8GUIDrawInterfaceC.h"
#include "DeviceFeedbackC.h"


//////////////////////////////////////////////////////////////////////////
//
//  OpenGL Device Driver Class ID
//

namespace PajaSystem {

	const PluginClass::ClassIdC	CLASS_DX8_DEVICEDRIVER = PluginClass::ClassIdC( 0, 20000 );


	class DX8DeviceC : public GraphicsDeviceI
	{
	public:
		static DX8DeviceC*				create_new();
		virtual Edit::DataBlockI*		create();
		virtual PluginClass::ClassIdC	get_class_id() const;
		virtual const char*				get_class_name();
		virtual DeviceInterfaceI*		query_interface( const PluginClass::SuperClassIdC& rSuperClassId );
		virtual PajaTypes::uint32		save( FileIO::SaveC* pSave );
		virtual PajaTypes::uint32		load( FileIO::LoadC* pLoad );

		virtual bool					init( HINSTANCE hInstance, HWND hParent, PajaTypes::int32 i32ID, PajaTypes::uint32 ui32Flags,
											PajaTypes::uint32 ui32Width = 0, PajaTypes::uint32 ui32Height = 0, PajaTypes::uint32 ui32BPP = 0,
											PajaSystem::DeviceFeedbackC* pFeedback = 0 );
		virtual void					destroy();
		virtual void					flush();
		virtual void					activate();
		virtual HWND					get_hwnd();
		virtual bool					configure();

		virtual bool					set_fullscreen( PajaTypes::uint32 ui32Width, PajaTypes::uint32 ui32Height,
														PajaTypes::uint32 ui32BPP = 0 );
		virtual bool					set_windowed();

		virtual void					set_size( PajaTypes::int32 int32X, PajaTypes::int32 int32Y,
														PajaTypes::int32 i32Width, PajaTypes::int32 i32Height );

		// clear device
		virtual void					clear_device( PajaTypes::uint32 ui32Flags, const PajaTypes::ColorC& rColor = PajaTypes::ColorC(),
														PajaTypes::float32 f32Depth = 1.0f, PajaTypes::int32 i32Stencil = 0 );

		virtual void					begin_draw();
		virtual void					end_draw();

		// Pushes current state and prepares to draw effects
		virtual void					begin_effects();
		virtual void					end_effects();

		virtual LPDIRECT3DDEVICE8		get_d3ddevice();

	private:

		DX8DeviceC();
		virtual ~DX8DeviceC();

		static LRESULT CALLBACK	stub_window_proc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );

		void	build_device_list( PajaTypes::uint32 ui32DefaultWidth, PajaTypes::uint32 ui32DefaultHeight, PajaTypes::uint32 ui32DefaultBPP );
		bool	find_depth_stencil_format( UINT iAdapter, D3DDEVTYPE rDeviceType, D3DFORMAT rTargetFormat, D3DFORMAT* pDepthStencilFormat );

		HWND						m_hWnd;
		LPDIRECT3D8					m_pD3D;
		LPDIRECT3DDEVICE8			m_pD3DDevice;
		DWORD						m_dwSavedState;
		D3DPRESENT_PARAMETERS		m_rD3Dpp; 
		D3DPRESENT_PARAMETERS		m_rSavedD3Dpp;

		PajaTypes::uint32			m_ui32CreateFlags;

		DX8ViewportC*				m_pInterface;
		DX8GUIDrawInterfaceC*		m_pGUIDrawInterface;
		DeviceFeedbackC*			m_pFeedback;

		static PajaTypes::int32		m_i32RefCount;
		static bool					m_bClassCreated;

		LONG						m_lSavedWindowStyle;
		LONG						m_lSavedExWindowStyle;
		PajaTypes::uint32			m_ui32SavedCreateFlags;
		HWND						m_hSavedParent;
		RECT						m_rSavedWindowRect;
		PajaTypes::BBox2C			m_rSavedViewport;
		bool						m_bD3DReady;

		struct ModeS
		{
			// Mode data
			DWORD					dwWidth;
			DWORD					dwHeight;
			D3DFORMAT				rFormat;
			DWORD					dwBehavior;
			D3DFORMAT				rDepthStencilFormat;
		};

		struct DeviceS
		{
			// Device data
			D3DDEVTYPE				rDeviceType;
			D3DCAPS8				rD3DCaps;
			TCHAR*					strDesc;
			bool					bCanDoWindowed;
			
			// Mode data
			bool					bWindowed;
			bool					bStereo;
			DWORD					dwCurrentMode;
			std::vector<ModeS>		rModes;
		};

		struct AdapterS
		{
			// Adapter data
			D3DADAPTER_IDENTIFIER8	rD3DAdapterIdentifier;
			UINT					iAdapter;

			// Device data
			DWORD					dwCurrentDevice;
			std::vector<DeviceS>	rDevices;
		};

		DWORD					m_dwCurAdapter;
		std::vector<AdapterS>	m_rAdapters;

	};

};

#endif // __OPENGLDEVICEC_H__