#include "StdAfx.h"
#include "WorkspaceNode.h"


//////////////////////////////////////////////////////////////////////////////////////////
//	初期化など
//////////////////////////////////////////////////////////////////////////////////////////
CWorkspaceNode::CWorkspaceNode()
{
}

CWorkspaceNode::CWorkspaceNode(LPCU8STR name)
{
	SetNodeName(name);
}

CWorkspaceNode::CWorkspaceNode(const CWorkspaceNode &other)
{
	SetNodeName(other.GetNodeName());
	m_keyData.Copy(other.m_keyData);
	m_subNode.Copy(other.m_subNode);
}


CWorkspaceNode::~CWorkspaceNode(void)
{
}

//	コピーオペレータ
void CWorkspaceNode::operator=(const CWorkspaceNode &other)
{
	//	データのコピー
	SetNodeName(other.GetNodeName());
	m_keyData.Copy(other.m_keyData);
	m_subNode.Copy(other.m_subNode);
}

//	全てクリア
void CWorkspaceNode::Clear(void)
{
	//	データ削除
	m_keyData.RemoveAll();
	m_subNode.RemoveAll();
}


//////////////////////////////////////////////////////////////////////////////////////////
//	Keyに対する処理(Public)
//////////////////////////////////////////////////////////////////////////////////////////
/*!
	データの設定

	このノードのデータに対するアクセス
*/
void CWorkspaceNode::SetKeyData(LPCU8STR key, LPCU8STR data, int noCase)
{
	m_keyData.Add(key, data,  noCase);
}

/*!
	データの取得

	このノードのデータに対するアクセス
*/
LPCU8STR CWorkspaceNode::GetKeyData(LPCU8STR key, LPCU8STR defaultData, int noCase)
{
	return m_keyData.Get(key, defaultData,  noCase);
}


/*!
	データの削除

	このノードのデータに対するアクセス
*/
void CWorkspaceNode::DeleteKey(LPCU8STR key)
{
	m_keyData.Delete(key);
}


/*!
	キー数を取得
*/
int CWorkspaceNode::GetKeyCount()
{
	return((int)m_keyData.GetCount());
}

/*!
	全てのキーを文字列として取得
*/
int CWorkspaceNode::GetAllKeyPair(IStringArrayPtr keys, IStringArrayPtr datas)
{
	//	サイズ初期化
	int count = (int)m_keyData.GetCount();
	if(keys != NULL)
		keys->SetSize(count);
	if(datas != NULL)
		datas->SetSize(count);

	//	設定
	for(int i=0;i<count;i++)
	{
		CWorkspaceKeyPair	*keyPair = m_keyData.GetByIndex(i);

		//	NULLでなければ設定
		if(keys != NULL)
			keys->SetString(i, keyPair->GetKey());
		if(datas != NULL)
			datas->SetString(i, keyPair->GetData());
	}

	return(count);
}


/*!
	キーをまとめて設定
*/
void CWorkspaceNode::ClearAndSetKeys(CUTF8StringArray &keys, CUTF8StringArray &datas)
{
	//	全削除
	m_keyData.RemoveAll();

	//	設定
	for(int i=0;i<keys.GetCount();i++)
		m_keyData.AddNoCompare(keys[i], datas[i]);
}

//////////////////////////////////////////////////////////////////////////////////////////
//	Keyに対する処理(Protect)
//////////////////////////////////////////////////////////////////////////////////////////
/*!
	Leafの検索
*/
int CWorkspaceNode::FindKeyIndex(LPCU8STR key,int noCase)
{
	return(m_keyData.Find(key, noCase));
}

//////////////////////////////////////////////////////////////////////////////////////////
//	サブノードに対する処理(Public)
//////////////////////////////////////////////////////////////////////////////////////////
/*!
	サブノードを検索する
*/
CWorkspaceNode *CWorkspaceNode::GetSubNode(CWorkspaceNodeWalker &path, CUTF8String &key)
{
	//	最後？
	if(path.CurrentIsLastNode())
	{
		//	自分のキー
		key = path.GetCurrentNode();
		return this;
	}
	else
	{
		//	自分のサブノードを検索
		CWorkspaceNode *subNode = GetSubNodeByName(path.GetCurrentNode());

		//	さらに下を検索
		path.WalkToNextNode();
		return(subNode->GetSubNode(path, key));
	}
}


/*!
	ノードを削除する

*/
void CWorkspaceNode::DeleteNode(LPCU8STR name)
{
	int index = FindSubNodeIndex(name);
	if(index != -1)
		m_subNode.RemoveAt(index);
}


/*!
	サブノード数を得る
*/
int CWorkspaceNode::GetSubNodeCount()
{
	return((int)m_subNode.GetCount ());
}


/*!
	全てのサブノード名を文字列として取得

	自分のサブノードのみです。
	下位ノードへは検索に行きません
*/
int CWorkspaceNode::GetAllSubNode(IStringArrayPtr list)
{
	//	サイズ初期化
	int count = (int)m_subNode.GetCount ();
	list->SetSize(count);

	//	設定
	for(int i=0;i<count;i++)
		list->SetString(i, m_subNode[i].GetNodeName());

	return(count);
}



//////////////////////////////////////////////////////////////////////////////////////////
//	サブノードに対する処理(Protected)
//////////////////////////////////////////////////////////////////////////////////////////
/*!
	サブノードを検索する
*/
int CWorkspaceNode::FindSubNodeIndex(LPCU8STR name)
{
	for(int i=0;i<(int)m_subNode.GetCount();i++)
	{
		if(strcmp((LPCSTR)m_subNode[i].GetNodeName(), (LPCSTR)name) == 0)
			return(i);
	}
	return -1;
}


/***********************************************************************************
	入出力に関する処理
***********************************************************************************/
/*!
	サブノードを名前から取得・作成する

	\param errorIfExist	TRUEだと、既に存在している場合にエラーとなる
*/
CWorkspaceNode *CWorkspaceNode::GetSubNodeByName(LPCU8STR name, int errorIfExist)
{
	int	index = FindSubNodeIndex(name);
	if(index == -1)
	{
		//	追加
		m_subNode.Add(CWorkspaceNode(name));
		return &m_subNode[m_subNode.GetCount ()-1];
	}

	//	エラー扱い？
	if(errorIfExist)
		return(NULL);
	return(&m_subNode[index]);
}


/*!
	サブノードをインデックスで取得する
*/
CWorkspaceNode *CWorkspaceNode::GetSubNodeByIndex(int index)
{
	if(index < 0 || index >= (int)m_subNode.GetCount())
		return(NULL);

	return(&m_subNode[index]);
}

/*!
	キーをインデックスで取得する
*/
CWorkspaceKeyPair *CWorkspaceNode::GetKeyByIndex(int index)
{
	if(index < 0 || index >= m_keyData.GetCount())
		return(NULL);

	return(m_keyData.GetByIndex(index));
}

