#ifndef __SFJP_MYU__AGH_ScreenBase_H__
#define __SFJP_MYU__AGH_ScreenBase_H__

//	Class Definitation
//class CScreenBase : public CWindowBase, public CControlBase
class CScreenBase : public CVisualControlBase	// <- 逆じゃないか・・・？(CWindowBaseがCScreenBaseを継承
{
protected:
	//	Must Override!! Methods.
	//virtual _AGH_POINT GetCurPos()=0;
	virtual _AGH_POINT GetCurPos(){
		throw CAghNotImplementedException("Can't use CScreenBase::GetCurPos() because not Overrided.");
		/*_AGH_POINT point;
		//ZeroMemory(&point, sizeof(point));
		point.x = -1;
		point.y = -1;
		return point;*/
	}

protected:
	// ******* Utilities (Not shuold using) ******************
	//std::vector<agh::CControlBase*> m_ctrlPtrAry; -> 既にアリマシタ…

	//	Get Control Pointer from Position
	CVisualControlBase* GetPosControl(int x, int y)
	{
		//	コントロールで該当するものがあるか？
		//for(int i=0; i<m_ctrlPtrAry.size(); i++)

		/*	2009/09/30 ちゃんとイテレータ使いましょう
		for(int i=0; i<((int)m_ctrlPtrAry.size()); _vcpp(i))
		{
			CVisualControlBase *p = GetVCtrlPtr(i);
			_AGH_RECT& rect = p->GetRect();

			if ( agh::IsRectInternal(&rect, x, y) ){
				return p;
			}
		}
		*/

		for(vctrl_iterator it = vcbegin(); it != vcend(); it++)
		{
			CVisualControlBase *p = it.get();
			_AGH_RECT& rect = p->GetRect();

			if ( agh::IsRectInternal(&rect, x, y) ){
				return p;
			}
		}

		return NULL;
	}
	CVisualControlBase* GetCurPosControl(){
		_AGH_POINT point = GetCurPos();
		return GetPosControl( point.x, point.y );
	}

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

_AGH_EVENT_ACCESS_MODIFIER:
	/*
	//	左クリック系 : Left Click Events
	virtual void OnBackgroundLButtonClick(int x, int y){}
	virtual void OnBackgroundLButtonDblClk(int x, int y){}
	virtual void OnBackgroundLButtonDown(int x, int y){}
	virtual void OnBackgroundLButtonUp(int x, int y){}

	//	右クリック系 : Right Click Events
	virtual void OnBackgroundRButtonClick(int x, int y){}
	virtual void OnBackgroundRButtonDblClk(int x, int y){}
	virtual void OnBackgroundRButtonDown(int x, int y){}
	virtual void OnBackgroundRButtonUp(int x, int y){}

	//	真中クリック系 : Center(Wheel) Click Events
	virtual void OnBackgroundCButtonClick(int x, int y){}
	virtual void OnBackgroundCButtonDblClk(int x, int y){}
	virtual void OnBackgroundCButtonDown(int x, int y){}
	virtual void OnBackgroundCButtonUp(int x, int y){}
	virtual void OnBackgroundMButtonClick(int x, int y){}
	virtual void OnBackgroundMButtonDblClk(int x, int y){}
	virtual void OnBackgroundMButtonDown(int x, int y){}
	virtual void OnBackgroundMButtonUp(int x, int y){}

	//	マウス移動 : Move Mouse Events
	virtual void OnBackgroundMouseMove(int nPosX, int nPosY, int nMoveX, int nMoveY){}*/

	//	ホイール : Wheel Events
	virtual void OnBackgroundWheelUp(int count){}
	virtual void OnBackgroundWheelDown(int count){}

/*
#define _AGH_CScreenBase_EVTIMPL2(EVT_NAME, V1, V2)	\
		agh::CControlBase *pControl = GetCurPosControl();	\
		if ( pControl == NULL )	\
			pControl->On##EVT_NAME(x,y);	\
		else	\
			OnBackground##EVT_NAME(x,y);

	virtual void OnLButtonClick(int x, int y){	_AGH_CScreenBase_EVTIMPL2(LButtonClick,x,y) }
	virtual void OnLButtonDblClk(int x, int y){	_AGH_CScreenBase_EVTIMPL2(LButtonDblClk,x,y)}
*/

