#include"CGUIRadioButton.h"

namespace Maid
{
	/*!
	 *	\class	ButtonListener CGUIRadioButton.h
	 *	\brief	ラジオボタンの内部で使用しているボタンリスナ
	 */
	class ButtonListener : public CGUIButton::Listener
	{
	public:
		ButtonListener( const CGUIRadioButton* p ) : m_pOwner(p){}
		virtual bool IsCollision( const POINT2DI& pos ) const
		{
			return m_pOwner->GetListener()->IsCollision( pos );
		}
	private:
		const CGUIRadioButton*	m_pOwner;
	};

	/*!
	 *	\class	CGUIRadioButton CGUIRadioButton.h
	 *	\brief	ラジオボタンクラス
	\n			これ単体でラジオボタンっぽい動作するけど、
	\n			１インスタンス１ボタンなので、グループ設定をする必要がある
	 */
enum PARTSID
{
	PARTSID_BUTTON=0,
};
/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! コンストラクタ
/*!
 *
 */
CGUIRadioButton::CGUIRadioButton()
{
	m_IsCheck = false;

	m_Button.SetID(PARTSID_BUTTON);
	m_Button.SetCallBack( MakeGUICallBackObject(&CGUIRadioButton::GUICallBack,this) );
	m_Button.SetListener( SPGUIBUTTONLISTENER( new ButtonListener(this) ) );
}

CGUIRadioButton::CGUIRadioButton( const CGUIRadioButton& button ) : IGUIParts( button )
{
	Copy( button );
}

CGUIRadioButton::~CGUIRadioButton()
{
	if( m_pGroup.get()!=NULL )
	{
		for( int i=0; i<(int)m_pGroup->m_GroupList.size(); ++i )
		{
			if( m_pGroup->m_GroupList[i]==this )
			{
				m_pGroup->m_GroupList.erase( m_pGroup->m_GroupList.begin()+i );
			}
		}
	}
}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! リスナの登録
/*!	リスナを登録しない場合、まったく動かないので注意！
 *
 *	\param	pListener	[i ]	新しいリスナ
 */
void	CGUIRadioButton::SetListener( const SPGUIRADIOBUTTONLISTENER& pListener )
{
	m_pListener = pListener;
	m_pListener->m_pOwner = this;
}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! リスナの取得
/*!
 *	\return すでに設定されているリスナ
 */
const SPGUIRADIOBUTTONLISTENER&	CGUIRadioButton::GetListener() const
{
	return m_pListener;
}


/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! チェックされているか？
/*!
 *	\return チェックされているなら true
 */
bool CGUIRadioButton::IsCheck() const
{
	return m_IsCheck;
}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! チェック状態の変更
/*!
 *	\param	IsCheck	[i ]	チェック状態にするなら true
 */
void CGUIRadioButton::SetCheck( bool IsCheck )
{
	if( IsCheck )
	{
		if( m_pGroup.get()!=NULL )
		{
			for( int i=0; i<(int)m_pGroup->m_GroupList.size(); ++i )
			{
				CGUIRadioButton* pButton = m_pGroup->m_GroupList[i];
				if( pButton==this ) { continue; }

				pButton->SetCheck(false);
			}
		}
	}

	m_IsCheck = IsCheck;
}



CGUIRadioButton& CGUIRadioButton::operator = ( const CGUIRadioButton& rha )
{
	Copy( rha );

	return *this;
}

void CGUIRadioButton::SetGroup( const SPGUIRADIOBUTTONGROUP& pGroup )
{
	m_pGroup = pGroup;

	if( m_pGroup.get()!=NULL )
	{
		m_pGroup->m_GroupList.push_back( this );
	}
}

void CGUIRadioButton::Copy( const CGUIRadioButton& rha )
{
	m_Button	= rha.m_Button;
	m_pListener = rha.m_pListener;
	m_IsCheck	= rha.m_IsCheck;
	m_pGroup = rha.m_pGroup;
	m_Button.SetID(PARTSID_BUTTON);
	m_Button.SetCallBack( MakeGUICallBackObject(&CGUIRadioButton::GUICallBack,this) );
	m_Button.SetListener( SPGUIBUTTONLISTENER( new ButtonListener(this) ) );

	if( m_pGroup.get()!=NULL )
	{
		for( int i=0; i<(int)m_pGroup->m_GroupList.size(); ++i )
		{
			if( m_pGroup->m_GroupList[i]==&rha ) { m_pGroup->m_GroupList[i] = this; }
		}
	}

}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! フレーム毎の処理
/*!
 *	引数などは IGUIParts::OnLocalMove を参照すること
 */
void CGUIRadioButton::OnLocalMove()
{
	MAID_ASSERT( m_pListener.get()==NULL, "リスナの設定がされていません" );
	m_pListener->OnMove();
}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! フレーム毎の描画
/*!
 *	引数などは IGUIParts::OnLocalDraw を参照すること
 */
void CGUIRadioButton::OnLocalDraw( const POINT2DI& pos, CGraphic& Render )
{
	MAID_ASSERT( m_pListener.get()==NULL, "リスナの設定がされていません" );

	m_pListener->OnDraw( pos, Render );
}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! このパーツ内にカーソルがあるか？
/*!
 *	引数などは IGUIParts::IsLocalCollision を参照すること
 */
bool CGUIRadioButton::IsLocalCollision( const POINT2DI& pos ) const
{
	MAID_ASSERT( m_pListener.get()==NULL, "リスナの設定がされていません" );
	return m_pListener->IsCollision( pos );
}

void CGUIRadioButton::OnLocalMouseIn  ( const POINT2DI& pos )
{
	m_Button.OnMouseIn( pos );
}

void CGUIRadioButton::OnLocalMouseOut ( const POINT2DI& pos )
{
	m_Button.OnMouseOut( pos );
}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! マウスのボタンが押された時に呼ばれる
/*!
 *	引数などは IGUIParts::OnLocalMouseDown を参照すること
 */
void CGUIRadioButton::OnLocalMouseDown( const POINT2DI& pos )
{
	m_Button.OnMouseDown( pos );
}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! マウスのボタンが離された時に呼ばれる
/*!
 *	引数などは IGUIParts::OnLocalMouseUp を参照すること
 */
void CGUIRadioButton::OnLocalMouseUp  ( const POINT2DI& pos )
{
	m_Button.OnMouseUp( pos );
}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! マウスのカーソルが動いた時に呼ばれる
/*!
 *	引数などは IGUIParts::OnLocalMouseMove を参照すること
 */
void CGUIRadioButton::OnLocalMouseMove( const POINT2DI& pos )
{
	m_Button.OnMouseMove( pos );
}


/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! キーボードのキーが押された時に呼ばれる
/*!
 *	引数などは IGUIParts::OnLocalKeyDown を参照すること
 */
void CGUIRadioButton::OnLocalKeyDown( unt08 KeyCode )
{
	m_Button.OnKeyDown( KeyCode );
}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! キーボードのキーが押された時に呼ばれる
/*!
 *	引数などは IGUIParts::OnLocalKeyUp を参照すること
 */
void CGUIRadioButton::OnLocalKeyUp( unt08 KeyCode )
{
	m_Button.OnKeyUp( KeyCode );
}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! フォーカスがきたとき・さったときに呼ばれる
/*!
 *	引数などは IGUIParts::OnLocalFocusIn を参照すること
 */
void CGUIRadioButton::OnLocalFocusIn()
{
	m_Button.OnFocusIn();
}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! フォーカスがきたとき・さったときに呼ばれる
/*!
 *	引数などは IGUIParts::OnLocalFocusOut を参照すること
 */
void CGUIRadioButton::OnLocalFocusOut()
{
	m_Button.OnFocusOut();
}


/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! 状態が変わった時に呼ばれる
/*!
 *	引数などは IGUIParts::OnLocalChangeState を参照すること
 */
void CGUIRadioButton::OnLocalChangeState( bool NewStateEnable, bool NewStateVisible )
{
	MAID_ASSERT( m_pListener.get()==NULL, "リスナの設定がされていません" );
	m_pListener->OnChengeState( NewStateEnable, NewStateVisible );
}

/*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-*/
//! メンバに持っているＧＵＩパーツからコールバックされる関数
/*!
 *	\param	GUIParts	[i ]	ＧＵＩパーツ
 *	\param	Message		[i ]	送られてくるメッセージ
 */
void CGUIRadioButton::GUICallBack( unt32 GUIParts, GUIMESSAGE Message )
{
	switch( GUIParts )
	{
	case PARTSID_BUTTON:
		{
			switch( Message )
			{
			case GUIMESSAGE_PARTS_FOCUSIN:
				{
					m_pListener->OnFocusIn();
				}break;

			case GUIMESSAGE_PARTS_FOCUSOUT:
				{
					m_pListener->OnFocusOut();
				}break;

			case GUIMESSAGE_BUTTON_MOUSEDOWN:
				{
					m_pListener->OnMouseDown();
					CallBack(GUIMESSAGE_BUTTON_MOUSEDOWN);
				}break;

			case GUIMESSAGE_BUTTON_MOUSEUP:
				{
					m_pListener->OnMouseUp();
					CallBack(GUIMESSAGE_BUTTON_MOUSEUP);
				}break;

			case GUIMESSAGE_BUTTON_CLICK:
				{
					if( !m_IsCheck ) { SetCheck(true); }

					m_pListener->OnMouseClick();
					CallBack(GUIMESSAGE_RADIO_CHANGEBUTTON);
/*
					if( m_IsCheck )
					{
						//	今チェックされてて、押された場合　→　反応なし
					}else
					{
						SetCheck(true);
						m_pListener->OnMouseClick();
						CallBack(GUIMESSAGE_RADIO_CHANGEBUTTON);
					}
*/
				}break;
			}
		}break;
	}
}


}
