#ifndef __SFJP_MYU__AGH_DEFS_H__
#define __SFJP_MYU__AGH_DEFS_H__

#include "agh_defs_stl.h"
#include "agh_arith_value_set.h"


#ifndef __AGH_MY_ALLOCATOR
	#define __AGH_MY_ALLOCATOR	std::allocator
#endif
//#define _AGH_ALLOCATOR(_Ty)	std::allocator<_Ty>
#define _AGH_ALLOCATOR(_Ty)		__AGH_MY_ALLOCATOR<_Ty>

//	Types
//typedef std::string			_agh_string;
typedef std::basic_string<char, std::char_traits<char>, _AGH_ALLOCATOR(char) >
								_agh_string;
#define _AGH_STRING				std::string

#define _AGH_VECTOR(_Ty)		std::vector<_Ty, _AGH_ALLOCATOR(_Ty) >
//#define _agh_vector(_Ty)		std::vector<_Ty, _AGH_ALLOCATOR(_Ty) >

#define _AGH_MAP(_K,_Ty)		std::map<_K, _Ty, std::less<_K>, _AGH_ALLOCATOR(_Ty) >
//#define _agh_map(_K,_Ty)		std::map<_K, _Ty, _AGH_ALLOCATOR(_Ty) >

typedef _AGH_MAP(_agh_string,_agh_string) _agh_map_strstr;

#define _AGH_LIST(_Ty)			std::list<_Ty, _AGH_ALLOCATOR(_Ty) >
//#define _agh_list(_Ty)		std::list<_Ty, _AGH_ALLOCATOR(_Ty) >

//typedef unsigned long _DWORD;
typedef unsigned long AGH_DWORD;
typedef unsigned char AGH_BYTE;
typedef unsigned long AGHDWORD;
//typedef unsigned long AGHCOLOR;
typedef unsigned char AGHBYTE;

/*
//	RECT
typedef struct _tagAGH_RECT
{
	long    left;
	long    top;
	long    right;
	long    bottom;

	_tagAGH_RECT(){
		left = top = right = bottom = 0;
	}
	_tagAGH_RECT(long left_in, long top_in, long right_in, long bottom_in){
		left = left_in;
		top = top_in;
		right = right_in;
		bottom = bottom_in;
	}
} _AGH_RECT, _AGH_RECT;

//	POINT
typedef struct _tagAGH_POINT
{
    long	x;
    long	y;

	_tagAGH_POINT(){ x = y = 0; }
	_tagAGH_POINT(long x_in, long y_in){
		x = x_in;
		y = y_in;
	}
} _AGH_POINT, AGH_POINT;
*/


//////////////////////////////////////////////////

typedef long pos_t;

//	POINT
class CPoint
{
public:
    agh::pos_t x;
    agh::pos_t y;

	CPoint(){ x = y = 0; }
	CPoint(agh::pos_t x_in, agh::pos_t y_in){
		x = x_in;
		y = y_in;
	}
	// Appendix Method ///////////////////////////////////

	double GetToPointDistance(const agh::CPoint &point){
		return ::sqrt((double) point.x*point.x + point.y*point.y );
	}
	double GetDistance(const agh::CPoint &point){
		return GetToPointDistance(point);
	}
	double GetDistance(agh::pos_t x, agh::pos_t y){
		return GetToPointDistance(CPoint(x,y));
	}

	// operator overload /////////////////////////////////

	CPoint operator + (const CPoint &xy){
		return CPoint(x+xy.x, y+xy.y);
	}

	CPoint operator + (int add){
		return CPoint(x+add, y+add);
	}

	CPoint operator - (const CPoint &xy){
		return CPoint(x-xy.x, y-xy.y);
	}

	CPoint operator - (int add){
		return CPoint(x-add, y-add);
	}

	CPoint operator * (const CPoint &xy){
		return CPoint(x*xy.x, y*xy.y);
	}

	CPoint operator * (int add){
		return CPoint(x*add, y*add);
	}

	CPoint operator / (const CPoint &xy){
		return CPoint(x/xy.x, y/xy.y);
	}

	CPoint operator / (int add){
		return CPoint(x/add, y/add);
	}

	/////

