#ifndef __SFJP_MYU__AGH_ControlArray_H__
#define __SFJP_MYU__AGH_ControlArray_H__


//	アイテム
template <typename BASE_T>
class CControlArrayItem : public BASE_T
{
public:
	//	コンストラクタ・デストラクタ
	CControlArrayItem(){}
	CControlArrayItem(int nTypeFlg) : BASE_T(nTypeFlg) {}
	virtual ~CControlArrayItem(){}
};


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


//	CControlArrayT
template <typename CTRL_T, typename MAPPING_T, typename KEY_T>
class CControlArrayT : public agh::CVisualControlBase
{
public:
	typedef CTRL_T _CA_CTRL_T;

protected:
	class _CA_CTRL_T2 : public _CA_CTRL_T
	{
	public:
		//	コンストラクタ・デストラクタ
		_CA_CTRL_T2(){}
		_CA_CTRL_T2(int nTypeFlg) : _CA_CTRL_T(nTypeFlg) {}
		virtual ~_CA_CTRL_T2(){}
	};

public: // typedefs
	typedef agh::CControlBase _BASE;
	typedef MAPPING_T _CA_CTRL_ARY_TYPE;
	typedef typename MAPPING_T::iterator _CA_CTRL_ARY_ITERATOR;
	//typedef _agh_vector(CTRL_T) _CA_CTRL_ARY_TYPE;
	//typedef _agh_vector(CTRL_T)::iterator _CA_CTRL_ARY_ITERATOR;

protected:
	_CA_CTRL_ARY_TYPE m_ctrlAry;		//	子コントロール群（実体配列）: Child Control List

public:
	class ca_iterator
	{
	private:
		_CA_CTRL_ARY_ITERATOR m_it;
	public:
		ca_iterator(_CA_CTRL_ARY_ITERATOR it_in){ m_it = it_in; }
		virtual ~ca_iterator(){}

		void operator ++ (){ m_it++; }
		void operator ++ (int){ m_it++; }
		int operator != (ca_iterator it_in){ return ( m_it != it_in.m_it ? 1 : 0 ); }
		//bool operator != (ca_iterator it_in){ return m_it != it_in.m_it ? true : false; }
		KEY_T key(){ return m_it.key(); }
		CTRL_T* get(){ return m_it.operator ->(); }
		CTRL_T* operator -> (){ return get(); }
		operator CTRL_T* (){ return get(); }

		_CA_CTRL_ARY_ITERATOR get_internal_iterator(){ return m_it; }
		_CA_CTRL_ARY_ITERATOR get_primitive_iterator(){ return m_it; }
	};

	typedef ca_iterator iterator;

	ca_iterator cabegin(){ return ca_iterator(m_ctrlAry.begin()); }
	ca_iterator caend(){ return ca_iterator(m_ctrlAry.end()); }
	ca_iterator begin(){ return ca_iterator(m_ctrlAry.begin()); }
	ca_iterator end(){ return ca_iterator(m_ctrlAry.end()); }
	size_t casize(){ return m_ctrlAry.size(); }
	size_t size(){ return m_ctrlAry.size(); }

public:
	//	コンストラクタ
	CControlArrayT(){
		CTRL_T t;
		m_nTypeFlg = t.GetTypeFlag();
	}
	CControlArrayT(int nTypeFlg) : _BASE(nTypeFlg) {
	}
	virtual ~CControlArrayT(){}

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

	CTRL_T& Add(KEY_T key)
	{
		CTRL_T t;
		return Add(key, t);
		/*
		T t;
		m_ctrlAry.push_back(t);
		return *m_ctrlAry.rbegin.operator ->();
		*/
	}
	CTRL_T& Add(KEY_T key, CTRL_T &t)
	{
		m_ctrlAry[key] = t;
		//m_ctrlAry.insert(std::pair<key, CTRL_T>(key, t));

		//CTRL_T* p = m_ctrlAry.rbegin.operator ->();
		CTRL_T* p = Get(key);
		RegistControl(p);
		return *p;
	}
	CTRL_T* Get(KEY_T key)
	{
		if ( m_ctrlAry.find(key) == m_ctrlAry.end() )
			return NULL;
		CTRL_T* p = &(m_ctrlAry[key]);
		return p;
	}
	bool Remove(KEY_T key)
	{
		/*T* p = Get(index);
		if ( p == NULL )
			return false;*/
		if ( m_ctrlAry.find(key) == m_ctrlAry.end() )
			return false;
		m_ctrlAry.erase( m_ctrlAry[key] );
		return true;
	}
	void RemoveAll(){ m_ctrlAry.clear(); }
	void Clear(){ m_ctrlAry.clear(); }
};


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


//agh::CControlArrayT<agh::CWindowBase, std::map<agh::CControlArrayItem<agh::CWindowBase>, int>, int> a;

/*
template <typename KEY_T, typename CTRL_T>
class CControlMap_Map : public _AGH_MAP(KEY_T,CTRL_T)
{
private:
	typedef typename _AGH_MAP(KEY_T,CTRL_T) _BASE;
	typedef typename _AGH_MAP(KEY_T,CTRL_T)::iterator _BASE_ITR;

public:
	class iterator : public _BASE_ITR
	{
	public:
		iterator() : _BASE_ITR(){}
		iterator(_BASE_ITR it) : _BASE_ITR(it){}

		void operator = (_BASE_ITR it){ _BASE::operator = (it); }

		//CTRL_T* operator ->(){ return _BASE_ITR::operator ->(); }
		//CTRL_T* operator ->(){ return &((std::pair<KEY_T,CTRL_T>*)_BASE_ITR::operator ->())->second; }
		CTRL_T* operator ->(){ return &operator *().second; }

		KEY_T first(){ return &operator *().first; }
		KEY_T key(){ return &operator *().first; }
	};
};
*/