	//	1 Paramator
#define _AGH_CScreenBase_EVT1(EVT_NAME, TYPE1, V1)	\
	virtual void On##EVT_NAME(TYPE1 V1)	\
	{	\
		agh::CVisualControlBase *pControl = GetCurPosControl();	\
		if ( pControl != NULL )	\
			pControl->On##EVT_NAME(V1);	\
		else	\
			OnBackground##EVT_NAME(V1);	\
	}


		/*agh::CControlBase *pControl = GetCurPosControl();	\
		if ( pControl != NULL )	\
			/*pControl->On##EVT_NAME(V1,V2);*//*	\
			OnControl##EVT_NAME(pControl,V1,V2);	\
		else	\
			OnBackground##EVT_NAME(V1,V2);	\*/

	//	2 Paramator
#define _AGH_CScreenBase_EVT2(EVT_NAME, TYPE1, V1, TYPE2, V2)	\
	virtual void On##EVT_NAME(TYPE1 V1, TYPE2 V2)	\
	{	\
		bool bExist = false;	\
		for(vctrl_iterator it = vcbegin(); it != vcend(); it++)	\
		{	\
			CVisualControlBase *p = it.get();	\
			_AGH_RECT& rect = p->GetRect();	\
			\
			if ( agh::IsRectInternal(&rect, x, y) ){	\
				OnControl##EVT_NAME(p,V1,V2);	\
				bExist = true;	\
			}	\
			else	\
				OnControl##EVT_NAME##Outer(p,V1,V2);	\
		}	\
		if ( !bExist )	\
			OnBackground##EVT_NAME(V1,V2);	\
		else	\
			OnBackground##EVT_NAME##Outer(V1,V2);	\
	}	\
	\
	/** Background Method Define **/	\
	virtual void OnBackground##EVT_NAME(TYPE1 V1, TYPE2 V2){}	\
	\
	/** Control Method Define **/	\
	virtual void OnControl##EVT_NAME(CVisualControlBase *pControl, TYPE1 V1, TYPE2 V2){	\
		pControl->On##EVT_NAME(V1,V2);	\
	}	\
	\
	/** Background Method Define **/	\
	virtual void OnBackground##EVT_NAME##Outer(TYPE1 V1, TYPE2 V2){}	\
	\
	/** Control Method Define **/	\
	virtual void OnControl##EVT_NAME##Outer(CVisualControlBase *pControl, TYPE1 V1, TYPE2 V2){	\
		pControl->On##EVT_NAME##Outer(V1,V2);	\
	}


/*	2009/09/30  ちゃんとイテレータ使いましょう
#define _AGH_CScreenBase_EVT2(EVT_NAME, TYPE1, V1, TYPE2, V2)	\
	virtual void On##EVT_NAME(TYPE1 V1, TYPE2 V2)	\
	{	\
		bool bExist = false;	\
		for(int i=0; i<((int)m_ctrlPtrAry.size()); _vcpp(i))	\
		{	\
			CVisualControlBase *p = GetVCtrlPtr(i);	\
			_AGH_RECT& rect = p->GetRect();	\
			\
			if ( agh::IsRectInternal(&rect, x, y) ){	\
				OnControl##EVT_NAME(p,V1,V2);	\
				bExist = true;	\
			}	\
			else	\
				OnControl##EVT_NAME##Outer(p,V1,V2);	\
		}	\
		if ( !bExist )	\
			OnBackground##EVT_NAME(V1,V2);	\
		else	\
			OnBackground##EVT_NAME##Outer(V1,V2);	\
	}	\
	\
*/

	//	4 Paramator