	CPoint& operator += (const CPoint &xy){
		x+=xy.x, y+=xy.y;
		return *this;	//	2009/10/07 要るくない？
	}

	CPoint& operator += (int add){
		x+=add, y+=add;
		return *this;	//	2009/10/07 要るくない？
	}

	CPoint& operator -= (const CPoint &xy){
		x-=xy.x, y-=xy.y;
		return *this;
	}

	CPoint& operator -= (int add){
		x-=add, y-=add;
		return *this;
	}

	CPoint& operator *= (const CPoint &xy){
		x*=xy.x, y*=xy.y;
		return *this;
	}

	CPoint& operator *= (int add){
		x*=add, y*=add;
		return *this;
	}

	CPoint& operator /= (const CPoint &xy){
		x/=xy.x, y/=xy.y;
		return *this;
	}

	CPoint& operator /= (int add){
		x/=add, y/=add;
		return *this;
	}
};
typedef agh::CPoint /*POINT,*/ AGH_POINT, _AGH_POINT;

//////////////////////////////////////////////////

//	CRect / RECT / AGH_RECT / _AGH_RECT
class CRect
{
public:
	agh::pos_t left;
	agh::pos_t top;
	agh::pos_t right;
	agh::pos_t bottom;

	CRect(){
		left = top = right = bottom = 0;
	}
	CRect(agh::pos_t left_in, agh::pos_t top_in, agh::pos_t right_in, agh::pos_t bottom_in){
		left = left_in;
		top = top_in;
		right = right_in;
		bottom = bottom_in;
	}

	// Appendix Method ///////////////////////////////////

	AGH_POINT GetCenter() const { return AGH_POINT( (left+right)/2, (top+bottom)/2 ); }

	AGH_POINT GetLeftTopPoint() const { return AGH_POINT(left,top); }
	AGH_POINT GetLtPoint() const { return AGH_POINT(left,top); }
	AGH_POINT GetLt() const { return AGH_POINT(left,top); }

	AGH_POINT GetRightBottomPoint() const { return AGH_POINT(right,bottom); }
	AGH_POINT GetRbPoint() const { return AGH_POINT(right,bottom); }
	AGH_POINT GetRb() const { return AGH_POINT(right,bottom); }

	// operator overload /////////////////////////////////

	CRect operator + (const CRect& rect){
		CRect rectNew = *this;
		rectNew += rect;
		return rectNew;
		/*return CRect(
			left + rect.left,
			top + rect.top,
			right + rect.right,
			bottom + rect.bottom);*/
	}

	CRect operator + (const CPoint& point){
		return operator +(CRect(point.x, point.y, point.x, point.y));	//	これでも速度変わらないか・・・！？
		/*return CRect(
			left + point.x,
			top + point.y,
			right + point.x,
			bottom + point.y);*/
	}

	CRect operator + (int add){
		return operator +(CPoint(add,add));	//	これでも速度変わらないっぽい！（インライン展開により）
		/*return CRect(
			left + add,
			top + add,
			right + add,
			bottom + add);*/
	}

	///

	CRect operator - (const CRect& rect){
		return CRect(
			left - rect.left,
			top - rect.top,
			right - rect.right,
			bottom - rect.bottom);
	}

	CRect operator - (const CPoint& point){
		return CRect(
			left - point.x,
			top - point.y,
			right - point.x,
			bottom - point.y);
	}

	CRect operator - (int minus){
		return operator -(CPoint(minus,minus));	//	これでも速度変わらないっぽい！（インライン展開により）
		/*return CRect(	
			left - minus,
			top - minus,
			right - minus,
			bottom - minus);*/
	}

	///	乗除算は拡大縮小 ////////
	
	CRect operator * (const CRect& rect){
		return CRect(
			left * rect.left,
			top * rect.top,
			right * rect.right,
			bottom * rect.bottom);
	}

	CRect operator * (const CPoint& pointMultiply){
		return CRect(
			left * pointMultiply.x,
			top * pointMultiply.y,
			right * pointMultiply.x,
			bottom * pointMultiply.y );
	}

