//
// Copyright (c) 2021, MindFusion LLC - Bulgaria.
//

using System;
using System.Drawing;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using System.IO;
using System.Windows.Forms;

using MindFusion.Diagramming;

using Path = System.IO.Path;
using ShapeDesignerCtl = MindFusion.Tools.ShapeDesignerCtrl.ShapeDesigner;


namespace MindFusion.Tools.ShapeDesigner
{
	/// <summary>
	/// A class that holds persistent settings that are saved to settings.xml
	/// </summary>
	public class Settings
	{
		
		/// <summary>
		/// Constructor required by xml serialization
		/// </summary>
		public Settings(){}

		/// <summary>
		/// Constructor for the instance that propagates values to ShapeDesigner
		/// </summary>
		public Settings(ShapeDesignerCtl shapeDesigner)
		{
			this.shapeDesigner = shapeDesigner;
		}

		public void Save()
		{
			string filename = Path.Combine(
					Path.GetDirectoryName(Application.ExecutablePath),
					FILENAME);
			
			XmlSerializer ser = new XmlSerializer(typeof(Settings));
			using (Stream s = new FileStream(filename, FileMode.Create))
				ser.Serialize(s, this);
		}

		internal void LoadFromDesigner()
		{
			backgroundColor.color = shapeDesigner.BackColor;
			gridColor.color = shapeDesigner.GridColor;
			outlineColor.color = shapeDesigner.OutlineColor;
			decorationColor.color = shapeDesigner.DecorationColor;
			textAreaContourColor.color = shapeDesigner.TextAreaContourColor;
			mainContourColor.color = shapeDesigner.MainContourColor;
			selectionColor.color = shapeDesigner.SelectionColor;
			gridSpacing = shapeDesigner.GridSpacing;
			showGrid = shapeDesigner.ShowGrid;
			ShapeSize = shapeDesigner.ShapeSize;
		}
		
		public void Load()
		{
			if (!File.Exists(FILENAME))
			{
				LoadFromDesigner();
				// set default ShowGrid to false
				ShowGrid = false;
				return;
			}

			XmlSerializer ser = new XmlSerializer(typeof(Settings));
			using (Stream s = new FileStream(FILENAME, FileMode.Open))
			{
				Settings settings = (Settings)ser.Deserialize(s);
				// settings -> shapeDesigner
				shapeDesigner.BackColor = settings.BackgroundColor;
				shapeDesigner.GridColor = settings.GridColor;
				shapeDesigner.OutlineColor = settings.OutlineColor;
				shapeDesigner.DecorationColor = settings.DecorationColor;
				shapeDesigner.TextAreaContourColor = settings.TextAreaContourColor;
				shapeDesigner.MainContourColor = settings.MainContourColor;
				shapeDesigner.SelectionColor = settings.SelectionColor;
				shapeDesigner.GridSpacing = settings.GridSpacing;
				shapeDesigner.ShowGrid = settings.ShowGrid;
				shapeDesigner.ShapeSize = settings.ShapeSize;
				// shapeDesigner -> this
				LoadFromDesigner();
			}
		}

		// Color is not serialized as it does not have default constructor
		[XmlIgnore()]
		public Color BackgroundColor
		{
			get { return backgroundColor.color;}
			set { 
				backgroundColor.color = value;
				if (shapeDesigner != null)
					shapeDesigner.BackColor = value;
			}
		}

//		//[XmlElement("BackgroundColor")]
//		public string XmlBackgroundColor
//		{
//			get { return XmlConv.FromColor(backgroundColor.color);}
//			set { BackgroundColor = XmlConv.ToColor(value);}
//		}

		[XmlIgnore()]
		public Color GridColor
		{
			get { return gridColor.color;}
			set 
			{ 
				gridColor.color = value;
				if (shapeDesigner != null)
					shapeDesigner.GridColor = value;
			}
		}

		[XmlIgnore()]
		public Color OutlineColor
		{
			get { return outlineColor.color;}
			set 
			{ 
				outlineColor.color = value;
				if (shapeDesigner != null)
					shapeDesigner.OutlineColor = value;
			}
		}

		[XmlIgnore()]
		public Color DecorationColor
		{
			get { return decorationColor.color;}
			set 
			{ 
				decorationColor.color = value;
				if (shapeDesigner != null)
					shapeDesigner.DecorationColor = value;
			}
		}

		[XmlIgnore()]
		public Color TextAreaContourColor
		{
			get { return textAreaContourColor.color;}
			set 
			{ 
				textAreaContourColor.color = value;
				if (shapeDesigner != null)
					shapeDesigner.TextAreaContourColor = value;
			}
		}

		[XmlIgnore()]
		public Color MainContourColor
		{
			get { return mainContourColor.color;}
			set 
			{ 
				mainContourColor.color = value;
				if (shapeDesigner != null)
					shapeDesigner.MainContourColor = value;
			}
		}

		[XmlIgnore()]
		public Color SelectionColor
		{
			get { return selectionColor.color;}
			set 
			{ 
				selectionColor.color = value;
				if (shapeDesigner != null)
					shapeDesigner.SelectionColor = value;
			}
		}


		public int GridSpacing
		{
			get { return gridSpacing;}
			set 
			{ 
				if (value <= 0)
					throw new ArgumentOutOfRangeException("value", "GridSpacing must be greater than zero");
				gridSpacing = value;
				if (shapeDesigner != null)
					shapeDesigner.GridSpacing = value;
			}
		}

		public bool ShowGrid
		{
			get { return showGrid;}
			set 
			{ 
				showGrid = value;
				if (shapeDesigner != null)
					shapeDesigner.ShowGrid = value;
			}
		}

		public const string FILENAME = "settings.xml";
		[XmlElement("BackgroundColor")] public XmlColor backgroundColor = new XmlColor();
		[XmlElement("OutlineColor")] public XmlColor outlineColor = new XmlColor();
		[XmlElement("GridColor")] public XmlColor gridColor = new XmlColor();
		[XmlElement("DecorationColor")] public XmlColor decorationColor = new XmlColor();
		[XmlElement("TextAreaContourColor")] public XmlColor textAreaContourColor = new XmlColor();
		[XmlElement("MainContourColor")] public XmlColor mainContourColor = new XmlColor();
		[XmlElement("SelectionColor")] public XmlColor selectionColor = new XmlColor();
		private int gridSpacing;
		private bool showGrid;
		private ShapeDesignerCtl shapeDesigner;
		public int ShapeSize;
	}

	public class XmlColor: IXmlSerializable
	{
		public void WriteXml(XmlWriter w)
		{
			w.WriteString(Converter.FromColor(color));
		}

		public void ReadXml(XmlReader r)
		{
			string s = r.ReadString();
			r.ReadEndElement();
			color = Converter.ToColor(s);
		}

		public XmlSchema GetSchema()
		{
			return null;
		}
		public Color color;
	}
}
