#pragma once

#include <afxtempl.h>
#include <afxmt.h>
#include <atlsimpcoll.h>


//	クリティカルセクション
#define	SCOPE_LOCK()\
	CSingleLock	__scopeLock(&m_scopeLock);\
	__scopeLock.Lock();


/*!
	\class CSortArray
	\brief ソートとコピーを実装する配列クラス
*/
template< class TYPE, class ARG_TYPE >
class CSortArray : public CArray<TYPE,ARG_TYPE>
{
public:
	//!	ソート
	void Sort()
	{
		int		Max = (int)GetSize(),i,j;
		TYPE	keyitem;

		for(i=1;i<Max;i++)
		{
			keyitem=GetAt(i);

			for(j=i-1;j>=0;j--)
			{
				if(ElementAt(j) > keyitem)
				{
					SetAt(j+1,ElementAt(j));
				}
				else
				{
					break;
				}
			}

			SetAt(j+1,keyitem);
		}
	}

	//!	反転ソート
	void RSort()
	{
		int		Max = (int)GetSize(),i,j;
		TYPE	keyitem;

		for(i=1;i<Max;i++)
		{
			keyitem=GetAt(i);

			for(j=i-1;j>=0;j--)
			{
				if(!(ElementAt(j) > keyitem))
				{
					SetAt(j+1,ElementAt(j));
				}
				else
				{
					break;
				}
			}

			SetAt(j+1,keyitem);
		}
	}

	//!	代入
	void operator=(const CSortArray<TYPE,ARG_TYPE> &other)
	{
		Copy(other);
	}

	//!	コンストラクタ
	CSortArray<TYPE,ARG_TYPE>()
	{
	}

	//!	コピーコンストラクタ
	CSortArray<TYPE,ARG_TYPE>(const CSortArray<TYPE,ARG_TYPE> &other)
	{
		Copy(other);
	}
	
	//!	検索
	int Find(ARG_TYPE find)
	{
		int		Max = (int)GetSize(),i;

		for(i=0;i<Max;i++)
		{
			if(find==GetAt(i))
				return(i);
		}
		return(-1);
	}

};


class CKeyData
{
public:
	CKeyData() {};
	CKeyData(CString key,CString data)
	{
		m_key = key;
		m_data = data;
	};

	CString	m_key;
	CString	m_data;
};

/*!
	\class CKeyDataArray
	\brief キーデータ配列クラス
*/
class CKeyDataArray : public CSortArray<CKeyData,CKeyData&>
{
public:
	//!	追加
	void Add(CString key,CString data,int overwrite=TRUE)
	{
		if(overwrite)
		{
			int index = Find(key);

			if(index == -1)
				CSortArray<CKeyData,CKeyData&>::Add(CKeyData(key,data));
			else
				SetAt(index,CKeyData(key,data));
		}
		else
		{
			CSortArray<CKeyData,CKeyData&>::Add(CKeyData(key,data));
		}
	};

	//!	取得
	CString Get(CString key,CString def, int noCase = FALSE)
	{
		int index = Find(key, noCase);

		if(index == -1)
			return(def);
		else
			return(GetAt(index).m_data);
	};

	//!	削除
	void Delete(CString key, int noCase = FALSE)
	{
		int index = Find(key, noCase);

		if(index != -1)
			RemoveAt(index);
	};


	//!	検索
	int Find(CString key, int noCase = FALSE)
	{
		if(noCase)
		{
			for(int i=0;i<GetSize();i++)
				if(GetAt(i).m_key.CompareNoCase(key) == 0)
					return(i);
			return(-1);
		}
		else
		{
			for(int i=0;i<GetSize();i++)
				if(GetAt(i).m_key == key)
					return(i);
			return(-1);
		}
	}
};

class CSortStringArray : public CSortArray<CString,CString&>
{
public:
	//!	ソート
	void SortNoCase()
	{
		int		Max = (int)GetSize(),i,j;
		CString	keyitem;

		for(i=1;i<Max;i++)
		{
			keyitem=GetAt(i);

			for(j=i-1;j>=0;j--)
			{
				if(ElementAt(j).CollateNoCase(keyitem) > 0)
				{
					SetAt(j+1,ElementAt(j));
				}
				else
				{
					break;
				}
			}

			SetAt(j+1,keyitem);
		}
	}
	
	//!	検索
	int FindString(CString str, int noCase)
	{
		for(int i=0;i<GetSize();i++)
		{
			if(noCase)
			{
				if(GetAt(i).CompareNoCase(str) == 0)
					return(i);
			}
			else
			{
				if(GetAt(i) == str)
					return(i);
			}
		}
	};
};



/************************************************************************************************/
/*	ポインタアレイ	*/
/************************************************************************************************/
/*!
	自動削除ポインタアレイ
*/
template< class TYPE>
class CAutoDeletePtrArray : public CTypedPtrArray<CPtrArray, TYPE*>
{
public:
	//!	デストラクタ
	virtual ~CAutoDeletePtrArray<TYPE>()
	{
		Clear();
	};

	//!	クリア
	void Clear()
	{
		//	全削除
		for(int i=0;i<GetCount();i++)
			delete GetAt(i);
		RemoveAll();
	};
};
