#pragma once
#include "SortArray.h"
#import <msxml.dll>
#include "buffer.h"

class CConfigSwapBase
{
public:
	virtual ~CConfigSwapBase();
	virtual CString & SwapString(CString &key,CString &data) = 0;
};

class CConfigNode
{
public:
	//	データ保持クラス
	class CConfigKey
	{
	public:
		CString	m_key;
		CString	m_data;

		CConfigKey() {};
		CConfigKey(CString key,CString data) {m_key = key;m_data = data;};
	};

public:
	CConfigNode(void);
	~CConfigNode(void);

	void SetConfig(CString path, CString data);																//	コンフィグデータの設定
	CString GetConfig(CString path, CString defaultData,CConfigSwapBase *swap=NULL,int noCase=FALSE);		//	コンフィグデータ取得
	void SaveToXml(MSXML::IXMLDOMDocumentPtr doc,MSXML::IXMLDOMElementPtr element,CString indent="\n\t");	//	XMLへ保存
	void LoadFromXml(MSXML::IXMLDOMDocumentPtr doc,MSXML::IXMLDOMNodePtr cur);			//	XMLからロード
	void Clear(void);																	//	全てクリア
	int GetAllKey(CStringArray &list);													//	全てのキーを取得
	int GetAllSubNode(CStringArray &list);												//	全てのサブノードを取得
	CConfigNode *GetSubNode(CString path, CString &key);								//	自分の仮想のノードを取得
	void DeleteNode(CString name);														//	ノード削除
	void DeleteKey(CString name);														//	キー削除
	int GetKeyCount();																	//	全てのキー数を取得
	int GetSubNodeCount();																//	全てのサブノードを数取得
	CString GetKeySwapString(CString str,CString noData,CConfigSwapBase *swap=NULL);	//	キー名で置き換えた文字列を取得
	void ToString(CBuffer &buf);
	int FromString(char **ptr);

	CString	m_name;																		//	ノード名

protected:
	int ParsePath(CString path, CString & topPath, CString & subPath);					//	パスの解析
	int GetKeyIndex(CString key,int noCase);											//	自分のキーを検索
	int GetSubNodeIndex(CString name);													//	サブノードを検索

	CSortArray<CConfigNode,CConfigNode&>	m_subNode;									//	サブキー
	CSortArray<CConfigKey,CConfigKey&>		m_curData;									//	自分のデータ

	void AddStartNode(CBuffer &buf);
	void AddEndNode(CBuffer &buf);
	void AddLeaf(CBuffer &buf,CString &key,CString &data);
	void AddOneText(CBuffer &buf,CString &str);

	CString GetOneText(char **ptr);

public:
	enum
	{
		START_NODE =	'S',
		END_NODE =		'E',
		LEAF =			'L',
		END =			0,
	};
};
