﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Xml;
using System.Xml.Linq;

public static class SppXmlReader {
	public static SppCadRoot cadRoot = new SppCadRoot ();
	public static ArrayList cadChildren = new ArrayList ();
	public static ArrayList folders = new ArrayList ();
	public static ArrayList names = new ArrayList ();
	public static bool loadSuccess = false;

	public static void LoadFromFile(string fileName, bool isModelRoot) {
		loadSuccess = false;
		if (System.IO.File.Exists (fileName)) {
			string xml = System.IO.File.ReadAllText (fileName);
			if (isModelRoot) {
				folders = new ArrayList ();
				names = new ArrayList ();
			}
			LoadXML (xml, false, isModelRoot);

		} else {
			Debug.LogError (fileName + " not found!");
			Debug.Break ();
		}
	}
	public static void Parse(SppWebData wd, bool isModelRoot) {
		if (isModelRoot) {
			folders = new ArrayList ();
			names = new ArrayList ();
		}	
		LoadXML (wd.text, ContainsBOM(wd.bytes), isModelRoot);
	}

	private static bool ContainsBOM (TextAsset ta)
	{
		bool retVal = false;
		if (ta.bytes.Length >= 3) {
			if (ta.bytes [0] == 239 && ta.bytes [1] == 187 && ta.bytes [2] == 191) // UTF-8
				retVal = true;
		}
		return retVal;
	}

	private static bool ContainsBOM (byte[] b)
	{
		bool retVal = false;
		if (b.Length >= 3) {
			if (b [0] == 239 && b [1] == 187 && b [2] == 191) // UTF-8
				retVal = true;
		}
		return retVal;
	}


