#pragma once

//! @file Utility/UI/Control.h
//! @brief コントロールクラスインクルードファイル

#include "Mix/HID/IMouse.h"
#include "Mix/Graphics/Utility/ICanvasRenderer.h"

#include "Utility/UI/Dialog.h"

namespace Utility{ namespace UI {

	//! @class Control
	//! @brief コントロールクラス
	class Control
	{
	protected:
		//! @struct UPDATE_EVENT_ARGS
		//! @brief 更新イベントパラメータ構造体
		struct UPDATE_EVENT_ARGS
		{
			Mix::Vector2 offset;					//!< 描画座標のオフセット
			Mix::HID::IMouse* pMouse;				//!< マウス
			Mix::Graphics::Utility::IFont* pFont;	//!< フォント
		};

		//! @struct DRAW_EVENT_ARGS
		//! @brief 描画イベントパラメータ構造体
		struct DRAW_EVENT_ARGS
		{
			Mix::Graphics::Utility::ICanvasRenderer* pCanvasRenderer;	//!< キャンバス

			Mix::Vector4 borderColor;					//!< ボーダーカラー
			Mix::Vector4 backgroundColor;				//!< バックグラウンドカラー１
			Mix::Vector4 darkBackgroundColor;			//!< バックグラウンドカラー２
			Mix::Vector4 darkDarkBackgroundColor;		//!< バックグラウンドカラー３
			Mix::Vector4 textColor;						//!< テキストカラー

			Mix::Vector4 selectedBackgroundColor;		//!< 選択時のバックグラウンドカラー
			Mix::Vector4 selectedTextColor;				//!< 選択時のテキストカラー
		};

	private:
		UI::Dialog* m_pParent;

		UInt32 m_ID;

		Mix::Vector2 m_Pos;
		Mix::Vector2 m_Size;

		Boolean m_bEnabled;
		Boolean m_bFocus;
		Boolean m_bDispose;

	public:
		//! @brief コンストラクタ
		Control( void );
		//! @brief デストラクタ
		virtual ~Control( void );

		//! @brief 初期化します
		//! @param[in] pParent 親になるダイアログのポインタ
		//! @param[in] id 自身のID
		void Initialize( UI::Dialog* pParent, UInt32 id );

		//! @brief 親のダイアログのポインタを取得します
		//! @return 親のダイアログのポインタを返します
		UI::Dialog* GetParent( void ) const;
		//! @brief 自身のIDを取得します
		//! @return 自身のIDを返します
		UInt32 GetID( void ) const;

		//! @brief 位置を設定します
		//! @param[in] pos 位置
		void SetPosition( const Mix::Vector2& pos );
		//! @brief 位置を取得します
		//! @return 位置を返します
		const Mix::Vector2& GetPosition( void ) const;

		//! @brief サイズを設定します
		//! @param[in] size サイズ
		void SetSize( const Mix::Vector2& size );
		//! @brief サイズを取得します
		//! @return サイズを返します
		const Mix::Vector2& GetSize( void ) const;

		//! @brief 有効にするかどうかを設定します
		//! @param[in] state 有効にする場合は True
		void SetEanbled( Boolean state );
		//! @brief 有効かどうかを取得します
		//! @return 有効な場合は True を返します
		Boolean GetEnabled( void ) const;

		//! @brief フォーカスされているかどうかを取得します
		//! @return フォーカスされている場合は True を返します
		Boolean IsFocus( void ) const;
		//! @brief 破棄されているかどうかを取得します
		//! @return 破棄されている場合は True を返します
		Boolean IsDispose( void ) const;

	protected:
		//! @brief コントロールを更新します
		//! @param[in] args 更新パラメータ
		virtual void Update( const Control::UPDATE_EVENT_ARGS& args ) = 0;

		//! @brief コントロールの矩形を取得します
		//! @return コントロールの矩形を返します
		virtual const Mix::RectangleF& GetRectangle( void ) const = 0;

		//! @brief 初期化する際に呼び出されます
		virtual void OnInitialize( void ) {}
		//! @brief 破棄する際に呼び出されます
		virtual void OnDispose( void ) {}

		//! @brief マウスカーソルが移動した際に呼び出されます
		//! @param[in] pMosue マウス
		virtual void OnMouseMove( Mix::HID::IMouse* pMouse ) {}
		//! @brief マウスカーソルがコントロール内に入った際に呼び出されます
		//! @param[in] pMosue マウス
		virtual void OnMouseEnter( Mix::HID::IMouse* pMouse ) {}
		//! @brief マウスカーソルがコントロール外に出た際に呼び出されます
		//! @param[in] pMosue マウス
		virtual void OnMouseLeave( Mix::HID::IMouse* pMouse ) {}
		//! @brief マウスボタンが押された際に呼び出されます
		//! @param[in] pMosue マウス
		virtual void OnMouseDown( Mix::HID::IMouse* pMouse ) {}
		//! @brief マウスボタンが離された際に呼び出されます
		//! @param[in] pMosue マウス
		virtual void OnMouseUp( Mix::HID::IMouse* pMouse ) {}

		//! @brief コントロールを描画する際に呼び出されます
		//! @param[in] args コントールの描画パラメータ
		virtual void OnDraw( const Control::DRAW_EVENT_ARGS& args ) {}

	private:
		void SetFocus( Boolean state );
		void Dispose( void );

		friend class Dialog;
	};
}}
