#ifndef OURDREAM_2D_RENDERSYSTEM_H
#define OURDREAM_2D_RENDERSYSTEM_H

#include "IInterface.h"
#include "ComDef.h"

enum EPrimType
{
	EPT_NULL=0,
	EPT_POINT_LIST=1,
	EPT_TRIANGLE_LIST=2,
	EPT_TRIANGLE_STRIP=3,
	EPT_TRIANGLE_FAN=4,
	EPT_LINE_LIST=5,
	EPT_LINE_STRIP=6
};
enum EVertexType
{
	EVT_NULL=0,
	EVT_OURDREAM_3D=1,
	EVT_OURDREAM_2D=2,
	EVT_OURDREAM_3D_PS=3,

};
enum EFillMode
{
	EFM_NORMAL=0,
	EFM_WIREFRAME=1
};
struct SThePrim
{
	int m_iID;
	EPrimType m_eType;
	EVertexType m_eVertexType;
	int m_iTotalVerts;
	void ** m_pVertexData;
	int m_iTotalIndices;
	WORD * m_pIndices;
	int m_iTextureID;
	int m_iPrimCount;

	void Init(void)
	{
		m_iID=0;
		m_eType=EPT_NULL;
		m_eVertexType=EVT_NULL;
		m_iTotalIndices=0;
		m_pVertexData=NULL;
		m_iTotalIndices=0;
		m_pIndices=NULL;
		m_iTextureID=0;
		m_iPrimCount=0;
	}
};

// 定义顶点结构
struct S2DVertex
{
	float	 m_x, m_y, m_z, m_rhw;
	DWORD	 m_color;
	float	 tx, ty; // 纹理坐标.
	S2DVertex()
	{
		m_x		= 0;
		m_y		= 0;  
		m_z		= 0;
		m_rhw	= 0;
		m_color = 0xffffffff;
		tx		= 0;
		ty		= 0;
	}
	void Init(float x, float y, float z, float rhw, DWORD c, float texx, float texy)
	{
		m_x		= x;
		m_y		= y;  
		m_z		= z;
		m_rhw	= rhw;
		m_color = c;
		tx		= texx;
		ty		= texy;
	}
	S2DVertex(float x, float y, float z, float rhw, DWORD c, float texx, float texy)
	{
		m_x		= x;
		m_y		= y;  
		m_z		= z;
		m_rhw	= rhw;
		m_color = c;
		tx		= texx;
		ty		= texy;
	}
};
struct S3DVertex
{
	float	 m_x, m_y, m_z;
	float	 m_nx, m_ny, m_nz;
	DWORD	 m_color;
	float	 tx, ty; // 纹理坐标.
	S3DVertex()
	{
		m_x		= 0;
		m_y		= 0;  
		m_z		= 0;
		m_nx	= 0;
		m_ny	= 0;
		m_nz	= 0;
		m_color = 0xffffffff;
		tx		= 0;
		ty		= 0;
 	}
	void Init(float x, float y, float z, float nx, float ny, float nz, DWORD c, float texx, float texy)
	{
		m_x		= x;
		m_y		= y;  
		m_z		= z;
		m_nx	= nx;
		m_ny	= ny;
		m_nz	= nz;
		m_color = c;
		tx		= texx;
		ty		= texy;
	}
	S3DVertex(float x, float y, float z, float nx, float ny, float nz, DWORD c, float texx, float texy)
	{
		m_x		= x;
		m_y		= y;  
		m_z		= z;
		m_nx	= nx;
		m_ny	= ny;
		m_nz	= nz;
		m_color = c;
		tx		= texx;
		ty		= texy;
	}
};
struct S3DPSVertex
{
	float	 m_x, m_y, m_z;
	float	 m_psize;
	DWORD	 m_color;
	S3DPSVertex()
	{
		m_x		= 0;
		m_y		= 0;  
		m_z		= 0;
		m_psize	= 0;
		m_color = 0xffffffff;
	}
	void Init(float x, float y, float z, float size, DWORD c)
	{
		m_x		= x;
		m_y		= y;  
		m_z		= z;
		m_psize	= size;
		m_color = c;
	}
	S3DPSVertex(float x, float y, float z, float size, DWORD c)
	{
		m_x		= x;
		m_y		= y;  
		m_z		= z;
		m_psize	= size;
		m_color = c;
	}
};
enum ELightType
{
	ELT_NULL=0,
	ELT_POINT=1,
	ELT_DIRECTIONAL=2,
	ELT_SPOT=3
};
struct SLight
{
	void Init(void)
	{
		m_eType=ELT_NULL;
		m_fPosX=m_fPosY=m_fPosZ=0;
		m_fDirX=m_fDirY=m_fDirZ=0;
		m_fAmbientR=m_fAmbientG=m_fAmbientB=m_fAmbientA=0;
		m_fDiffuseR=m_fDiffuseG=m_fDiffuseB=m_fDiffuseA=0;
		m_fSpecularR=m_fSpecularG=m_fSpecularB=m_fSpecularA=0;
		m_fRange=0;
		m_fFalloff=0;
		m_fAttenuation0=0;
		m_fAttenuation1=0;
		m_fAttenuation2=0;
		m_fTheta=0;
		m_fPhi=0;
	}