	//	2009/10/08 FPU演算は結構重い（10倍くらい）・・・のでintバージョンも用意した。
	CRect operator * (int nMultiply){
		return operator *( CPoint(nMultiply, nMultiply) );	//	これでも速度変わらないっぽい！（インライン展開により）
	}

	CRect operator * (float fMultiply){
		//return operator *( CPoint(multiply, multiply) );	//	これでも速度変わらないっぽい！（インライン展開により）
		return CRect(	//	CPointにするとintになっちゃうからこうしないと駄目だな・・・
			(agh::pos_t)(left * fMultiply),
			(agh::pos_t)(top * fMultiply),
			(agh::pos_t)(right * fMultiply),
			(agh::pos_t)(bottom * fMultiply) );
	}
	
	////////

	CRect operator /(const CRect& rect){
		return CRect(
			left / rect.left,
			top / rect.top,
			right / rect.right,
			bottom / rect.bottom);
	}

	CRect operator / (const CPoint& pointDivide){
		return CRect(
			(agh::pos_t)(left / pointDivide.x),
			(agh::pos_t)(top / pointDivide.y),
			(agh::pos_t)(right / pointDivide.x),
			(agh::pos_t)(bottom / pointDivide.y) );
	}

	//	2009/10/08 FPU演算は結構重い（10倍くらい）・・・のでintバージョンも用意した。
	CRect operator / (int nDivide){
		return operator /( CPoint(nDivide, nDivide) );	//	これでも速度変わらないっぽい！（インライン展開により）
	}

	CRect operator / (float fDivide){
		//return operator *( CPoint(multiply, multiply) );	//	これでも速度変わらないっぽい！（インライン展開により）
		return CRect(	//	CPointにするとintになっちゃうからこうしないと駄目だな・・・
			(agh::pos_t)(left / fDivide),
			(agh::pos_t)(top / fDivide),
			(agh::pos_t)(right / fDivide),
			(agh::pos_t)(bottom / fDivide) );
	}

	// ### eq ##################

	CRect& operator += (const CRect& rect)
	{
		left += rect.left;
		top += rect.top;
		right += rect.right;
		bottom += rect.bottom;
		return *this;
	}

	CRect& operator += (const CPoint& point)
	{
		left += point.x;
		top += point.y;
		right += point.x;
		bottom += point.y;
		return *this;
	}

	CRect& operator += (int add)
	{
		return operator +=(CPoint(add,add));	//	これでも速度変わらないっぽい！（インライン展開により）
		/*left += add;
		top += add;
		right += add;
		bottom += add;*/
		return *this;
	}

	///

	CRect& operator -= (const CRect& rect)
	{
		left -= rect.left;
		top -= rect.top;
		right -= rect.right;
		bottom -= rect.bottom;
		return *this;
	}

	CRect& operator -= (const CPoint& point)
	{
		left -= point.x;
		top -= point.y;
		right -= point.x;
		bottom -= point.y;
		return *this;
	}

	CRect& operator -= (int minus)
	{
		return operator -=(CPoint(minus,minus));	//	これでも速度変わらないっぽい！（インライン展開により）
		/*left -= minus;
		top -= minus;
		right -= minus;
		bottom -= minus;*/
		return *this;
	}

	///	乗除算は拡大縮小 ////////

	//////////////////////////////////


	bool IsInner(agh::pos_t x, agh::pos_t y){
		if ( x >= left && x <= right && y >= top && y <= bottom )
			return true;
		else
			return false;
	}
};
typedef agh::CRect /*RECT,*/ AGH_RECT, _AGH_RECT;

//////////////////////////////////////////////////


class CAghAnyClassBase {};



///// COLOR Types ///////////////////////////////////////////////////////////////////////////////

typedef unsigned long COLOR;
typedef agh::COLOR COLOR_t;
typedef agh::COLOR color_t;
typedef agh::COLOR _color_t;
typedef agh::COLOR RGB;
typedef agh::COLOR XRGB;
typedef agh::COLOR ARGB;

typedef agh::COLOR COLOR32;
typedef agh::COLOR RGB32;
typedef agh::COLOR XRGB32;
typedef agh::COLOR ARGB32;

typedef unsigned char COLOR_VALUE;
typedef agh::COLOR_VALUE SINGLE_COLOR;
typedef agh::COLOR_VALUE COLOR_SINGLE;
typedef agh::COLOR_VALUE COLOR_BYTE;

