using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;

namespace NovelInterpreter.Compiler
{
	/// <summary>
	/// 分割された構文を吉里吉里形式のXMLに変換するクラス
	/// </summary>
	public class XMLDocument
	{
		/// <summary>
		/// XMLで扱いやすい形式に変換されたリストをXMLに成形し
		/// ファイルとして書き出す
		/// </summary>
		/// <param name="list">変換済みリスト</param>
		/// <param name="path">書き出したいパス</param>
		public static void Write(List<KeyValuePair<string, string>> list, string path)
		{
			// XMLファイルの作成
			FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write);
			XmlTextWriter writer = new XmlTextWriter(fs, Encoding.UTF8);

			// XMLファイルにインデントを入れる
			writer.Formatting = Formatting.Indented;

			// ドキュメントの書き込み開始
			writer.WriteStartDocument();
			DocumentWrite(writer, list);
			writer.WriteEndDocument();

			// XMLファイルを閉じる
			writer.Close();
			fs.Close();
		}

		static void DocumentWrite(XmlTextWriter writer, List<KeyValuePair<string, string>> list)
		{
			writer.WriteStartElement(Configuration.Config.rootNodeName);

			// for文を使う理由はforeach文でcontinueしても
			// 入れ子構造になっているためうまく行かない
			for (int i = 0; i < list.Count; i++)
			{
				switch (list[i].Key)
				{
					case "Element":
						ElementWrite(writer, "Attribute", list, ref i);
						break;

					case "Label":
						// ラベルの書き込み
						// 書式は<Label Name="" Shiori="" />
						writer.WriteStartElement("Label");
						writer.WriteAttributeString("Name", list[i++].Value);
						writer.WriteAttributeString("Shiori", list[i].Value);
						writer.WriteEndElement();
						break;

					case "Word":
						// 文字の書き込み
						writer.WriteStartElement("Word");
						writer.WriteString(list[i].Value);
						writer.WriteEndElement();
						break;
				}
			}

			writer.WriteEndElement();
		}

		static void ElementWrite(XmlTextWriter writer, string checkName, List<KeyValuePair<string, string>> list, ref int i)
		{
			// 要素の書き出し
			writer.WriteStartElement(list[i].Key);
			writer.WriteAttributeString("Name", list[i].Value);

			// 属性が入る可能性は次の要素
			try
			{
				while (list[++i].Key == checkName)
				{
					writer.WriteStartElement(list[i].Key);	// Attribute要素の書き込み
					writer.WriteAttributeString("Name", list[i].Value);
					writer.WriteAttributeString("Value", list[++i].Value);
					writer.WriteEndElement();
				}
			}
			catch { }
			i--;		// for文用にValueの位置に合わせる

			writer.WriteEndElement();
		}
	}
}
