using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Windows;

namespace OPlanner {

	public static class ExportCoursesHelper {

		public static XmlDocument GetCoursesXml(OPlannerData data, Size mapSize) {
			if (data == null) {
				return null;
			}
			string version = "2.0.3";
			XmlDocument doc = new XmlDocument();
			XmlDeclaration xmlDeclaration = doc.CreateXmlDeclaration("1.0", "utf-8", null);
			doc.AppendChild(xmlDeclaration);
			XmlElement root = doc.CreateElement("CourseData");
			XmlElement node;
			XmlElement subNode;
			doc.AppendChild(root);
			node = doc.CreateElement("IOFVersion");
			node.SetAttribute("version", version);
			root.AppendChild(node);
			node = doc.CreateElement("ModifyDate");
			subNode = doc.CreateElement("Date");
			subNode.SetAttribute("dateFormat", "YYYY-MM-DD");
			subNode.InnerText = DateTime.Now.ToString("yyyy-MM-dd");
			node.AppendChild(subNode);
			subNode = doc.CreateElement("Clock");
			subNode.SetAttribute("clockFormat", "HH:MM:SS");
			subNode.InnerText = DateTime.Now.ToString("HH:mm:ss");
			node.AppendChild(subNode);
			root.AppendChild(node);
			node = doc.CreateElement("Map");
			subNode = doc.CreateElement("Scale");
			subNode.InnerText = data.MapScale.ToString();
			node.AppendChild(subNode);
			subNode = CreateMapPosition(doc, -mapSize.Width/2, -mapSize.Height/2);
			node.AppendChild(subNode);
			root.AppendChild(node);
			for (int i = 0; i < data.OObjects.Count; i++) {
				if (data.OObjects[i] is OStart) {
					node = CreateStartPoint(doc, (OStart)data.OObjects[i]);
					root.AppendChild(node);
				}
				if (data.OObjects[i] is OFinish) {
					node = CreateFinishPoint(doc, (OFinish)data.OObjects[i]);
					root.AppendChild(node);
				}
				if (data.OObjects[i] is OControl) {
					node = CreateControl(doc, (OControl)data.OObjects[i]);
					root.AppendChild(node);
				}
			}
			for (int i = 0; i < data.Courses.Count; i++) {
				node = CreateCourse(doc, data.Courses[i], i.ToString());
				root.AppendChild(node);
			}
			return doc;
		}

		static XmlElement CreateMapPosition(XmlDocument doc, double x, double y) {
			XmlElement node = doc.CreateElement("MapPosition");
			node.SetAttribute("x", Math.Round(OPlannerHelper.PixelsToMillimetres(x),1).ToString());
			node.SetAttribute("y", Math.Round(OPlannerHelper.PixelsToMillimetres(-y), 1).ToString());
			node.SetAttribute("unit", "mm");
			return node;
		}

		static XmlElement CreateStartPoint(XmlDocument doc, OStart obj) {
			XmlElement node = doc.CreateElement("StartPoint");
			XmlElement subNode = doc.CreateElement("StartPointCode");
			subNode.InnerText = obj.ObjectCode;
			node.AppendChild(subNode);
			subNode = CreateMapPosition(doc, obj.X, obj.Y);
			node.AppendChild(subNode);
			return node;
		}

		static XmlElement CreateFinishPoint(XmlDocument doc, OFinish obj) {
			XmlElement node = doc.CreateElement("FinishPoint");
			XmlElement subNode = doc.CreateElement("FinishPointCode");
			subNode.InnerText = obj.ObjectCode;
			node.AppendChild(subNode);
			subNode = CreateMapPosition(doc, obj.X, obj.Y);
			node.AppendChild(subNode);
			return node;
		}

		static XmlElement CreateControl(XmlDocument doc, OControl obj) {
			XmlElement node = doc.CreateElement("Control");
			XmlElement subNode = doc.CreateElement("ControlCode");
			subNode.InnerText = obj.ObjectCode;
			node.AppendChild(subNode);
			subNode = CreateMapPosition(doc, obj.X, obj.Y);
			node.AppendChild(subNode);
			return node;
		}

		static XmlElement CreateCourseControl(XmlDocument doc, OCourseControl obj) {
			XmlElement node = doc.CreateElement("CourseControl");
			XmlElement subNode;
			int controlNum = obj.GetCourse().GetControlNum(obj);
			node.SetAttribute("markedRoute", "N");
			subNode = doc.CreateElement("Sequence");
			subNode.InnerText = controlNum.ToString();
			node.AppendChild(subNode);
			subNode = doc.CreateElement("ControlCode");
			subNode.InnerText = obj.TargetObject.ObjectCode;
			node.AppendChild(subNode);
			subNode = doc.CreateElement("LegLength");
			subNode.SetAttribute("unit", "m");
			subNode.InnerText = Math.Round(obj.GetCourse().GetLegLength(controlNum)).ToString();
			node.AppendChild(subNode);
			return node;
		}

		static XmlElement CreateCourse(XmlDocument doc, Course course, string id) {
			XmlElement node = doc.CreateElement("Course");
			XmlElement subNode;
			subNode = doc.CreateElement("CourseName");
			subNode.InnerText = course.Name;
			node.AppendChild(subNode);
			subNode = doc.CreateElement("CourseId");
			subNode.InnerText = id;
			node.AppendChild(subNode);
			subNode = doc.CreateElement("CourseVariation");
			node.AppendChild(subNode);
			XmlElement subSubNode;
			subSubNode = doc.CreateElement("CourseVariationId");
			subSubNode.InnerText = "0";
			subNode.AppendChild(subSubNode);
			subSubNode = doc.CreateElement("CourseLength");
			subSubNode.SetAttribute("unit", "m");
			subSubNode.InnerText = Math.Round(course.GetLength()*1000).ToString();
			subNode.AppendChild(subSubNode);
			subSubNode = doc.CreateElement("CourseClimb");
			subSubNode.SetAttribute("unit", "m");
			subSubNode.InnerText =  Math.Round(course.Climb).ToString();
			subNode.AppendChild(subSubNode);
			OStart start = course.GetStart();
			if (start != null) {
				subSubNode = doc.CreateElement("StartPointCode");
				subSubNode.InnerText = start.ObjectCode;
				subNode.AppendChild(subSubNode);
			}
			for (int i = 0; i < course.OrderedObjects.Count; i++) {
				if (course.OrderedObjects[i] is OCourseControl) {
					subSubNode = CreateCourseControl(doc, (OCourseControl)course.OrderedObjects[i]);
					subNode.AppendChild(subSubNode);
				}
			}
			OFinish finish = course.GetFinish();
			if (finish != null) {
				subSubNode = doc.CreateElement("FinishPointCode");
				subSubNode.InnerText = finish.ObjectCode;
				subNode.AppendChild(subSubNode);
			}
			subSubNode = doc.CreateElement("DistanceToFinish");
			subSubNode.SetAttribute("unit", "m");
			subSubNode.InnerText = Math.Round(course.GetDistanceToFinish()).ToString();
			subNode.AppendChild(subSubNode);
			return node;
		}

	}

}
