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

namespace ScaffoldingExample.Helpers
{
    /// <summary>
    /// Сериализация XML
    /// </summary>
    public class LightXMLSerializer
    {
        public string AttributeQuote { get; set; }
        public string IndentStr { get; set; }

        protected StringBuilder Result;

        /// <summary>
        /// Конструктор
        /// </summary>
        public LightXMLSerializer()
        {
            //Значения по умолчанию для свойств
            AttributeQuote = @"""";
            IndentStr = "  ";
            
            Result = new StringBuilder();
            Result.AppendLine("<?xml version='1.0' encoding='utf-8'?>");
        }

        /// <summary>
        /// Открытие элемента с отступом
        /// </summary>
        public void Open(string elementName, Dictionary<string, string> attrs = null, int indent = 0)
        {
            AddIndent(indent);
            Result.AppendLine("<" + elementName + SerializeAttrs(attrs) + ">");
        }

        /// <summary>
        /// Сериализация атрибутов
        /// </summary>
        public string SerializeAttrs(Dictionary<string, string> attrs)
        {
            string Result = "";

            if(attrs != null)
            {
                if(attrs.Count > 0)
                {
                    StringBuilder b = new StringBuilder();

                    foreach(var x in attrs)
                    {
                        b.Append(" ");
                        b.Append(x.Key);
                        b.Append("=");
                        b.Append(AttributeQuote);
                        b.Append(x.Value);
                        b.Append(AttributeQuote);
                    }

                    Result = b.ToString();
                }
            }

            return Result;
        }

        /// <summary>
        /// Закрытие элемента с отступом
        /// </summary>
        public void Close(string elementName, int indent = 0)
        {
            AddIndent(indent);
            Result.AppendLine("</" + elementName + ">");
        }

        /// <summary>
        /// Элемент с простым содержимым
        /// </summary>
        public void SimpleContent(string elementName, string elementValue, int indent = 0)
        {
            AddIndent(indent);
            Result.AppendLine("<" + elementName + ">" + elementValue + "</" + elementName + ">");
        }

        /// <summary>
        /// Элемент с простым содержимым и атрибутами
        /// </summary>
        public void SimpleContentWithAttributes(string elementName, string elementValue, Dictionary<string, string> attrs = null, int indent = 0)
        {
            AddIndent(indent);
            Result.AppendLine("<" + elementName + SerializeAttrs(attrs) + ">" + elementValue + "</" + elementName + ">");
        }

        /// <summary>
        /// Секция CData
        /// </summary>
        public string CData(string data)
        {
            string Result = "<![CDATA[" + data + "]]>";
            return Result;
        }

        /// <summary>
        /// Добавление отступов
        /// </summary>
        public void AddIndent(int indent)
        {
            if (indent > 0)
            {
                for (int i = 0; i < indent; i++)
                {
                    Result.Append(IndentStr);
                }
            }
        }

        /// <summary>
        /// Возврат результатата в виде строки
        /// </summary>
        public string XMLAsString
        {
            get
            {
                return Result.ToString();
            }
        }

        /// <summary>
        /// Сохранение результатов в файл
        /// </summary>
        public string WriteToFile(string path, string filename)
        {
            string sl = @"\";
            string fn = path.Trim();
            if (!fn.EndsWith(sl)) fn = fn + sl;
            fn = fn + filename + ".xml";

            //Удаление файла, если он существует
            if (File.Exists(fn))
            {
                File.Delete(fn);
            }

            //Запись данных в файл
            File.AppendAllText(fn, this.XMLAsString);
            return fn;
        }
    }
}