/*!	
	@file
	@brief	レンダリングドライバ Direct3D9 Ver.
*/

#ifndef CVideoDriverD3D9_h
#define CVideoDriverD3D9_h

#include"../../../../../Setup/CompileMode.h"
#include"../../../../../template/com_ptr.h"
#include"../../../../../Auxiliary/Windows/CDllWrapper.h"
#include"../../CVideoCardDriver.h"

#include"D3D9Include.h"

#include"CPixelShaderCompiler.h"
#include"CVertexShaderCompiler.h"
#include<d3d9.h>
#include<vector>

namespace Maid
{
	class CVideoCardDriverD3D9 : public IVideoCardDriver
	{
	public:

		enum SHADERMODEL
		{
			SHADERMODEL_DEFAULT,	//!<	自動的に決定
			SHADERMODEL_0000,		//!<	シェーダー無し
			SHADERMODEL_0101,		//!<	Ver 1.1 
			SHADERMODEL_0200,		//!<	Ver 2.0 
			SHADERMODEL_0300,		//!<	Ver 3.0 
		};

		CVideoCardDriverD3D9( HWND hWnd, SHADERMODEL shader = SHADERMODEL_DEFAULT  );

		virtual void Initialize( const SCREENMODE& mode);
		virtual void Reset( const SCREENMODE& Mode );
		virtual void Restore();
		virtual void Finalize();
		virtual void Flip();
		virtual DEVICESTATE TestCooperativeLevel();


		virtual SPSURFACEBUFFER CreateSurface( const SIZE2DI& size, PIXELFORMAT fmt );
		virtual SPTEXTUREBUFFER CreateTextureBuffer( const CTextureBufferMemory& buffer );
		virtual SPTEXTUREBUFFER CreateRTTextureBuffer( const SIZE2DI& size, PIXELFORMAT fmt );
		virtual SPINDEXBUFFER	CreateIndexBuffer( const MySTL::vector<unt08>& data, int Format );
		virtual SPVERTEXBUFFER  CreateVertexBuffer( const MySTL::vector<unt08>& data, VERTEXFORMAT Format );
		virtual SPVERTEXSHADERBUFFER CreateVertexShader( const mstring& Name );
		virtual SPVERTEXSHADERBUFFER CreateVertexShader( const MySTL::vector<unt08>& Code, SHADERCOMPILE type );
		virtual SPPIXELSHADERBUFFER CreatePixelShader( const mstring& Name );
		virtual SPPIXELSHADERBUFFER CreatePixelShader( const MySTL::vector<unt08>& Code, SHADERCOMPILE type );
		virtual SPVERTEXDECLARATIONBUFFER CreateVertexDeclarationBuffer( const mstring& Name );

		virtual void SetRenderTarget( const ISurfaceBuffer* pBuffer );
		virtual void ResetRenderTarget();
		virtual void SetDepthStencil( const ISurfaceBuffer* pBuffer );
		virtual void ResetDepthStencil();

		virtual void UnsetTextureBuffer( int stage );
		virtual void SetIndexBuffer( const SPINDEXBUFFER& pBuffer );
		virtual void SetTextureBuffer( const SPTEXTUREBUFFER& pBuffer, int stage );
		virtual void SetVertexBuffer( const SPVERTEXBUFFER& pBuffer, int pos );
		virtual void SetVertexShader( const SPVERTEXSHADERBUFFER& pShader );
		virtual void SetPixelShader( const SPPIXELSHADERBUFFER& pShader );
		virtual void SetVertexDeclaration( const SPVERTEXDECLARATIONBUFFER& pDecl );

		virtual void SetVertexShaderConstF( int pos, const VECTOR4DF& vec );
		virtual void SetRenderState( RENDERSTATE state, unt value );
		virtual void SetSamplerState( int Stage, SAMPLERSTATE state, unt value );
		virtual void SetViewPort( const RECT2DI& screen, float MinZ, float MaxZ );
		virtual void CopySurface( const SPSURFACEBUFFER& pSrc, SPSURFACEBUFFERMEMORY& pDst );

		virtual mstring GetVideoInfo();


		virtual void BeginScene();
		virtual void EndScene();

		virtual void ClearColor( const COLOR_R08G08B08I& Color );
		virtual void ClearZ( float val );
		virtual void DrawPrimitive( PRIMITIVE prim, unt StartVertex, unt PrimitiveCount );
		virtual void DrawPrimitiveUP( PRIMITIVE prim, const void* pVertex, unt Stride, unt PrimitiveCount );

		virtual void DrawIndexedPrimitive( PRIMITIVE prim, int BaseVertexOffset, unt MinIndex, unt NumVertices, unt StartIndex, unt PrimitiveCount );

		virtual void DrawIndexPrimitiveUP( PRIMITIVE prim, int MinIndex, int NumVertices, const void* pVertex, int VertexSize, int PrimitiveCount, const void* pIndex, int IndexSize  );


	private:
		void CreateD3D9();
		void CreateDevice( const SCREENMODE& mode );
		void InitializePresertParameters( D3DPRESENT_PARAMETERS& Info, const SCREENMODE& Mode  );
		D3DFORMAT	GetBackBufferFormatD3D( SCREENMODE::TYPE Mode ) const;
		bool SerchDisplayMode( int Width, int Height, int RefreshRate, D3DFORMAT Format );

		void UpdateWindowInfo();
		void CreateRTSurface();
		void ReleaseRTSurface();

	private:
		HWND					m_hWnd;
		CDllWrapper				m_d3d9DLL;		//!<	d3d9.dll
		SPD3D					m_pDirect3D;	//!<	Direct3D オブジェクト
		SPD3DDEVICE				m_pDevice;		//!<	レンダリングデバイス
		D3DADAPTER_IDENTIFIER9	m_AdaptrerInfo;		//!<	アダプタ情報

		D3DPRESENT_PARAMETERS		m_DeviceInfo;		//!<	作成したデバイス情報

		MySTL::vector<D3DDISPLAYMODE>	m_DisplayModeList;	//!<	初期化できるディスプレイモードリスト
		D3DFORMAT						m_16BitModeFormat;	//!<	16BitColor時のバックバッファのピクセルフォーマット
		D3DFORMAT						m_32BitModeFormat;	//!<	32BitColor時のバックバッファのピクセルフォーマット
		D3DFORMAT						m_WindowModeFormat;	//!<	WindowMode時のバックバッファのピクセルフォーマット
		D3DCAPS9						m_DeviceCaps;
		bool		m_IsSoftTnL;	//	頂点処理を ソフトウェアで行うか？


		SPVERTEXSHAERCOMPILER	m_pVertexShaderCompiler;
		SPPIXELSHAERCOMPILER	m_pPixelShaderCompiler;


		SPD3DSURFACEBUFFER	m_pAspectLockBuffer;
		SPD3DSURFACEBUFFER	m_pDefaultDepthStencil;

		SHADERMODEL			m_ShaderModel;

		bool IsAspectLock();
		SCREENMODE			m_ScreenMode;
		SIZE2DI				m_AspectLock;

		LONG		m_WindowModeStyle;
		POINT2DI	m_WindowModePos;

	};
}


#endif
