#ifndef OURDREAM_2D_COMDEF_H
#define OURDREAM_2D_COMDEF_H

#include <windows.h>
#include "VideoType.h"

#ifdef OD2DDLL
#define EXPORT  __declspec(dllexport)
#else
#define EXPORT
#endif

#define CALL  __stdcall

// 定义常用数据类型
#ifndef DWORD
typedef unsigned long       DWORD;
typedef unsigned short      WORD;
typedef unsigned char       BYTE;
#endif

#define LOWORDINT(n) ((int)((signed short)(LOWORD(n))))
#define HIWORDINT(n) ((int)((signed short)(HIWORD(n))))

// 颜色相关的宏
#define ARGB(a,r,g,b)	((DWORD(a)<<24) + (DWORD(r)<<16) + (DWORD(g)<<8) + DWORD(b))
#define GETA(col)		((col)>>24)
#define GETR(col)		(((col)>>16) & 0xFF)
#define GETG(col)		(((col)>>8) & 0xFF)
#define GETB(col)		((col) & 0xFF)
#define SETA(col,a)		(((col) & 0x00FFFFFF) + (DWORD(a)<<24))
#define SETR(col,r)		(((col) & 0xFF00FFFF) + (DWORD(r)<<16))
#define SETG(col,g)		(((col) & 0xFFFF00FF) + (DWORD(g)<<8))
#define SETB(col,b)		(((col) & 0xFFFFFF00) + DWORD(b))

// 定义混合方式
#define	BLEND_COLORADD		1
#define	BLEND_COLORMUL		0
#define	BLEND_ALPHABLEND	2
#define	BLEND_ALPHAADD		0
#define	BLEND_ZWRITE		4
#define	BLEND_NOZWRITE		0

#define BLEND_DEFAULT		(BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE)
#define BLEND_DEFAULT_Z		(BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_ZWRITE)

// 定义回调函数格式
typedef bool (*OD2DCallback)();
// 自定义消息处理回调函数
typedef LRESULT (*MyMessageProc)( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );

// 系统设置信息结构
struct SOD2DSystemSetup
{
	EOD2DVideoType m_eRenderType;
	
	HWND m_hWindowID;
	
	bool m_bUseZBuffer;
	bool m_bWindowed;
	bool m_bUseStencilBuffer;
	bool m_bHideMouse;
	bool m_bUseHighPrecisionFPU;
	bool m_bUseVsync;
	bool m_bUseLog;
	
	int m_iScreenWidth;
	int m_iScreenHeight;
	int m_iColorMode;
	int m_iTextureFilter;
	int m_iAntialias;
	int m_iFixFPS;
	
	char m_szIcon[MAX_PATH];
	char m_szTitle[256];
	char m_szLog[MAX_PATH];
	
	void Init(void)
	{
		m_eRenderType			=EYVT_NULL;
		m_hWindowID				=NULL;
		m_bUseZBuffer			=true;
		m_bWindowed				=true;
		m_bUseStencilBuffer		=true;
		m_bHideMouse			=false;
		m_bUseHighPrecisionFPU	=true;
		m_bUseVsync				=false;
		m_bUseLog				=false;
		
		m_iScreenWidth			=800;
		m_iScreenHeight			=600;
		m_iColorMode			=32;
		m_iTextureFilter		=0;
		m_iAntialias			=0;
		m_iFixFPS				=0;
		
		m_szIcon[0]				='\0';
		m_szLog[0]				='\0';
		m_szTitle[0]			='\0';
	}
};

// 定义FPS方式
#define OD2DFPS_UNLIMITED	0
#define OD2DFPS_VSYNC		-1

