#pragma once
#include "SimpleArrayTemplate.h"

#define	PAIR_STRING_KEY_LEN			128
#define	PAIR_STRING_DATA_LEN		256
#define	PAIR_STRING_ARRAY_GROW_SIZE	5


/*!
	ワークスペース用記録領域
*/
class CWorkspaceKeyPair
{
public:
	CWorkspaceKeyPair() {};
	CWorkspaceKeyPair(LPCSTR key,LPCSTR data)
	{
		m_key = key;
		m_data = data;
	};

	//!	設定
	void SetPair(LPCSTR key, LPCSTR data)
	{
		m_key = key;
		m_data = data;
	}

	//!	キー取得
	LPCSTR GetKey()
	{
		return	m_key;
	}

	//!	データ取得
	LPCSTR GetData()
	{
		return	m_data;
	}

private:
	//!	キー
	CWorkspaceString<PAIR_STRING_KEY_LEN>	m_key;

	//!	データ
	CWorkspaceString<PAIR_STRING_DATA_LEN>	m_data;
};


/*!
	キーペア用メモリプール
*/
class IWorkspaceKeyPairArrayMemoryPool
{
public:
	//!	メモリブロック確保
	virtual void *AllocMemoryBlock(int blockSize, int count) = 0;

	//!	メモリブロック開放
	virtual void FreeMemoryBlock(void *memPtr) = 0;

	//!	最適チャンクサイズ取得
	int GetChunkSize()
	{
		return sizeof(CWorkspaceKeyPair) * PAIR_STRING_ARRAY_GROW_SIZE;
	}
};

/*!
	\class CWorkspaceKeyPairArray
	\brief キーデータ配列クラス
*/
class CWorkspaceKeyPairArray : public CSimpleArrayTemplate<CWorkspaceKeyPair, CWorkspaceKeyPair&, CSimpleArrayTemplateItmeConstructor<CWorkspaceKeyPair>, PAIR_STRING_ARRAY_GROW_SIZE>
{
public:
	//!	コンストラクタ
	CWorkspaceKeyPairArray(IWorkspaceKeyPairArrayMemoryPool *pool = NULL)
	{
		m_memoryPool = pool;
	}

	//!	メモリプール取得
	IWorkspaceKeyPairArrayMemoryPool *GetMemoryPool() const
	{
		return m_memoryPool;
	}

	///////////////////////////////////////////////////////////////////////////////////
	//	キーペア操作
	///////////////////////////////////////////////////////////////////////////////////
	//!	強制追加
	void AddNoCompare(LPCSTR key, LPCSTR data)
	{
		CSimpleArrayTemplate<	CWorkspaceKeyPair, 
								CWorkspaceKeyPair&,
								CSimpleArrayTemplateItmeConstructor<CWorkspaceKeyPair>,
								PAIR_STRING_ARRAY_GROW_SIZE>
			::Add(CWorkspaceKeyPair(key,data));
	}

	//!	確保
	void Add(LPCSTR key, LPCSTR data, int noCase = FALSE)
	{
		int index = Find(key, noCase);
		if(index == -1)
			CSimpleArrayTemplate<	CWorkspaceKeyPair, 
									CWorkspaceKeyPair&,
									CSimpleArrayTemplateItmeConstructor<CWorkspaceKeyPair>,
									PAIR_STRING_ARRAY_GROW_SIZE>
				::Add(CWorkspaceKeyPair(key,data));
		else
		{
			GetAt(index).SetPair(key, data);
		}
	}

	//!	取得
	LPCSTR Get(LPCSTR key, LPCSTR defVal, int noCase = FALSE)
	{
		int index = Find(key, noCase);
		if(index == -1)
			return(defVal);
		else
			return(GetAt(index).GetData());
	}

	//!	削除
	void Delete(LPCSTR key, int noCase = FALSE)
	{
		int index = Find(key, noCase);
		if(index != -1)
			RemoveAt(index);
	}

	//!	検索
	int Find(LPCSTR key, int noCase = FALSE)
	{
		if(noCase)
		{
			for(int i=0;i<GetCount();i++)
				if(_strcmpi(GetAt(i).GetKey(), key) == 0)
					return(i);
			return(-1);
		}
		else
		{
			for(int i=0;i<GetCount();i++)
				if(strcmp(GetAt(i).GetKey(), key) == 0)
					return(i);
			return(-1);
		}
	}

	//!	指定位置を取得
	_inline CWorkspaceKeyPair *GetByIndex(int index)
	{
		return(&GetAt(index));
	}

protected:
	///////////////////////////////////////////////////////////////////////////////////
	//	オーバーロード
	///////////////////////////////////////////////////////////////////////////////////
	//!	メモリブロック確保
	virtual void *AllocMemoryBlock(int blockSize, int count)
	{
		if(m_memoryPool)
			return m_memoryPool->AllocMemoryBlock(blockSize, count);
		else
			return new BYTE[blockSize * count];
	}

	//!	メモリブロック開放
	virtual void FreeMemoryBlock(void *memPtr)
	{
		if(m_memoryPool)
			m_memoryPool->FreeMemoryBlock(memPtr);
		else
			delete (BYTE*)memPtr;
	}

	///////////////////////////////////////////////////////////////////////////////////
	//	メンバ変数
	///////////////////////////////////////////////////////////////////////////////////
	//!	メモリプール
	IWorkspaceKeyPairArrayMemoryPool	*m_memoryPool;
};