//////////////////////////////////////////

/*typedef AGHCOLOR COLOR;
typedef AGHCOLOR AGH_COLOR;
typedef AGHCOLOR _AGH_COLOR;*/

#define AGH_FILTER_BYTE(x)		((x)&0xff)
#define AGHCOLOR_ARGB(a,r,g,b)	((agh::COLOR)(\
	(((a)&0xff)<<24)|\
	(((r)&0xff)<<16)|\
	(((g)&0xff)<<8)|\
	(((b)&0xff))))
#define AGHCOLOR_RGB(r,g,b)		AGHCOLOR_ARGB(0xff,r,g,b)
#define AGHCOLOR_XRGB(r,g,b)	AGHCOLOR_ARGB(0xff,r,g,b)

inline AGH_BYTE AghWrapByte( int x )
{
	if ( x > 255 )
		return 255;
	if ( x < 0 )
		return 0;
	return x;
}

////////////////////////////////
//
//		マクロ
//
#define AGHCOLOR_A(a)			((agh::COLOR)((((a)&0xff)<<24)|(0x00ffffff)))
#define AGHCOLORW_A(a)			AGHCOLOR_A(AghWrapByte(a))
#define AGHCOLORW_ARGB(a,r,g,b)	AGHCOLOR_ARGB(AghWrapByte(a),AghWrapByte(r),AghWrapByte(g),AghWrapByte(b))
#define AGHCOLORW_RGBA(r,g,b,a)	AGHCOLOR_RGBA(AghWrapByte(r),AghWrapByte(g),AghWrapByte(b),AghWrapByte(a))
#define AGHCOLORW_XRGB(r,g,b)	AGHCOLOR_XRGB(AghWrapByte(r),AghWrapByte(g),AghWrapByte(b))

//	ものくろー
#define AGHCOLOR_MONO(v)		AGHCOLOR_XRGB(v,v,v)
#define AGHCOLORW_MONO(v)		AGHCOLOR_XRGB(AghWrapByte(v),AghWrapByte(v),AghWrapByte(v))

#define AGHCOLOR_BLUE			((agh::COLOR)0xff0000ff)
#define AGHCOLOR_GREEN			((agh::COLOR)0xff00ff00)
#define AGHCOLOR_RED			((agh::COLOR)0xffff0000)
#define AGHCOLOR_PINK			((agh::COLOR)0xffff00ff)
#define AGHCOLOR_CYAN			((agh::COLOR)0xff00ffff)
#define AGHCOLOR_YELLOW			((agh::COLOR)0xffffff00)
#define AGHCOLOR_WHITE			((agh::COLOR)0xffffffff)
#define AGHCOLOR_BLACK			((agh::COLOR)0xff000000)
#define AGHCOLOR_FULLWHITE		((agh::COLOR)0xffffffff)	//	AGHCOLOR_WHITEに同じ

#define AGHCOLOR_NABLUE			((agh::COLOR)0x000000ff)
#define AGHCOLOR_NAGREEN		((agh::COLOR)0x0000ff00)
#define AGHCOLOR_NARED			((agh::COLOR)0x00ff0000)
#define AGHCOLOR_NAPINK			((agh::COLOR)0x00ff00ff)
#define AGHCOLOR_NACYAN			((agh::COLOR)0x0000ffff)
#define AGHCOLOR_NAYELLOW		((agh::COLOR)0x00ffff00)
#define AGHCOLOR_NAWHITE		((agh::COLOR)0x00ffffff)
#define AGHCOLOR_NABLACK		((agh::COLOR)0x00000000)

#define AGHCOLOR_FULLALPHA		((agh::COLOR)0xff000000)
#define AGHCOLOR_ZEROALPHA		((agh::COLOR)0x00000000)

//	フィルター
#define AGHCOLOR_ZEROALPHA_FILTER(c)	(c&0x00ffffff)
#define AGHCOLOR_FULLALPHA_FILTER(c)	(c|0xff000000)

