#include "StdAfx.h"
#include "WorkspaceXMLWriter.h"
#include "TypedBuffer.h"

CWorkspaceXMLWriter::CWorkspaceXMLWriter(void)
{
}

CWorkspaceXMLWriter::~CWorkspaceXMLWriter(void)
{
}

/*!
	XML出力(throw CWorkspaceXMLWriterException)
*/
CString CWorkspaceXMLWriter::ToString(CWorkspaceNode *root, CString workspaceClassType)
{
	m_xml.Empty();
	m_xml.SetGrowSize(65536);
	m_workspaceClassType = workspaceClassType;

	//	ヘッダ出力
	WriteHeader();

	//	データ出力
	CTextEscape	escape;
	escape.AddEscape(_T("<"), _T("&lt;"));
	escape.AddEscape(_T(">"), _T("&gt;"));
	escape.AddEscape(_T("&"), _T("&amp;"));
	WriteSubNode(root, escape, _T("\t"));

	//	フッタ出力
	WriteFooter();

	//	UTF16へ変換
	CStringW			utf16(m_xml.GetCString());

	//	UTF8へ変換
	int mbLen = WideCharToMultiByte(CP_UTF8, 0, utf16.GetBuffer(0), utf16.GetLength(), NULL, 0, NULL, NULL);
	CString	utf8;
	WideCharToMultiByte(CP_UTF8, 0, utf16.GetBuffer(0), utf16.GetLength(), utf8.GetBuffer(mbLen + 1), mbLen, NULL, NULL);
	utf8.ReleaseBufferSetLength(mbLen);

	return utf8;
}

/*!
	ファイルへ出力
*/
void CWorkspaceXMLWriter::SaveToFile(CWorkspaceNode *root, CString path, CString workspaceClassType)
{
	CString utf8 = ToString(root, workspaceClassType);

	//	開く
	FILE	*out;
	if(_tfopen_s(&out, path, _T("wb")) != 0)
		throw CWorkspaceXMLWriterException(_T("ファイルのオープンに失敗しました"));

	fwrite((LPCSTR)utf8, utf8.GetLength(), 1, out);
	fclose(out);
}


/////////////////////////////////////////////////////////////////////////////
//	出力関数
/////////////////////////////////////////////////////////////////////////////
/*!
	ヘッダーを出力
*/
void CWorkspaceXMLWriter::WriteHeader()
{
	m_xml.AppendLPCSTR("<?xml version=\"1.0\"?>\r\n<!--Soft3304 CWorkspace class.-->\r\n<CWorkspaceClass type=\"");
	m_xml.AppendString(m_workspaceClassType);
	m_xml.AppendLPCSTR("\">\r\n");
}

/*!
	フッター出力
*/
void CWorkspaceXMLWriter::WriteFooter()
{
	m_xml.AppendLPCSTR("</CWorkspaceClass>\r\n");
}


/*!
	１ノード出力
*/
void CWorkspaceXMLWriter::WriteSubNode(CWorkspaceNode *node, CTextEscape &escape, CString tab)
{
	//	自分を出力
	m_xml.AppendString(tab);
	m_xml.AppendLPCSTR("<Subnode name=\"");
	m_xml.AppendLPCSTR(node->GetNodeName());
	m_xml.AppendLPCSTR("\">\r\n");

	//	キー出力
	for(int i=0;;i++)
	{
		CWorkspaceKeyPair *key = node->GetKeyByIndex(i);
		if(key == NULL)
			break;

		//	変換
		CString data = escape.Escape(key->GetData());

		//	出力
		m_xml.AppendString(tab);
		m_xml.AppendLPCSTR("\t<Key name=\"");
		m_xml.AppendLPCSTR(key->GetKey());
		m_xml.AppendLPCSTR("\">");
		m_xml.AppendString(data);
		m_xml.AppendLPCSTR("</Key>\r\n");
	}

	//	サブノード出力
	for(int i=0;;i++)
	{
		CWorkspaceNode *subnode = node->GetSubNodeByIndex(i);
		if(subnode == NULL)
			break;

		//	出力
		WriteSubNode(subnode, escape, tab + _T("\t"));
	}

	//	自分を閉じる
	m_xml.AppendString(tab);
	m_xml.AppendLPCSTR("</Subnode>\r\n");
}
