#include "StdAfx.h"
#include "WorkspaceXMLWriter.h"
#include "TextEscape.h"
#include "UTF8StringConvert.h"

#define	TAB_WRITE_COUNT	100

/////////////////////////////////////////////////////////////////////////////
//	出力関数
/////////////////////////////////////////////////////////////////////////////
/*!
	コンストラクタ
*/
CWorkspaceXMLWriter::CWorkspaceXMLWriter(void)
{
}

/*
	デストラクタ
*/
CWorkspaceXMLWriter::~CWorkspaceXMLWriter(void)
{
}


/////////////////////////////////////////////////////////////////////////////
//	出力
/////////////////////////////////////////////////////////////////////////////
/*!
	XML出力(throw CWorkspaceXMLWriterException)
*/
CUTF8String CWorkspaceXMLWriter::ToString(CWorkspaceNode *root, CUTF8String workspaceClassType)
{
	//	クラスタイプ設定
	m_workspaceClassType = workspaceClassType;

	//	バッファ準備
	m_xml.Empty();
	m_xml.SetGrowSize(65536);

	//	ヘッダ出力
	WriteHeader();

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

	//	フッタ出力
	WriteFooter();

	//	UTF8へ変換
	return m_xml;
}

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

	//	開く
	FILE	*out;
	if(fopen_s(&out, _cnvMBCS(path), "wb") != 0)
		return(-1);

	//	バイトオーダーマーク
	fputc(0xEF, out);
	fputc(0xBB, out);
	fputc(0xBF, out);

	//	本文出力
	fwrite((LPCU8STR)utf8, utf8.GetLength(), 1, out);
	fclose(out);
	return(0);
}


/////////////////////////////////////////////////////////////////////////////
//	出力関数
/////////////////////////////////////////////////////////////////////////////
/*!
	ヘッダーを出力
*/
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, int tabCount)
{
	//	自分を出力
	WriteTab(tabCount);
	m_xml.AppendLPCSTR("<Subnode name=\"");
	m_xml.AppendLPCU8STR(node->GetNodeName());
	m_xml.AppendLPCSTR("\">\r\n");

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

		//	出力
		WriteTab(tabCount);
		m_xml.AppendLPCSTR("\t<Key name=\"");
		m_xml.AppendLPCU8STR(key->GetKey());
		m_xml.AppendLPCSTR("\">");
		m_xml.AppendLPCU8STR(escape.Escape(key->GetData()));
		m_xml.AppendLPCSTR("</Key>\r\n");
	}

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

		//	出力
		WriteSubNode(subnode, escape, tabCount + 1);
	}

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


/*!
	タブ追加
*/
void CWorkspaceXMLWriter::WriteTab(int tabCount)
{
	char	tabs[TAB_WRITE_COUNT];

	//	タブ
	memset(tabs, '\t', TAB_WRITE_COUNT);
	while(tabCount > 0)
	{
		if(tabCount <= TAB_WRITE_COUNT)
		{
			m_xml.Append(tabs, tabCount);
			break;
		}
		else
		{
			m_xml.Append(tabs, TAB_WRITE_COUNT);
			tabCount -= TAB_WRITE_COUNT;
		}
	}
}