	ELightType m_eType;
	float m_fPosX, m_fPosY, m_fPosZ;
	float m_fDirX, m_fDirY, m_fDirZ;
	float m_fAmbientR, m_fAmbientG, m_fAmbientB, m_fAmbientA;
	float m_fDiffuseR, m_fDiffuseG, m_fDiffuseB, m_fDiffuseA;
	float m_fSpecularR, m_fSpecularG, m_fSpecularB, m_fSpecularA;
	float m_fRange;
	float m_fFalloff;
	float m_fAttenuation0;
	float m_fAttenuation1;
	float m_fAttenuation2;
	float m_fTheta;
	float m_fPhi;
};

struct SMaterial
{
	void Init(void)
	{
		m_fEmissiveR=m_fEmissiveG=m_fEmissiveB=m_fEmissiveA=0;
		m_fAmbientR=m_fAmbientG=m_fAmbientB=m_fAmbientA=0;
		m_fDiffuseR=m_fDiffuseG=m_fDiffuseB=m_fDiffuseA=0;
		m_fSpecularR=m_fSpecularG=m_fSpecularB=m_fSpecularA=0;
		m_fPower=0;
	}

	float m_fEmissiveR, m_fEmissiveG, m_fEmissiveB, m_fEmissiveA;
	float m_fAmbientR, m_fAmbientG, m_fAmbientB, m_fAmbientA;
	float m_fDiffuseR, m_fDiffuseG, m_fDiffuseB, m_fDiffuseA;
	float m_fSpecularR, m_fSpecularG, m_fSpecularB, m_fSpecularA;
    float m_fPower;
};

enum ETextureUsage
{
	ETU_DYNAMIC=0,
	ETU_RENDERTARGET=1
};

enum EShaderType
{
	EST_NULL=0,
	EST_VERTEXSHADER=1,
	EST_PIXELSHADER=2
};

enum EShaderVer
{
	ESV_NULL=0,
	ESV_VS_1_1=1,
	ESV_VS_2_0=2,
	ESV_VS_2_a=3,
	ESV_VS_3_0=4,
	ESV_PS_1_1=5,
	ESV_PS_1_2=6,
	ESV_PS_1_3=7,
	ESV_PS_1_4=8,
	ESV_PS_2_0=9,
	ESV_PS_2_a=10,
	ESV_PS_2_b=11,
	ESV_PS_3_0=12
};

enum EShaderValType
{
	ESVT_BOOL=1,
	ESVT_BOOL_ARRAY=2,
	ESVT_FLOAT=3,
	ESVT_FLOAT_ARRAY=4,
	ESVT_INT=5,
	ESVT_INT_ARRAY=6,
	ESVT_MATRIX=7,
	ESVT_MATRIX_ARRAY=8,
	ESVT_MATRIXPOINT_ARRAY=9,
	ESVT_MATRIXTRANSPOSE=10,
	ESVT_MATRIXTRANSPOSE_ARRAY=11,
	ESVT_MATRIXTRANSPOSEPOINTER_ARRAY=12,
	ESVT_VECTOR=13,
	ESVT_VECTOR_ARRAY=14,
	ESVT_CUSTOMIZE_VALUE=15
};

class IRenderSystem : public IInterface
{
public:
	virtual bool CALL Init(SOD2DSystemSetup setup)=0;
	virtual void CALL Release(void)=0;
	virtual void CALL Clear(DWORD color)=0;
	virtual void CALL BeginScene(void)=0;
	virtual void CALL EndScene(void)=0;

