#include "StdAfx.h"
#include "WorkspaceXMLReader.h"


CWorkspaceXMLReader::CWorkspaceXMLReader(void)
{
}

CWorkspaceXMLReader::~CWorkspaceXMLReader(void)
{
}

void CWorkspaceXMLReader::LoadFromFile(CWorkspaceNode *root, CString path, CString workspaceClassType)
{
	m_curNode = root;
	m_inKeyLeaf = 0;
	m_depth.RemoveAll();
	m_workspaceClassType = workspaceClassType;

	StartScan(LoadXmlFile(path));

	//	最終チェック
	if(m_depth.GetCount())
			throw CXMLTextParserException(_T("Subnodeが閉じていません"), m_dataLen - m_xmlData.GetLength());
}

/*!
	XML読み込み(throw CXMLTextParserException)
*/
void CWorkspaceXMLReader::FromString(CWorkspaceNode *root, CStringA str, CString workspaceClassType)
{
	m_curNode = root;
	m_inKeyLeaf = 0;
	m_depth.RemoveAll();
	m_workspaceClassType = workspaceClassType;

	StartScan(str);

	//	最終チェック
	if(m_depth.GetCount())
			throw CXMLTextParserException(_T("Subnodeが閉じていません"), m_dataLen - m_xmlData.GetLength());
}


/////////////////////////////////////////////////////////////////////////////////////
//	実装
/////////////////////////////////////////////////////////////////////////////////////
/*!
	開始タグ
*/
void CWorkspaceXMLReader::OnStartTag(CString tag, CTagOptionArray &keys)
{
	//	チェック
	if(m_inKeyLeaf)
		throw CXMLTextParserException(_T("Key内にタグは記述できません"), m_dataLen - m_xmlData.GetLength());

	//	タグ
	if(tag == "Subnode" || tag == "Node")
	{
		//	チェック
		if(keys.GetSize() != 1 || keys[0].m_key != "name")
			throw CXMLTextParserException(_T("無効なSubnodeタグです"), m_dataLen - m_xmlData.GetLength());

		//	最上位？
		if(m_depth.GetCount() == 0)
		{
			if(keys[0].m_data != m_workspaceClassType)
				throw CXMLTextParserException(_T("最初のSubnodeが存在しません"), m_dataLen - m_xmlData.GetLength());
			else
				m_depth.AddHead(m_curNode);
		}
		else
		{
			//	追加
			m_curNode = m_curNode->AddNewSubNode(keys[0].m_data); 
			if(m_curNode == NULL)
				throw CXMLTextParserException(_T("同名のSubnodeが存在します"), m_dataLen - m_xmlData.GetLength());
			m_depth.AddHead(m_curNode);
		}
	}
	else if(tag == "Key" || tag == "Leaf")
	{
		//	チェック
		if(m_depth.GetCount() == 0 || keys.GetSize() != 1 || (keys[0].m_key != "name" && keys[0].m_key != "key"))
			throw CXMLTextParserException(_T("無効なKeyタグです"), m_dataLen - m_xmlData.GetLength());
		m_inKeyLeaf = 1;
		m_keyName = keys[0].m_data;
	}
	else if(tag == "CWorkspaceClass" || tag == "CConfigClass")
	{
		//	チェック
		if(m_depth.GetCount() != 0 || keys.GetSize() != 1 || keys[0].m_key != "type")
			throw CXMLTextParserException(_T("無効なCWorkspaceClassタグです"), m_dataLen - m_xmlData.GetLength());

		//	クラス名チェック
		if(m_workspaceClassType !=  keys[0].m_data)
			throw CXMLTextParserException(_T("ワークスペース名が異なります、ロードできません"), m_dataLen - m_xmlData.GetLength());
	}
	else
	{
		throw CXMLTextParserException(_T("無効なタグです: ") + tag, m_dataLen - m_xmlData.GetLength());
	}
}

/*!
	終了タグ
*/
void CWorkspaceXMLReader::OnEndTag(CString tag)
{
	//	タグ
	if(tag == "Subnode" || tag == "Node")
	{
		//	チェック
		if(m_inKeyLeaf)
			throw CXMLTextParserException(_T("Key内にタグは記述できません"), m_dataLen - m_xmlData.GetLength());

		//	ノード深さチェック
		if(m_depth.GetCount() <= 0)
			throw CXMLTextParserException(_T("Subnodeタグの対応が異常です"), m_dataLen - m_xmlData.GetLength());

		m_depth.RemoveHead();

		//	最上位？
		if(m_depth.GetCount() != 0)
			m_curNode = m_depth.GetHead();
		else
			m_curNode = NULL;
	}
	else if(tag == "Key" || tag == "Leaf")
	{
		//	チェック
		if(!m_inKeyLeaf)
			throw CXMLTextParserException(_T("無効な終了タグです"), m_dataLen - m_xmlData.GetLength());
		m_inKeyLeaf = 0;
	}
	else if(tag == "CWorkspaceClass" || tag == "CConfigClass")
	{
		//	チェック
		if(m_inKeyLeaf)
			throw CXMLTextParserException(_T("Key内にタグは記述できません"), m_dataLen - m_xmlData.GetLength());
	}
	else
	{
		throw CXMLTextParserException(_T("無効なタグです"), m_dataLen - m_xmlData.GetLength());
	}
}

/*!
	特殊タグ
*/
void CWorkspaceXMLReader::OnSpecialTag(CString tag)
{
}

/*!
	データ
*/
void CWorkspaceXMLReader::OnData(CString data)
{
	if(m_inKeyLeaf)
	{
		m_curNode->SetKeyData(m_keyName, data, FALSE);
	}
	else
	{
		data.Trim();
		if(!data.IsEmpty())
			throw CXMLTextParserException(_T("無効なデータです"), m_dataLen - m_xmlData.GetLength());
	}
}