// 浮点型的RECT
struct SOD2DFloatRect
{
	float m_fLeft;
	float m_fTop;
	float m_fRight;
	float m_fButtom;
	float m_fWidth;
	float m_fHeight;
	void Init(float left=0.0f, float top=0.0f, float right=0.0f, float buttom=0.0f)
	{
		m_fLeft=left;
		m_fTop=top;
		m_fRight=right;
		m_fButtom=buttom;
		m_fWidth=m_fRight-m_fLeft;
		m_fHeight=m_fButtom-m_fTop;
	}
	// 判断一个点是否在区域内
	bool IsPointIn(float x, float y)
	{
		if (x>m_fLeft && x<m_fRight && y>m_fTop && y<m_fButtom)
		{
			return true;
		}
		return false;
	}
	// 判断区域是否超出屏幕范围（或窗口范围）
	bool IsOutOfScreen(int ScreenWidth, int ScreenHeight)
	{
		if (m_fLeft<0 || m_fRight>ScreenWidth || 
			m_fTop<0 || m_fButtom>ScreenHeight)
		{
			return true;
		}
		return false;
	}
	// 判断一个区域是否包含另一个区域
	bool IsContain(float left, float top, float right, float buttom)
	{
		if (left>=m_fLeft && top>=m_fTop && right<=m_fRight && buttom<=m_fButtom)
		{
			return true;
		}
		return false;
	}
	// 判断两个区域是否碰撞
	bool IsCollision(float left, float top, float right, float buttom)
	{
		if (left<m_fRight && right>m_fLeft && top<m_fButtom && buttom>m_fTop)
		{
			return true;
		}
		return false;
	}
	SOD2DFloatRect & operator=(const SOD2DFloatRect & rhs)
	{
		if (this==&rhs)
		{
			return *this;
		}
		this->m_fLeft=rhs.m_fLeft;
		this->m_fTop=rhs.m_fTop;
		this->m_fRight=rhs.m_fRight;
		this->m_fButtom=rhs.m_fButtom;
		this->m_fWidth=rhs.m_fWidth;
		this->m_fHeight=rhs.m_fHeight;
		return *this;
	}
	bool operator== (const SOD2DFloatRect &rhs) const
	{
		return (this->m_fLeft==rhs.m_fLeft && this->m_fTop==rhs.m_fTop && 
			this->m_fRight==rhs.m_fRight && this->m_fButtom==rhs.m_fButtom);
	}
	SOD2DFloatRect operator- () const { SOD2DFloatRect temp; temp.Init(-m_fLeft, -m_fTop, -m_fRight, -m_fButtom); return temp; }
	SOD2DFloatRect operator- (const SOD2DFloatRect &rhs) const { SOD2DFloatRect temp; temp.Init(m_fLeft-rhs.m_fLeft, m_fTop-rhs.m_fTop, m_fRight-rhs.m_fRight, m_fButtom-rhs.m_fTop); return temp; }
	SOD2DFloatRect operator+ (const SOD2DFloatRect &rhs) const { SOD2DFloatRect temp; temp.Init(m_fLeft+rhs.m_fLeft, m_fTop+rhs.m_fTop, m_fRight+rhs.m_fRight, m_fButtom+rhs.m_fTop); return temp; }
	SOD2DFloatRect& operator-= (const SOD2DFloatRect &rhs) { m_fLeft-=rhs.m_fLeft; m_fTop-=rhs.m_fTop; m_fRight-=rhs.m_fRight; m_fButtom-=rhs.m_fButtom; return *this; }
	SOD2DFloatRect& operator+= (const SOD2DFloatRect &rhs) { m_fLeft+=rhs.m_fLeft; m_fTop+=rhs.m_fTop; m_fRight+=rhs.m_fRight; m_fButtom+=rhs.m_fButtom; return *this; }
	bool operator!= (const SOD2DFloatRect &rhs) const { return (m_fLeft!=rhs.m_fLeft || m_fTop!=rhs.m_fTop || m_fRight!=rhs.m_fRight || m_fButtom!=rhs.m_fButtom); }
	
	SOD2DFloatRect operator/ (const float scalar) const { SOD2DFloatRect temp; temp.Init(m_fLeft/scalar, m_fTop/scalar, m_fRight/scalar, m_fButtom/scalar); return temp; }
	SOD2DFloatRect operator* (const float scalar) const { SOD2DFloatRect temp; temp.Init(m_fLeft*scalar, m_fTop*scalar); return temp; }
	SOD2DFloatRect& operator*= (const float scalar) { m_fLeft*=scalar; m_fTop*=scalar; m_fRight*=scalar; m_fButtom*=scalar; return *this; }
};

// 定义常用文件格式
enum EOD2DFileType
{
	EODFT_BMP						=1,
	EODFT_JPG						=2,
	EODFT_TGA						=3,
	EODFT_PNG						=4,
	EODFT_DDS						=5
};

#endif