#define _AGH_CScreenBase_EVT4(EVT_NAME, TYPE1, V1, TYPE2, V2, TYPE3, V3, TYPE4, V4)	\
	virtual void On##EVT_NAME(TYPE1 V1, TYPE2 V2, TYPE3 V3, TYPE4 V4)	\
	{	\
		bool bExist = false;	\
		for(vctrl_iterator it = vcbegin(); it != vcend(); it++)	\
		{	\
			CVisualControlBase *p = it.get();	\
			_AGH_RECT& rect = p->GetRect();	\
			\
			if ( agh::IsRectInternal(&rect, nPosX, nPosY) ){	\
				OnControl##EVT_NAME(p,V1,V2,V3,V4);	\
				bExist = true;	\
			}	\
			else	\
				OnControl##EVT_NAME##Outer(p,V1,V2,V3,V4);	\
		}	\
		if ( !bExist )	\
			OnBackground##EVT_NAME(V1,V2,V3,V4);	\
		else	\
			OnBackground##EVT_NAME##Outer(V1,V2,V3,V4);	\
	}	\
	\
	/** Background Method Define **/	\
	virtual void OnBackground##EVT_NAME(TYPE1 V1, TYPE2 V2, TYPE3 V3, TYPE4 V4){}	\
	\
	/** Control Method Define **/	\
	virtual void OnControl##EVT_NAME(CVisualControlBase *pControl, TYPE1 V1, TYPE2 V2, TYPE3 V3, TYPE4 V4){	\
		pControl->On##EVT_NAME(V1,V2,V3,V4);	\
	}	\
	\
	/** Background Method Define **/	\
	virtual void OnBackground##EVT_NAME##Outer(TYPE1 V1, TYPE2 V2, TYPE3 V3, TYPE4 V4){}	\
	\
	/** Control Method Define **/	\
	virtual void OnControl##EVT_NAME##Outer(CVisualControlBase *pControl, TYPE1 V1, TYPE2 V2, TYPE3 V3, TYPE4 V4){	\
		pControl->On##EVT_NAME##Outer(V1,V2,V3,V4);	\
	}

/*	2009/09/30  ちゃんとイテレータ使いましょう
#define _AGH_CScreenBase_EVT4(EVT_NAME, TYPE1, V1, TYPE2, V2, TYPE3, V3, TYPE4, V4)	\
	virtual void On##EVT_NAME(TYPE1 V1, TYPE2 V2, TYPE3 V3, TYPE4 V4)	\
	{	\
		bool bExist = false;	\
		for(int i=0; i<((int)m_ctrlPtrAry.size()); _vcpp(i))	\
		{	\
			CVisualControlBase *p = GetVCtrlPtr(i);	\
			_AGH_RECT& rect = p->GetRect();	\
			\
			if ( agh::IsRectInternal(&rect, nPosX, nPosY) ){	\
				OnControl##EVT_NAME(p,V1,V2,V3,V4);	\
				bExist = true;	\
			}	\
			else	\
				OnControl##EVT_NAME##Outer(p,V1,V2,V3,V4);	\
		}	\
		if ( !bExist )	\
			OnBackground##EVT_NAME(V1,V2,V3,V4);	\
		else	\
			OnBackground##EVT_NAME##Outer(V1,V2,V3,V4);	\
	}	\
	\
*/

	//	左クリック系 : Left Click Events
	_AGH_CScreenBase_EVT2(LButtonClick, int, x, int, y);
	_AGH_CScreenBase_EVT2(LButtonDblClk, int, x, int, y);
	_AGH_CScreenBase_EVT2(LButtonDown, int, x, int, y);
	_AGH_CScreenBase_EVT2(LButtonUp, int, x, int, y);

	//	右クリック系 : Right Click Events
	_AGH_CScreenBase_EVT2(RButtonClick, int, x, int, y);
	_AGH_CScreenBase_EVT2(RButtonDblClk, int, x, int, y);
	_AGH_CScreenBase_EVT2(RButtonDown, int, x, int, y);
	_AGH_CScreenBase_EVT2(RButtonUp, int, x, int, y);

	//	真中クリック系 : Center(Wheel) Click Events
	_AGH_CScreenBase_EVT2(CButtonClick, int, x, int, y);
	_AGH_CScreenBase_EVT2(CButtonDblClk, int, x, int, y);
	_AGH_CScreenBase_EVT2(CButtonDown, int, x, int, y);
	_AGH_CScreenBase_EVT2(CButtonUp, int, x, int, y);
	/*_AGH_CScreenBase_EVT2(MButtonClick, int, x, int, y);
	_AGH_CScreenBase_EVT2(MButtonDblClk, int, x, int, y);
	_AGH_CScreenBase_EVT2(MButtonDown, int, x, int, y);
	_AGH_CScreenBase_EVT2(MButtonUp, int, x, int, y);*/

	//	マウス移動 : Move Mouse Events
	_AGH_CScreenBase_EVT4(MouseMove, int, nPosX, int, nPosY, int, nMoveX, int, nMoveY);

	//	ホイール : Wheel Events
	_AGH_CScreenBase_EVT1(WheelUp, int, count);
	_AGH_CScreenBase_EVT1(WheelDown, int, count);
};


#endif//__SFJP_MYU__AGH_ScreenBase_H__
