#pragma once
#include "ManagedInterfaceBasicInterfaces.h"

/*!
	配列型の宣言
*/
class CWorkspaceNode;
typedef CArray<CWorkspaceNode,CWorkspaceNode&>	CWorkspaceNodeArray;

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

	CString	m_key;
	CString	m_data;
};

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

			if(index == -1)
				CArray<CWorkspaceKeyData>::Add(CWorkspaceKeyData(key,data));
			else
				SetAt(index, CWorkspaceKeyData(key,data));
		}
		else
		{
			CArray<CWorkspaceKeyData>::Add(CWorkspaceKeyData(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 CWorkspaceNode
{
	friend class CWorkspaceXMLReader;
	friend class CWorkspaceXMLWriter;

public:
	CWorkspaceNode(void);
	CWorkspaceNode(CString name);
	~CWorkspaceNode(void);

	/*********************************************************
		初期化など
	**********************************************************/
	//!	CArrayで利用するための、コピー演算子
	void operator=(const CWorkspaceNode &other);

	//!	全データクリア
	void Clear(void);

	//!	ノード名の設定
	void SetNodeName(CString name) { m_nodeName = name; };

	//!	ノード名の取得
	CString GetNodeName() { return(m_nodeName); };


	/*********************************************************
		Keyに関する処理
	**********************************************************/
	//!	データの設定
	void SetKeyData(CString key, CString data,int noCase);

	//!	データの取得
	CString GetKeyData(CString key, CString defaultData, int noCase);

	//!	データの削除
	void DeleteKey(CString key);

	//!	キー数を取得
	int GetKeyCount();

	//!	全てのキー名を文字列として取得
	int GetAllKey(IStringArrayPtr list);

	//!	全てのデータを文字列として取得
	int GetAllData(IStringArrayPtr list);

	//!	キーを検索
	int FindKeyData(CString sData, int noCase = FALSE, int pathCompare = FALSE);

	//!	キーをまとめて設定
	void ClearAndSetKeys(CStringArray &keys, CStringArray &datas);

	/******************************************************
		サブノードに関する処理
	*******************************************************/
	//!	サブノードを検索する
	CWorkspaceNode *GetSubNode(CString path, CString &key);

	//!	サブノードを追加する
	void AddSubNode(CString name);

	//!	ノードを削除する
	void DeleteNode(CString name);

	//!	サブノード数を得る
	int GetSubNodeCount();

	//!	全てのサブノード名を文字列として取得
	int GetAllSubNode(IStringArrayPtr list);


protected:
	/******************************************************
		入出力に関する処理
	*******************************************************/
	//!	サブノードを作成する
	CWorkspaceNode *AddNewSubNode(CString name);

	//!	サブノードをインデックスで取得する
	CWorkspaceNode *GetSubNodeByIndex(int index);

	//!	キーをインデックスで取得する
	CWorkspaceKeyData *GetKeyByIndex(int index);

protected:
	/******************************************************
		Keyに関する処理
	*******************************************************/
	//!	Keyの検索
	int FindKeyIndex(CString &key,int noCase);

	/******************************************************
		サブノードに関する処理
	*******************************************************/
	//!	サブノードを検索する
	int FindSubNodeIndex(CString name);

	/******************************************************
		その他の関数
	*******************************************************/
	//!	パスの解析
	int ParsePath(CString path, CString & topPath, CString & subPath);


protected:
	//!	このノードの持つデータ
	CWorkspaceKeyDataArray			m_keyData;

	//!	サブノート
	CWorkspaceNodeArray		m_subNode;

	//!	このノードの名前
	CString					m_nodeName;
};