//	map
template <typename CTRL_T, typename KEY_T>
//class CControlMap : public CControlArrayT<CTRL_T, _AGH_MAP(KEY_T,CTRL_T), KEY_T>
//class CControlMap : public CControlArrayT<CTRL_T, CControlMap_Map<KEY_T,CTRL_T>, KEY_T>
class CControlMap : public CControlArrayT<CTRL_T, agh::map<KEY_T,CTRL_T>, KEY_T>
{
private:
	typedef CControlArrayT<CTRL_T, _AGH_MAP(KEY_T,CTRL_T), KEY_T> _BASE;
public:
	//	コンストラクタ
	CControlMap(){}
	CControlMap(int nTypeFlg) : _BASE(nTypeFlg) {
	}
	virtual ~CControlMap(){}
};


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


//	list
template <typename CTRL_T>
//class CControlList : public CControlArrayT<CTRL_T, _AGH_LIST(CTRL_T), int /* 使わないのでなんでもいいんだけどね・・・ */ >
class CControlList : public CControlArrayT<CTRL_T, agh::list<CTRL_T>, int /* 使わないのでなんでもいいんだけどね・・・ */ >
{
private:
	typedef CControlArrayT<CTRL_T, _AGH_LIST(CTRL_T), int> _BASE;
	//typedef typename _AGH_LIST(CTRL_T)::iterator iterator;
public:
	//	コンストラクタ
	CControlList(){}
	CControlList(int nTypeFlg) : _BASE(nTypeFlg) {
	}
	virtual ~CControlList(){}

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

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

	/*CTRL_T& Add()
	{
		CTRL_T t;
		return Add(t);
	}
	CTRL_T& Add(CTRL_T &t)
	{
		m_ctrlAry.push_back(t);
		CTRL_T* p = m_ctrlAry.rbegin().operator ->();
		RegistControl(p);
		return *p;
	}
	CTRL_T* Get(iterator it)
	{
		return it;
	}
	bool Remove(iterator it)
	{
		if ( it == m_ctrlAry.end() )
			return false;
		m_ctrlAry.erase( it );
		return true;
	}*/

	CTRL_T& Add()
	{
		CTRL_T t;
		return Add(t);
		/*
		T t;
		m_ctrlAry.push_back(t);
		return *m_ctrlAry.rbegin.operator ->();
		*/
	}
	CTRL_T& Add(CTRL_T &t)
	{
		m_ctrlAry.push_back(t);
		CTRL_T* p = m_ctrlAry.rbegin().operator ->();
		RegistControl(p);
		return *p;
	}
	CTRL_T* Get(iterator it)
	{
		return it;
	}
	bool Remove(iterator it)
	{
		if ( it == m_ctrlAry.end() )
			return false;
		m_ctrlAry.erase( it.get_internal_iterator() );
		return true;
	}
};


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

#ifdef VALID_CControlVector
//	vector
template <typename CTRL_T>
class CControlVector : public CControlArrayT<CTRL_T, _AGH_VECTOR(CTRL_T), size_t>
{
private:
	typedef CControlArrayT<CTRL_T, _AGH_VECTOR(CTRL_T), size_t> _BASE;
public:
	//	コンストラクタ
	CControlVector(){}
	CControlVector(int nTypeFlg) : _BASE(nTypeFlg) {
	}
	virtual ~CControlVector(){}

	/**** vector用にオーバーライド *******************************************/

	CTRL_T& Add()
	{
		CTRL_T t;
		return Add(t);
		/*
		T t;
		m_ctrlAry.push_back(t);
		return *m_ctrlAry.rbegin.operator ->();
		*/
	}
	CTRL_T& Add(CTRL_T &t)
	{
		m_ctrlAry.push_back(t);
		CTRL_T *p = &(m_ctrlAry[m_ctrlAry.size()-1]);
		RegistControl(p);
		return *p;
	}
	CTRL_T* Get(unsigned int index)
	{
		if ( index > m_ctrlAry.size() )
			return NULL;
		return &m_ctrlAry[index];
	}
	bool Remove(unsigned int index)
	{
		/*T* p = Get(index);
		if ( p == NULL )
			return false;*/
		if ( index > m_ctrlAry.size() )
			return false;
		return m_ctrlAry.erase[index];
		return true;
	}
};
#endif


//typedef CControlList CControlArray;
template <typename CTRL_T>
class CControlArray : public CControlList<CTRL_T> {
public:
	CControlArray(){}
	CControlArray(int nTypeFlg) : CControlList<CTRL_T>(nTypeFlg) {}
	virtual ~CControlArray(){}
};

template <typename CTRL_T>
class CControlPool : public CControlList<CTRL_T> {
public:
	CControlPool(){}
	CControlPool(int nTypeFlg) : CControlList<CTRL_T>(nTypeFlg) {}
	virtual ~CControlPool(){}
};

#endif//__SFJP_MYU__AGH_ControlArray_H__