	virtual EOD2DVideoType CALL GetRenderType(void)=0;
	//////////////////////////////////////////////////////////////////////////
	virtual void CALL SetRenderRestoreFunction(OD2DCallback fun)=0;
	virtual OD2DCallback CALL GetRenderRestoreFunction(void)=0;
	//////////////////////////////////////////////////////////////////////////
	virtual bool CALL CreateTexture(int ID, int width, int height, int miplevel, ETextureUsage usage)=0;
	virtual bool CALL LoadTexture(int ID, LPSTR FileName, DWORD Color)=0;
	virtual bool CALL LoadTextureFromMemory(int ID, void * data, DWORD size, DWORD Color)=0;
	virtual int CALL GetTextureWidth(int ID, bool Original=false)=0;
	virtual int CALL GetTextureHeight(int ID, bool Original=false)=0;
	virtual void CALL DelTexture(int ID)=0;
	virtual void CALL DelALLTexture(void)=0;
	
	virtual bool CALL LoadFont(int ID, LPSTR FontName, int Width, int Height, int Weight, bool Italic)=0;
	virtual void CALL DelFont(int ID)=0;
	virtual void CALL DelAllFont(void)=0;
	virtual void CALL SetFontColor(int ID, int R, int G, int B, int A)=0;
	virtual void CALL GetFontColor(int ID, int *R, int *G, int *B, int *A)=0;
	virtual RECT CALL GetFontRect(LPSTR Caption, int X, int Y, int ID)=0;
	virtual RECT CALL GetFontRect(LPWSTR Caption, int X, int Y, int ID)=0;
	virtual bool CALL RenderFont(LPSTR Caption, int X, int Y, int R, int G, int B, int A, bool Shadow, int FontID)=0;
	virtual bool CALL RenderFont(LPWSTR Caption, int X, int Y, int R, int G, int B, int A, bool Shadow, int FontID)=0;
	//////////////////////////////////////////////////////////////////////////
	virtual void CALL SetLight(SLight *light, int index)=0;
	virtual void CALL EnableLight(int index)=0;
	virtual void CALL DisableLight(int index)=0;
	virtual void CALL SetMaterial(SMaterial *mat)=0;

	virtual void CALL EnableAlpha(void)=0;
	virtual void CALL DisableAlpha(void)=0;

	virtual void CALL EnablePointSprite(float size, float min, float max, float a, float b, float c)=0;
	virtual void CALL DisablePointSprite(void)=0;

	virtual void CALL SetBlendMode(int blend)=0;
	virtual int CALL GetCurBlendMode(void)=0;

	virtual void CALL SetFillMode(EFillMode mode)=0;
	//////////////////////////////////////////////////////////////////////////
	virtual bool CALL AddPrim(SThePrim prim)=0;
	virtual void CALL DelPrim(int ID)=0;
	virtual void CALL DelAllPrim(void)=0;
	virtual int CALL RenderPrim(int ID=0)=0;

	virtual bool CALL DrawPrim(SThePrim prim)=0;
	virtual bool CALL DrawPrimEx(SThePrim prim)=0;
	//////////////////////////////////////////////////////////////////////////
	virtual void CALL ScreenShot(LPTSTR pFilename, EOD2DFileType eType)=0;

	virtual bool CALL ExecOffScreenRender(DWORD clearcolor, OD2DCallback funcs, int texID)=0;
	//////////////////////////////////////////////////////////////////////////
	virtual void CALL Draw2DTriangle(float X1, float Y1, float X2, float Y2, float X3, float Y3, 
									DWORD color1, DWORD color2, DWORD color3, int TextureID,
									float texx1, float texy1, float texx2, float texy2, float texx3, float texy3, 
									bool fill, int blend)=0;

	virtual void CALL Draw2DQuad(float left, float top, float right, float button, 
								DWORD leftupcolor, DWORD leftdowncolor, DWORD rightupcolor, DWORD rightdowncolor, 
								int TextureID,
								float texleft, float textop, float texright, float texbutton,
								bool fill, int blend)=0;
	//////////////////////////////////////////////////////////////////////////
	virtual DWORD CALL TransformColor(int a, int r, int g, int b)=0;
	virtual DWORD CALL GetAFromColor(DWORD color)=0;
	virtual DWORD CALL GetRFromColor(DWORD color)=0;
	virtual DWORD CALL GetGFromColor(DWORD color)=0;
	virtual DWORD CALL GetBFromColor(DWORD color)=0;
	virtual DWORD CALL SetAToColor(DWORD color, int a)=0;
	virtual DWORD CALL SetRToColor(DWORD color, int r)=0;
	virtual DWORD CALL SetGToColor(DWORD color, int g)=0;
	virtual DWORD CALL SetBToColor(DWORD color, int b)=0;
	//////////////////////////////////////////////////////////////////////////
};

#endif