#define AGHCOLOR_GETNAMASK(c)		(c&0x00ffffff)
#define AGHCOLOR_GETNRMASK(c)		(c&0xff00ffff)
#define AGHCOLOR_GETNGMASK(c)		(c&0xffff00ff)
#define AGHCOLOR_GETNBMASK(c)		(c&0xffffff00)

#define AGHCOLOR_GETAMASK(c)		(c&0xff000000)
#define AGHCOLOR_GETRMASK(c)		(c&0x00ff0000)
#define AGHCOLOR_GETGMASK(c)		(c&0x0000ff00)
#define AGHCOLOR_GETBMASK(c)		(c&0x000000ff)

#define AGHCOLOR_AMASK(c)			(c&0xff000000)
#define AGHCOLOR_RMASK(c)			(c&0x00ff0000)
#define AGHCOLOR_GMASK(c)			(c&0x0000ff00)
#define AGHCOLOR_BMASK(c)			(c&0x000000ff)

#define AGHCOLOR_GETA(c)			(AGHCOLOR_AMASK(c)>>24)
#define AGHCOLOR_GETR(c)			(AGHCOLOR_RMASK(c)>>16)
#define AGHCOLOR_GETG(c)			(AGHCOLOR_GMASK(c)>>8)
#define AGHCOLOR_GETB(c)			(AGHCOLOR_BMASK(c))

#define AGHCOLOR_CHANGEA(c,A)		(AGHCOLOR_GETNAMASK(c)|(A<<24))
#define AGHCOLOR_CHANGER(c,R)		(AGHCOLOR_GETNRMASK(c)|(R<<16))
#define AGHCOLOR_CHANGEG(c,G)		(AGHCOLOR_GETNGMASK(c)|(G<<8))
#define AGHCOLOR_CHANGEB(c,B)		(AGHCOLOR_GETNBMASK(c)|(B))

///// Vector Types ///////////////////////////////////////////////////////////////////////////////

typedef float pos3d_t;

//	AGH_VECTOR2
typedef struct _AGH_XY
{
	agh::pos3d_t x;
	agh::pos3d_t y;

	_AGH_XY(){
		y = x = 0;
	}
	_AGH_XY( agh::pos3d_t x_in, agh::pos3d_t y_in ){
		x = x_in;
		y = y_in;
	}
	_AGH_XY( long x_in, long y_in ){
		x = (float)x_in;
		y = (float)y_in;
	}

	// operator overload /////////////////////////////////

	_AGH_XY operator + (_AGH_XY xy){
		return _AGH_XY(x+xy.x, y+xy.y);
	}

	_AGH_XY operator + (float add){
		return _AGH_XY(x+add, y+add);
	}

	_AGH_XY operator - (_AGH_XY xy){
		return _AGH_XY(x-xy.x, y-xy.y);
	}

	_AGH_XY operator - (float add){
		return _AGH_XY(x-add, y-add);
	}

	_AGH_XY& operator += (_AGH_XY xy){
		x-xy.x, y-xy.y;
	}

	_AGH_XY& operator += (float add){
		x-add, y-add;
	}
}
AGH_XY, AGH_VECTOR2, AGHVECTOR2, VECTOR2;



//	AGH_VECTOR3
typedef struct _AGH_XYZ
{
	agh::pos3d_t x;
	agh::pos3d_t y;
	agh::pos3d_t z;

	_AGH_XYZ(){
		z = y = x = 0;
	}
	_AGH_XYZ( agh::pos3d_t x_in, agh::pos3d_t y_in, agh::pos3d_t z_in ){
		x = x_in;
		y = y_in;
		z = z_in;
	}
}
AGH_XYZ, AGH_VECTOR, AGH_VECTOR3, AGHVECTOR3;

////////////////////////////////////////////////////////////////////////////

//	Single Inheritance
class _CAghCallbackDummyBaseSI{};
typedef _CAghCallbackDummyBaseSI _CAghCallbackDummyBase;

//	Multiple Inheritance
class _CAghCallbackDummyBaseMI_A{};class _CAghCallbackDummyBaseMI_B{};
class _CAghCallbackDummyBaseMI : public _CAghCallbackDummyBaseMI_A, public _CAghCallbackDummyBaseMI_B{};


#endif//__SFJP_MYU__AGH_DEFS_H__