	private static void LoadXML (string txt, bool hasBOM, bool isModelRoot)
	{
		string val;  
		string key;

		cadRoot = new SppCadRoot ();
		cadChildren = new ArrayList ();

		if (txt.Length > 0) {
			string s;
			if (hasBOM)
				s = txt.Substring (1, txt.Length - 1);
			else
				s = txt;

			XDocument xDoc = XDocument.Parse (s);
			if (xDoc != null) {
				XElement root = xDoc.Root;
				if (root != null) {
					cadRoot.displayName = root.Attribute ("DisplayName").Value;
					// NEW
					cadRoot.isBuyPart = "";
					if ((string)root.Attribute ("IsBuyPart") != null) {
						cadRoot.isBuyPart = root.Attribute ("IsBuyPart").Value;
					}
					cadRoot.dataType = "";
					if ((string)root.Attribute ("DataType") != null) {
						cadRoot.dataType = root.Attribute ("DataType").Value;
					}

					XAttribute attr = null;
					foreach (XElement child in root.Elements()) {
						if (child.Name == "Property") {
							key = child.Attribute ("DisplayName").Value;
							val = child.Attribute ("Value").Value;
							attr = child.Attribute ("Units");
							txt = (attr == null) ? txt = "" : child.Attribute ("Units").Value;
							if (key != "" && val != "") {
								if (key == "Description")
									cadRoot.description = val;
								else if (key == "Order Number")
									cadRoot.orderNumber = val;
								else if (key == "Dimension") {
									cadRoot.dimension = val;
									if (txt != "")
										cadRoot.dimensionUnit = txt; 
								} else if (key == "Weight") {
									cadRoot.weight = val;
									if (txt != "")
										cadRoot.weightUnit = txt; 
								} 
							}
							cadRoot.dimensionFormated = BestDimension (cadRoot.dimension, ref cadRoot.dimensionUnit);
							cadRoot.weightFormated = BestWeight (cadRoot.weight, ref cadRoot.weightUnit); 
						}
						if (child.Name == "RotateTo") {
							// NEW
							Vector3 v = new Vector3 (0, 0, 0);
							// This woks probaly for both versions  
							v.x = -float.Parse (child.Attribute ("X").Value);
							v.y = -float.Parse (child.Attribute ("Z").Value);
							v.z = -float.Parse (child.Attribute ("Y").Value);
							SppConfig.basicRotation= Quaternion.Euler (v);
						} else if (child.Name == "Occurrence") {
							SppCadChild cadChild = new SppCadChild ();
							cadChild.displayName = child.Attribute ("DisplayName").Value;
							cadChild.dataType = child.Attribute ("DataType").Value;
							cadChild.isBuyPart = child.Attribute ("IsBuyPart").Value;
							if (cadChild.displayName.Length == 0) {
								cadChild.displayName = "#" + cadChildren.Count.ToString () + " " + cadChild.dataType;
							}

                            
							foreach (XElement subChild in child.Elements()) {
                                try
                                {
                                    
                                    key = subChild.Attribute("DisplayName").Value;
                                    val = subChild.Attribute("Value").Value;
                                    attr = subChild.Attribute("Units");
                                    txt = (attr == null) ? txt = "" : subChild.Attribute("Units").Value;
                                    if (key != "" && val != "")
                                    {
                                        if (key == "Description")
                                            cadChild.description = val;
                                        else if (key == "Order Number")
                                            cadChild.orderNumber = val;
                                        else if (key == "Dimension")
                                        {
                                            cadChild.dimension = val;
                                            if (txt != "")
                                                cadChild.dimensionUnit = txt;
                                        }
                                        else if (key == "Weight")
                                        {
                                            cadChild.weight = val;
                                            if (txt != "")
                                                cadChild.weightUnit = txt;
                                        }
                                    }
                                }
                                catch (System.Exception e)
                                {
                                    key = "";
                                    val = "";

                                }
							}
                            
							cadChild.dimensionFormated = BestDimension (cadChild.dimension, ref cadChild.dimensionUnit);
							cadChild.weightFormated = BestWeight (cadChild.weight, ref cadChild.weightUnit); 
							cadChildren.Add (cadChild);
						} else if (child.Name == "FoldersAndNames") {
							if (isModelRoot) {
								// Fehlt: ArticleNumber und isItem
								key = child.Attribute ("DisplayName").Value;
								val = child.Attribute ("Folder").Value;
								val = val.Replace ("\\", "/"); // make it unix conform
								if (key != "" && val != "") {
									names.Add(key);
									folders.Add(val);
								}
							}	
						}	
					}
				}
				loadSuccess = true;	
			}

		} else
			Debug.Log ("Missing XML file!");
	}

	private static string BestDimension (string s, ref string u)
	{
        /*
		string retVal = s;
		try {
			if (s.Length > 0) {
				string[] parts = s.Split ('x');
				if (parts.Length == 3) {
					Vector3 v = new Vector3 (float.Parse (parts [0]), float.Parse (parts [1]), float.Parse (parts [2]));
					float mi = Mathf.Min (v.x, v.y);
					mi = Mathf.Min (mi, v.z);
					if (mi >= 1000f) {
						// m
						u = "m";
						v /= 1000f;
						retVal = v.x.ToString ("f2") + "x" + v.y.ToString ("f2") + "x" + v.z.ToString ("f2");
					} else if (mi >= 10) {
						// cm
						u = "cm";
						v /= 10f;
						retVal = v.x.ToString ("f2") + "x" + v.y.ToString ("f2") + "x" + v.z.ToString ("f2");
					}
				}
			}
		} catch {
			retVal = s;
		}
		return retVal;	
        */
        return s + u;
	}

	private static string BestWeight (string s, ref string u)
	{
        /*
		string retVal = s;
		try {
			float v = float.Parse (s);
			if (v >= 1000000f) {
				// t
				u = "t";
				v /= 1000000f;
				retVal = v.ToString ("f2");
			} else if (v >= 1000f) {
				// kg
				u = "kg";
				v /= 1000f;
				retVal = v.ToString ("f2");
			}
		} catch {
			retVal = s;
		}
		return retVal;	
        */
        return s + u;
	}

}
