using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using System.ComponentModel;
using System.Xml;
using System.Xml.Schema;
using System.IO;
namespace XMLConvert
{
	/// 
	/// Root Node
	/// 
	[XmlRoot("html")]
	public class vlnhtml : VlnHtmlContainer
	{
	}
	[TypeConverter(typeof(ExpandableObjectConverter))]
	/// 
	/// Part
	/// 
	public class VlnHtmlPart
	{
			#region ID
			protected string _ID = string.Empty;
			[System.ComponentModel.DefaultValueAttribute("")]
			[XmlIgnore]
			public string ID
			{
				get { return _ID; }
				set { _ID = value; }
			}
			#endregion
			//#region Parent and Containing Svg
			//// ToDo: MyParent
			//private SvgPartGrouping _MyParent;
			//[XmlIgnore()]
			//public SvgPartGrouping MyParent
			//{
			//  get { return _MyParent; }
			//  set { _MyParent = value; }
			//}
			//// ToDo: MySvg
			//private Svg _MySvg;
			//public Svg MySvg
			//{
			//  get { return _MySvg; }
			//  set { _MySvg = value; }
			//}
			//internal void SetParent(SvgPartGrouping myParent)
			//{
			//  _MyParent = myParent;
			//  _MySvg = myParent.MySvg == null? MyParent : myParent.MySvg;
			//}
			//#endregion
		#region Dictionary of Parts
		internal virtual void AddLookup(Dictionary lookUp)
		{
			if (_ID != string.Empty && !lookUp.ContainsKey(_ID))
				lookUp.Add(_ID, this);
		}
		#endregion
	}
	[Serializable()]
	[TypeConverter(typeof(VlnHtmlPartsConverter))]
	/// 
	/// Parts
	/// 
	public class VlnHtmlParts : CollectionBase, ICustomTypeDescriptor
	{
		/// Notifies when the collection has been modified.
		public event EventHandler OnItemsChanged;
		/// Notifies that an item has been added.
		public event VlnHtmlPartHandler OnItemAdd;
		/// Notifies that items have been added.
		public event VlnHtmlPartHandler OnItemsAdd;
		/// Notifies that an item has been removed.
		public event VlnHtmlPartHandler OnItemRemove;
		/// 
		///	 
		///	   Initializes a new instance of .
		///	
		/// 
		public VlnHtmlParts()
		{
		}
		/// 
		///	 
		///	   Initializes a new instance of  based on another .
		///	
		/// 
		/// 
		///	   A  from which the contents are copied
		/// 
		public VlnHtmlParts(VlnHtmlParts value)
		{
			this.AddRange(value);
		}
		/// 
		///	 
		///	   Initializes a new instance of  containing any array of  objects.
		///	
		/// 
		/// 
		///	   A array of  objects with which to intialize the collection
		/// 
		public VlnHtmlParts(VlnHtmlPart[] value)
		{
			this.AddRange(value);
		}
		/// 
		/// Represents the entry at the specified index of the .
		/// 
		/// The zero-based index of the entry to locate in the collection.
		/// 
		///	 The entry at the specified index of the collection.
		/// 
		///  is outside the valid range of indexes for the collection.
		public VlnHtmlPart this[int index]
		{
			get { return ((VlnHtmlPart)(List[index])); }
			set { List[index] = value; }
		}
		//#region SetupInheritance
		//internal void SetupInheritance(SvgInheritedSettings myParentsSettings)
		//{
		//  foreach (vlnhtmlpart vlnhtmlpart in List)
		//    vlnhtmlpart.SetupInheritance(myParentsSettings);
		//}
		//#endregion
		#region Dictionary of Parts
		internal void AddLookup(Dictionary lookUp)
		{
			foreach (VlnHtmlPart vlnhtmlpart in List)
				vlnhtmlpart.AddLookup(lookUp);
		}
		#endregion
		internal static void ShowException(Exception ex)
		{
			StringBuilder sb = new StringBuilder();
			string sep = "";
			for (Exception ex1 = ex; ex1 != null; ex1 = ex1.InnerException)
			{
				sb.Append(sep + string.Format("ShowException {0} - {1}", ex1.GetType().Name, ex1.Message));
				sep = "\r\n";
			}
			Console.WriteLine(sb);
		}
		/// 
		///	Adds a  with the specified value to the 
		///	 .
		/// 
		/// The  to add.
		/// 
		///	The index at which the new element was inserted.
		/// 
		/// 
		public int Add(VlnHtmlPart value)
		{
			int ndx = List.Add(value);
			if (OnItemAdd != null) { OnItemAdd(this, new vlnhtmlpartArgs(value)); }
			if (OnItemsChanged != null) { OnItemsChanged(value, EventArgs.Empty); }
			return ndx;
		}
		/// 
		/// Copies the elements of an array to the end of the .
		/// 
		/// 
		///	An array of type  containing the objects to add to the collection.
		/// 
		/// 
		///   None.
		/// 
		/// 
		public void AddRange(VlnHtmlPart[] value)
		{
			for (int i = 0; i < value.Length; i++)
			{
				this.Add(value[i]);
			}
			if (OnItemsAdd != null) { OnItemsAdd(this, new vlnhtmlpartArgs(value)); }
			if (OnItemsChanged != null) { OnItemsChanged(value, EventArgs.Empty); }
		}
		/// 
		///	 
		///	   Adds the contents of another  to the end of the collection.
		///	
		/// 
		/// 
		///	A  containing the objects to add to the collection.
		/// 
		/// 
		///   None.
		/// 
		/// 
		public void AddRange(VlnHtmlParts value)
		{
			for (int i = 0; i < value.Count; i++)
			{
				this.Add(value[i]);
			}
			if (OnItemsAdd != null) { OnItemsAdd(this, new vlnhtmlpartArgs(value)); }
			if (OnItemsChanged != null) { OnItemsChanged(value, EventArgs.Empty); }
		}
		/// 
		/// Gets a value indicating whether the 
		///	 contains the specified .
		/// 
		/// The  to locate.
		/// 
		///  if the  is contained in the collection; 
		///   otherwise, .
		/// 
		/// 
		public bool Contains(VlnHtmlPart value)
		{
			return List.Contains(value);
		}
		/// 
		/// Copies the  values to a one-dimensional  instance at the 
		///	specified index.
		/// 
		/// The one-dimensional  that is the destination of the values copied from  .
		/// The index in  where copying begins.
		/// 
		///   None.
		/// 
		///  is multidimensional. -or- The number of elements in the  is greater than the available space between  and the end of .
		///  is . 
		///  is less than 's lowbound. 
		/// 
		public void CopyTo(VlnHtmlPart[] array, int index)
		{
			List.CopyTo(array, index);
		}
		/// 
		///	Returns the index of a  in 
		///	   the  .
		/// 
		/// The  to locate.
		/// 
		/// The index of the  of  in the 
		/// , if found; otherwise, -1.
		/// 
		/// 
		public int IndexOf(VlnHtmlPart value)
		{
			return List.IndexOf(value);
		}
		/// 
		/// Inserts a  into the  at the specified index.
		/// 
		/// The zero-based index where  should be inserted.
		/// The  to insert.
		/// None.
		/// 
		public void Insert(int index, VlnHtmlPart value)
		{
			List.Insert(index, value);
			if (OnItemAdd != null) { OnItemAdd(this, new vlnhtmlpartArgs(value)); }
			if (OnItemsChanged != null) { OnItemsChanged(value, EventArgs.Empty); }
		}
		/// 
		///	 Removes a specific  from the 
		///	 .
		/// 
		/// The  to remove from the  .
		/// None.
		///  is not found in the Collection. 
		public void Remove(VlnHtmlPart value)
		{
			List.Remove(value);
			if (OnItemRemove != null) { OnItemRemove(this, new vlnhtmlpartArgs(value)); }
			if (OnItemsChanged != null) { OnItemsChanged(value, EventArgs.Empty); }
		}
		#region ICustomTypeDescriptor impl
		public String GetClassName()
		{ return TypeDescriptor.GetClassName(this, true); }
		public AttributeCollection GetAttributes()
		{ return TypeDescriptor.GetAttributes(this, true); }
		public String GetComponentName()
		{ return TypeDescriptor.GetComponentName(this, true); }
		public TypeConverter GetConverter()
		{ return TypeDescriptor.GetConverter(this, true); }
		public EventDescriptor GetDefaultEvent()
		{ return TypeDescriptor.GetDefaultEvent(this, true); }
		public PropertyDescriptor GetDefaultProperty()
		{ return TypeDescriptor.GetDefaultProperty(this, true); }
		public object GetEditor(Type editorBaseType)
		{ return TypeDescriptor.GetEditor(this, editorBaseType, true); }
		public EventDescriptorCollection GetEvents(System.Attribute[] attributes)
		{ return TypeDescriptor.GetEvents(this, attributes, true); }
		public EventDescriptorCollection GetEvents()
		{ return TypeDescriptor.GetEvents(this, true); }
		public object GetPropertyOwner(PropertyDescriptor pd)
		{ return this; }
		/// 
		/// Called to get the properties of this type. Returns properties with certain
		/// attributes. this restriction is not implemented here.
		/// 
		/// 
		/// 
		public PropertyDescriptorCollection GetProperties(System.Attribute[] attributes)
		{ return GetProperties(); }
		/// 
		/// Called to get the properties of this type.
		/// 
		/// 
		public PropertyDescriptorCollection GetProperties()
		{
			// Create a collection object to hold property descriptors
			PropertyDescriptorCollection pds = new PropertyDescriptorCollection(null);
			// Iterate the list 
			for (int i = 0; i < this.Count; i++)
			{
				// Create a property descriptor for the item and add to the property descriptor collection
				vlnhtmlpartsPropertyDescriptor pd = new vlnhtmlpartsPropertyDescriptor(this, i);
				pds.Add(pd);
			}
			// return the property descriptor collection
			return pds;
		}
		#endregion
		/// Event arguments for the vlnhtmlparts collection class.
		public class vlnhtmlpartArgs : EventArgs
		{
			private VlnHtmlParts t;
			/// Default constructor.
			public vlnhtmlpartArgs()
			{
				t = new VlnHtmlParts();
			}
			/// Initializes with a vlnhtmlpart.
			/// Data object.
			public vlnhtmlpartArgs(VlnHtmlPart t)
				: this()
			{
				this.t.Add(t);
			}
			/// Initializes with a collection of vlnhtmlpart objects.
			/// Collection of data.
			public vlnhtmlpartArgs(VlnHtmlParts ts)
				: this()
			{
				this.t.AddRange(ts);
			}
			/// Initializes with an array of vlnhtmlpart objects.
			/// Array of data.
			public vlnhtmlpartArgs(VlnHtmlPart[] ts)
				: this()
			{
				this.t.AddRange(ts);
			}
			/// Gets or sets the data of this argument.
			public VlnHtmlParts vlnhtmlparts
			{
				get { return t; }
				set { t = value; }
			}
		}
		/// vlnhtmlparts event handler.
		public delegate void VlnHtmlPartHandler(object sender, vlnhtmlpartArgs e);
		#region Property Descriptor
		/// 
		/// Summary description for CollectionPropertyDescriptor.
		/// 
		public partial class vlnhtmlpartsPropertyDescriptor : vlnListPropertyDescriptor
		{
			private VlnHtmlPart Item { get { return (VlnHtmlPart)_Item; } }
			public vlnhtmlpartsPropertyDescriptor(VlnHtmlParts collection, int index) : base(collection, index) { ;}
			public override string DisplayName
			{ get { return Item.GetType().Name; } }
		}
		#endregion
		[Serializable()]
		public partial class vlnListPropertyDescriptor : PropertyDescriptor
		{
			protected object _Item = null;
			public vlnListPropertyDescriptor(System.Collections.IList collection, int index)
				: base("#" + index.ToString(), null)
			{ _Item = collection[index]; }
			public override bool CanResetValue(object component)
			{ return true; }
			public override Type ComponentType
			{ get { return _Item.GetType(); } }
			public override object GetValue(object component)
			{ return _Item; }
			public override bool IsReadOnly
			{ get { return false; } }
			public override Type PropertyType
			{ get { return _Item.GetType(); } }
			public override void ResetValue(object component)
			{ ;}
			public override bool ShouldSerializeValue(object component)
			{ return true; }
			public override void SetValue(object component, object value)
			{ /*_Item = value*/;}
			//public override AttributeCollection Attributes
			//{ get { return new AttributeCollection(null); } }
			public override string DisplayName
			{ get { return _Item.ToString(); } }
			public override string Description
			{ get { return _Item.ToString(); } }
			public override string Name
			{ get { return _Item.ToString(); } }
		} // Class
		#region Converter
		internal class VlnHtmlPartsConverter : ExpandableObjectConverter
		{
			public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destType)
			{
				if (destType == typeof(string) && value is VlnHtmlParts)
				{
					// Return department and department role separated by comma.
					return ((VlnHtmlParts)value).List.Count.ToString() + " SVG Drawing Parts";
				}
				return base.ConvertTo(context, culture, value, destType);
			}
		}
		#endregion
		/// SVGParts event handler.
		//public delegate void VlnHtmlPartHandler(object sender, VlnHtmlPartArgs e);
		//#region Property Descriptor
		///// 
		///// Summary description for CollectionPropertyDescriptor.
		///// 
		//public partial class VlnHtmlPartsPropertyDescriptor : vlnListPropertyDescriptor
		//{
		//	private VlnHtmlPart Item { get { return (VlnHtmlPart)_Item; } }
		//	public VlnHtmlPartsPropertyDescriptor(VlnHtmlParts collection, int index) : base(collection, index) { ;}
		//	public override string DisplayName
		//	{ get { return Item.GetType().Name; } }
		//}
		//#endregion
		//[Serializable()]
		//public partial class vlnListPropertyDescriptor : PropertyDescriptor
		//{
		//	protected object _Item = null;
		//	public vlnListPropertyDescriptor(System.Collections.IList collection, int index)
		//		: base("#" + index.ToString(), null)
		//	{ _Item = collection[index]; }
		//	public override bool CanResetValue(object component)
		//	{ return true; }
		//	public override Type ComponentType
		//	{ get { return _Item.GetType(); } }
		//	public override object GetValue(object component)
		//	{ return _Item; }
		//	public override bool IsReadOnly
		//	{ get { return false; } }
		//	public override Type PropertyType
		//	{ get { return _Item.GetType(); } }
		//	public override void ResetValue(object component)
		//	{ ;}
		//	public override bool ShouldSerializeValue(object component)
		//	{ return true; }
		//	public override void SetValue(object component, object value)
		//	{ /*_Item = value*/;}
		//	//public override AttributeCollection Attributes
		//	//{ get { return new AttributeCollection(null); } }
		//	public override string DisplayName
		//	{ get { return _Item.ToString(); } }
		//	public override string Description
		//	{ get { return _Item.ToString(); } }
		//	public override string Name
		//	{ get { return _Item.ToString(); } }
		//} // Class
		//#region Converter
		//internal class VlnHtmlPartsConverter : ExpandableObjectConverter
		//{
		//	public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destType)
		//	{
		//		if (destType == typeof(string) && value is VlnHtmlParts)
		//		{
		//			// Return department and department role separated by comma.
		//			return ((VlnHtmlParts)value).List.Count.ToString() + " Vln Html Parts";
		//		}
		//		return base.ConvertTo(context, culture, value, destType);
		//	}
		//}
		//	}
		//#endregion
	}
	/// 
	/// Hyperrlink
	/// 
	public class vlnhtml_a
	{
		//url
	}
	public class vlnhtmlContent : VlnHtmlPart
	{
		string _text;
		[XmlText]
		public string Text
		{
			get { return _text; }
			set { _text = value; }
		}
		string _style;// -qt-block-indent:1or2
		[XmlAttribute("style")]
		public string Style
		{
			get { return _style; }
			set { _style = value; }
		}
		string _align;// Center Right Justify
		[XmlAttribute("align")]
		public string Align
		{
			get { return _align; }
			set { _align = value; }
		}
	}
	/// 
	/// Paragraph
	/// 
	public class vlnhtml_p : vlnhtmlContent
	{
	}
	/// 
	/// Break
	/// 
	public class vlnhtml_br : VlnHtmlPart
	{
	}
	/// 
	/// Image
	/// 
	public class vlnhtml_img : VlnHtmlPart
	{
		string _src;//filename and Path
		[XmlAttribute("src")]
		public string Src
		{
			get { return _src; }
			set { _src = value; }
		}
		int _width;
		[XmlAttribute("width")]
		public int Width
		{
			get { return _width; }
			set { _width = value; }
		}
	}
	/// 
	/// Container
	/// 
	public class VlnHtmlContainer : VlnHtmlPart
	{
		VlnHtmlParts _Children = new VlnHtmlParts();
		[XmlElement("ul", typeof(vlnhtml_ul))]
		[XmlElement("ol", typeof(vlnhtml_ol))]
		[XmlElement("li", typeof(vlnhtml_li))]
		[XmlElement("p", typeof(vlnhtml_p))]
		[XmlElement("a", typeof(vlnhtml_a))]
		[XmlElement("br", typeof(vlnhtml_br))]
		[XmlElement("img", typeof(vlnhtml_img))]
		[XmlElement("table", typeof(vlnhtml_table))]
		internal VlnHtmlParts Children
		{
			get
			{
				//if (_Children == null)
				//	_Children = new VlnHtmlParts();
				return _Children;
			}
			set { _Children = value; }
		}
	}
	/// 
	/// Ordered List
	/// 
	public class vlnhtml_ol : VlnHtmlContainer
	{
		string _style;// -qt-block-indent:1or2
		[XmlAttribute("style")]
		public string Style
		{
			get { return _style; }
			set { _style = value; }
		}
	}
	/// 
	/// Unordered List
	/// 
	public class vlnhtml_ul : VlnHtmlContainer
	{
		string _style;// -qt-block-indent:1or2
		[XmlAttribute("style")]
		public string Style
		{
			get { return _style; }
			set { _style = value; }
		}
	}
	/// 
	/// List Item
	/// 
	public class vlnhtml_li : vlnhtmlContent
	{
	}
	/// 
	/// Table
	/// 
	public class vlnhtml_table : VlnHtmlContainer
	{
		string _style;// -qt-block-indent:1or2
		[XmlAttribute("style")]
		public string Style
		{
			get { return _style; }
			set { _style = value; }
		}
		int _border;//
		int _cellspacing;
		int _cellpadding;
	}
	public class vlnhtml_tr : VlnHtmlContainer
	{
	}
	public class vlnhtml_td : VlnHtmlContainer
	{
	}
	public static class HtmlSerializer where T : class
	{
		public static string StringSerialize(T t)
		{
			string strOutput = string.Empty;
			XmlSerializer xs = new XmlSerializer(typeof(T), "http://www.w3.org/2000/html");
			using (MemoryStream ms = new MemoryStream())
			{
				xs.Serialize(new NonXsiTextWriter(ms, Encoding.UTF8), t);
				//xs.Serialize(ms, t);
				ms.Position = 0;
				StreamReader sr = new StreamReader(ms);
				strOutput = sr.ReadToEnd();
				ms.Close();
			}
			return strOutput;
		}
		public static T StringDeserialize(string s)
		{
			T t;
			XmlSerializer xs = new XmlSerializer(typeof(T), "http://www.w3.org/2000/html");
			UTF8Encoding enc = new UTF8Encoding();
			Byte[] arrBytData = enc.GetBytes(s);
			using (MemoryStream ms = new MemoryStream(arrBytData))
			{
				t = (T)xs.Deserialize(ms);
			}
			return t;
		}
		public static void WriteFile(T t, string fileName)
		{
			string strOutput = string.Empty;
			XmlSerializer xs = new XmlSerializer(typeof(T), "http://www.w3.org/2000/html");
			using (FileStream fs = new FileStream(fileName, FileMode.Create))
			{
				xs.Serialize(new NonXsiTextWriter(fs, Encoding.UTF8), t);
				fs.Close();
			}
		}
		public static T ReadFile(string fileName)
		{
			T t;
			XmlSerializer xs = new XmlSerializer(typeof(T), "http://www.w3.org/2000/html");
			using (FileStream fs = new FileStream(fileName, FileMode.Open))
			{
				t = (T)xs.Deserialize(fs);
			}
			return t;
		}
	}
	public class NonXsiTextWriter : XmlTextWriter
	{
		public NonXsiTextWriter(TextWriter w) : base(w) { }
		public NonXsiTextWriter(Stream w, Encoding encoding)
			: base(w, encoding)
		{
			this.Formatting = Formatting.Indented;
		}
		public NonXsiTextWriter(string filename, Encoding encoding) : base(filename, encoding) { }
		bool _skip = false;
		public override void WriteStartAttribute(string prefix, string localName, string ns)
		{
			if ((prefix == "xmlns" && (localName == "xsd" || localName == "xsi")) || // Omits XSD and XSI declarations. 
				ns == XmlSchema.InstanceNamespace) // Omits all XSI attributes. 
			{
				_skip = true;
				return;
			}
			if (localName == "xlink_href")
				base.WriteStartAttribute(prefix, "xlink:href", ns);
			else
				base.WriteStartAttribute(prefix, localName, ns);
		}
		public override void WriteString(string text)
		{
			if (_skip) return;
			base.WriteString(text);
		}
		public override void WriteEndAttribute()
		{
			if (_skip)
			{ // Reset the flag, so we keep writing. 
				_skip = false;
				return;
			}
			base.WriteEndAttribute();
		}
	}
}