﻿/*******************************************************************************
 * You may amend and distribute as you like, but don't remove this header!
 *
 * EPPlus provides server-side generation of Excel 2007/2010 spreadsheets.
 * See http://www.codeplex.com/EPPlus for details.
 *
 * Copyright (C) 2011  Jan Källman
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.

 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
 * See the GNU Lesser General Public License for more details.
 *
 * The GNU Lesser General Public License can be viewed at http://www.opensource.org/licenses/lgpl-license.php
 * If you unfamiliar with this license or have questions about it, here is an http://www.gnu.org/licenses/gpl-faq.html
 *
 * All code and executables are provided "as is" with no warranty either express or implied. 
 * The author accepts no liability for any damage or loss of business that this product may cause.
 *
 * Code change notes:
 * 
 * Author							Change						         Date
 * ******************************************************************************
 * Jan Källman		    Initial Release		         2009-10-01
 * Jan Källman		    License changed GPL-->LGPL 2011-12-27
 * Eyal Seagull       Add "CreateComplexNode"    2012-04-03
 * Eyal Seagull       Add "DeleteTopNode"        2012-04-13
 *******************************************************************************/

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using OfficeOpenXml.Style;
using System.Globalization;
using System.IO;
namespace OfficeOpenXml
{
	/// <summary>
	/// Help class containing XML functions. 
	/// Can be Inherited 
	/// </summary>
	public abstract class XmlHelper
	{
		internal delegate int ChangedEventHandler(StyleBase sender, Style.StyleChangeEventArgs e);

		internal XmlHelper(XmlNamespaceManager nameSpaceManager)
		{
			TopNode = null;
			NameSpaceManager = nameSpaceManager;
		}

		internal XmlHelper(XmlNamespaceManager nameSpaceManager, XmlNode topNode)
		{
			TopNode = topNode;
			NameSpaceManager = nameSpaceManager;
		}
		//internal bool ChangedFlag;
		internal XmlNamespaceManager NameSpaceManager { get; set; }
		internal XmlNode TopNode { get; set; }
		string[] _schemaNodeOrder = null;
		/// <summary>
		/// Schema order list
		/// </summary>
		internal string[] SchemaNodeOrder
		{
			get
			{
				return _schemaNodeOrder;
			}
			set
			{
				_schemaNodeOrder = value;
			}
		}
		internal XmlNode CreateNode(string path)
		{
			if (path == "")
				return TopNode;
			else
				return CreateNode(path, false);
		}
		internal XmlNode CreateNode(string path, bool insertFirst)
		{
			XmlNode node = TopNode;
			XmlNode prependNode = null;
			foreach (string subPath in path.Split('/'))
			{
				XmlNode subNode = node.SelectSingleNode(subPath, NameSpaceManager);
				if (subNode == null)
				{
					string nodeName;
					string nodePrefix;

					string nameSpaceURI = "";
					string[] nameSplit = subPath.Split(':');

					if (SchemaNodeOrder != null && subPath[0] != '@')
					{
						insertFirst = false;
						prependNode = GetPrependNode(subPath, node);
					}

					if (nameSplit.Length > 1)
					{
						nodePrefix = nameSplit[0];
						if (nodePrefix[0] == '@') nodePrefix = nodePrefix.Substring(1, nodePrefix.Length - 1);
						nameSpaceURI = NameSpaceManager.LookupNamespace(nodePrefix);
						nodeName = nameSplit[1];
					}
					else
					{
						nodePrefix = "";
						nameSpaceURI = "";
						nodeName = nameSplit[0];
					}
					if (subPath.StartsWith("@"))
					{
						XmlAttribute addedAtt = node.OwnerDocument.CreateAttribute(subPath.Substring(1, subPath.Length - 1), nameSpaceURI);  //nameSpaceURI
						node.Attributes.Append(addedAtt);
					}
					else
					{
						if (nodePrefix == "")
						{
							subNode = node.OwnerDocument.CreateElement(nodeName, nameSpaceURI);
						}
						else
						{
							if (nodePrefix == "" || (node.OwnerDocument != null && node.OwnerDocument.DocumentElement != null && node.OwnerDocument.DocumentElement.NamespaceURI == nameSpaceURI &&
									node.OwnerDocument.DocumentElement.Prefix == ""))
							{
								subNode = node.OwnerDocument.CreateElement(nodeName, nameSpaceURI);
							}
							else
							{
								subNode = node.OwnerDocument.CreateElement(nodePrefix, nodeName, nameSpaceURI);
							}
						}
						if (prependNode != null)
						{
							node.InsertBefore(subNode, prependNode);
							prependNode = null;
						}
						else if (insertFirst)
						{
							node.PrependChild(subNode);
						}
						else
						{
							node.AppendChild(subNode);
						}
					}
				}
				node = subNode;
			}
			return node;
		}

		/// <summary>
		/// Options to insert a node in the XmlDocument
		/// </summary>
		internal enum eNodeInsertOrder
		{
			/// <summary>
			/// Insert as first node of "topNode"
			/// </summary>
			First,

			/// <summary>
			/// Insert as the last child of "topNode"
			/// </summary>
			Last,

			/// <summary>
			/// Insert after the "referenceNode"
			/// </summary>
			After,

			/// <summary>
			/// Insert before the "referenceNode"
			/// </summary>
			Before,

			/// <summary>
			/// Use the Schema List to insert in the right order. If the Schema list
			/// is null or empty, consider "Last" as the selected option
			/// </summary>
			SchemaOrder
		}

		/// <summary>
		/// Create a complex node. Insert the node according to SchemaOrder
		/// using the TopNode as the parent
		/// </summary>
		/// <param name="path"></param>
		/// <returns></returns>
		internal XmlNode CreateComplexNode(
			string path)
		{
			return CreateComplexNode(
				TopNode,
				path,
				eNodeInsertOrder.SchemaOrder,
				null);
		}

		/// <summary>
		/// Create a complex node. Insert the node according to the <paramref name="path"/>
		/// using the <paramref name="topNode"/> as the parent
		/// </summary>
		/// <param name="topNode"></param>
		/// <param name="path"></param>
		/// <returns></returns>
		internal XmlNode CreateComplexNode(
			XmlNode topNode,
			string path)
		{
			return CreateComplexNode(
				topNode,
				path,
				eNodeInsertOrder.SchemaOrder,
				null);
		}

		/// <summary>
		/// Creates complex XML nodes
    /// </summary>
    /// <remarks>
		/// 1. "d:conditionalFormatting"
		///		1.1. Creates/find the first "conditionalFormatting" node
		/// 
		/// 2. "d:conditionalFormatting/@sqref"
		///		2.1. Creates/find the first "conditionalFormatting" node
		///		2.2. Creates (if not exists) the @sqref attribute
		///
		/// 3. "d:conditionalFormatting/@id='7'/@sqref='A9:B99'"
		///		3.1. Creates/find the first "conditionalFormatting" node
		///		3.2. Creates/update its @id attribute to "7"
		///		3.3. Creates/update its @sqref attribute to "A9:B99"
		///
		/// 4. "d:conditionalFormatting[@id='7']/@sqref='X1:X5'"
		///		4.1. Creates/find the first "conditionalFormatting" node with @id=7
		///		4.2. Creates/update its @sqref attribute to "X1:X5"
		///	
		/// 5. "d:conditionalFormatting[@id='7']/@id='8'/@sqref='X1:X5'/d:cfRule/@id='AB'"
		///		5.1. Creates/find the first "conditionalFormatting" node with @id=7
		///		5.2. Set its @id attribute to "8"
		///		5.2. Creates/update its @sqref attribute and set it to "X1:X5"
		///		5.3. Creates/find the first "cfRule" node (inside the node)
		///		5.4. Creates/update its @id attribute to "AB"
		///	
		/// 6. "d:cfRule/@id=''"
		///		6.1. Creates/find the first "cfRule" node
		///		6.1. Remove the @id attribute
    ///	</remarks>
		/// <param name="topNode"></param>
		/// <param name="path"></param>
		/// <param name="nodeInsertOrder"></param>
		/// <param name="referenceNode"></param>
		/// <returns>The last node creates/found</returns>
		internal XmlNode CreateComplexNode(
			XmlNode topNode,
			string path,
			eNodeInsertOrder nodeInsertOrder,
			XmlNode referenceNode)
		{
			// Path is obrigatory
			if ((path == null) || (path == string.Empty))
			{
				return topNode;
			}

			XmlNode node = topNode;
			string nameSpaceURI = string.Empty;

      //TODO: BUG: when the "path" contains "/" in an attrribue value, it gives an error.

			// Separate the XPath to Nodes and Attributes
			foreach (string subPath in path.Split('/'))
			{
				// The subPath can be any one of those:
				// nodeName
				// x:nodeName
				// nodeName[find criteria]
				// x:nodeName[find criteria]
				// @attribute
				// @attribute='attribute value'

				// Check if the subPath has at least one character
				if (subPath.Length > 0)
				{
					// Check if the subPath is an attribute (with or without value)
					if (subPath.StartsWith("@"))
					{
						// @attribute										--> Create attribute
						// @attribute=''								--> Remove attribute
						// @attribute='attribute value' --> Create attribute + update value
						string[] attributeSplit = subPath.Split('=');
						string attributeName = attributeSplit[0].Substring(1, attributeSplit[0].Length - 1);
						string attributeValue = null;	// Null means no attribute value

						// Check if we have an attribute value to set
						if (attributeSplit.Length > 1)
						{
							// Remove the ' or " from the attribute value
							attributeValue = attributeSplit[1].Replace("'", "").Replace("\"", "");
						}

						// Get the attribute (if exists)
						XmlAttribute attribute = (XmlAttribute)(node.Attributes.GetNamedItem(attributeName));

						// Remove the attribute if value is empty (not null)
						if (attributeValue == string.Empty)
						{
							// Only if the attribute exists
							if (attribute != null)
							{
								node.Attributes.Remove(attribute);
							}
						}
						else
						{
							// Create the attribue if does not exists
							if (attribute == null)
							{
								// Create the attribute
								attribute = node.OwnerDocument.CreateAttribute(
									attributeName);

								// Add it to the current node
								node.Attributes.Append(attribute);
							}

							// Update the attribute value
							if (attributeValue != null)
							{
								node.Attributes[attributeName].Value = attributeValue;
							}
						}
					}
					else
					{
						// nodeName
						// x:nodeName
						// nodeName[find criteria]
						// x:nodeName[find criteria]

						// Look for the node (with or without filter criteria)
						XmlNode subNode = node.SelectSingleNode(subPath, NameSpaceManager);

						// Check if the node does not exists
						if (subNode == null)
						{
							string nodeName;
							string nodePrefix;
							string[] nameSplit = subPath.Split(':');
							nameSpaceURI = string.Empty;

							// Check if the name has a prefix like "d:nodeName"
							if (nameSplit.Length > 1)
							{
								nodePrefix = nameSplit[0];
								nameSpaceURI = NameSpaceManager.LookupNamespace(nodePrefix);
								nodeName = nameSplit[1];
							}
							else
							{
								nodePrefix = string.Empty;
								nameSpaceURI = string.Empty;
								nodeName = nameSplit[0];
							}

							// Check if we have a criteria part in the node name
							if (nodeName.IndexOf("[") > 0)
							{
								// remove the criteria from the node name
								nodeName = nodeName.Substring(0, nodeName.IndexOf("["));
							}

							if (nodePrefix == string.Empty)
							{
								subNode = node.OwnerDocument.CreateElement(nodeName, nameSpaceURI);
							}
							else
							{
								if (node.OwnerDocument != null
									&& node.OwnerDocument.DocumentElement != null
									&& node.OwnerDocument.DocumentElement.NamespaceURI == nameSpaceURI
									&& node.OwnerDocument.DocumentElement.Prefix == string.Empty)
								{
									subNode = node.OwnerDocument.CreateElement(
										nodeName,
										nameSpaceURI);
								}
								else
								{
									subNode = node.OwnerDocument.CreateElement(
										nodePrefix,
										nodeName,
										nameSpaceURI);
								}
							}

							// Check if we need to use the "SchemaOrder"
							if (nodeInsertOrder == eNodeInsertOrder.SchemaOrder)
							{
								// Check if the Schema Order List is empty
								if ((SchemaNodeOrder == null) || (SchemaNodeOrder.Length == 0))
								{
									// Use the "Insert Last" option when Schema Order List is empty
									nodeInsertOrder = eNodeInsertOrder.Last;
								}
								else
								{
									// Find the prepend node in order to insert
									referenceNode = GetPrependNode(nodeName, node);

									if (referenceNode != null)
									{
										nodeInsertOrder = eNodeInsertOrder.Before;
									}
									else
									{
										nodeInsertOrder = eNodeInsertOrder.Last;
									}
								}
							}

							switch (nodeInsertOrder)
							{
								case eNodeInsertOrder.After:
									node.InsertAfter(subNode, referenceNode);
                                    referenceNode = null;
                                    break;

								case eNodeInsertOrder.Before:
									node.InsertBefore(subNode, referenceNode);
                                    referenceNode = null;
									break;

								case eNodeInsertOrder.First:
									node.PrependChild(subNode);
									break;

								case eNodeInsertOrder.Last:
									node.AppendChild(subNode);
									break;
							}
						}

						// Make the newly created node the top node when the rest of the path
						// is being evaluated. So newly created nodes will be the children of the
						// one we just created.
						node = subNode;
					}
				}
			}

			// Return the last created/found node
			return node;
		}

		/// <summary>
		/// return Prepend node
		/// </summary>
		/// <param name="nodeName">name of the node to check</param>
		/// <param name="node">Topnode to check children</param>
		/// <returns></returns>
		private XmlNode GetPrependNode(string nodeName, XmlNode node)
		{
			int pos = GetNodePos(nodeName);
			if (pos < 0)
			{
				return null;
			}
			XmlNode prependNode = null;
			foreach (XmlNode childNode in node.ChildNodes)
			{
				int childPos = GetNodePos(childNode.Name);
				if (childPos > -1)  //Found?
				{
					if (childPos > pos) //Position is before
					{
						prependNode = childNode;
						break;
					}
				}
			}
			return prependNode;
		}
		private int GetNodePos(string nodeName)
		{
			int ix = nodeName.IndexOf(":");
			if (ix > 0)
			{
				nodeName = nodeName.Substring(ix + 1, nodeName.Length - (ix + 1));
			}
			for (int i = 0; i < _schemaNodeOrder.Length; i++)
			{
				if (nodeName == _schemaNodeOrder[i])
				{
					return i;
				}
			}
			return -1;
		}
		internal void DeleteAllNode(string path)
		{
			string[] split = path.Split('/');
			XmlNode node = TopNode;
			foreach (string s in split)
			{
				node = node.SelectSingleNode(s, NameSpaceManager);
				if (node != null)
				{
					if (node is XmlAttribute)
					{
						(node as XmlAttribute).OwnerElement.Attributes.Remove(node as XmlAttribute);
					}
					else
					{
						node.ParentNode.RemoveChild(node);
					}
				}
				else
				{
					break;
				}
			}
		}
		internal void DeleteNode(string path)
		{
			var node = TopNode.SelectSingleNode(path, NameSpaceManager);
			if (node != null)
			{
				if (node is XmlAttribute)
				{
					var att = (XmlAttribute)node;
					att.OwnerElement.Attributes.Remove(att);
				}
				else
				{
					node.ParentNode.RemoveChild(node);
				}
			}
		}
    internal void DeleteTopNode()
    {
      TopNode.ParentNode.RemoveChild(TopNode);
    }
		internal void SetXmlNodeString(string path, string value)
		{
			SetXmlNodeString(TopNode, path, value, false, false);
		}
		internal void SetXmlNodeString(string path, string value, bool removeIfBlank)
		{
			SetXmlNodeString(TopNode, path, value, removeIfBlank, false);
		}
		internal void SetXmlNodeString(XmlNode node, string path, string value)
		{
			SetXmlNodeString(node, path, value, false, false);
		}
		internal void SetXmlNodeString(XmlNode node, string path, string value, bool removeIfBlank)
		{
			SetXmlNodeString(node, path, value, removeIfBlank, false);
		}
		internal void SetXmlNodeString(XmlNode node, string path, string value, bool removeIfBlank, bool insertFirst)
		{
			if (node == null)
			{
				return;
			}
			if (value == "" && removeIfBlank)
			{
				DeleteAllNode(path);
			}
			else
			{
				XmlNode nameNode = node.SelectSingleNode(path, NameSpaceManager);
				if (nameNode == null)
				{
					CreateNode(path, insertFirst);
					nameNode = node.SelectSingleNode(path, NameSpaceManager);
				}
				//if (nameNode.InnerText != value) HasChanged();
				nameNode.InnerText = value;
			}
		}
		internal void SetXmlNodeBool(string path, bool value)
		{
			SetXmlNodeString(TopNode, path, value ? "1" : "0", false, false);
		}
		internal void SetXmlNodeBool(string path, bool value, bool removeIf)
		{
			if (value == removeIf)
			{
				var node = TopNode.SelectSingleNode(path, NameSpaceManager);
				if (node != null)
				{
					if (node is XmlAttribute)
					{
						var elem = (node as XmlAttribute).OwnerElement;
						elem.ParentNode.RemoveChild(elem);
					}
					else
					{
						TopNode.RemoveChild(node);
					}
				}
			}
			else
			{
				SetXmlNodeString(TopNode, path, value ? "1" : "0", false, false);
			}
		}
		internal bool ExistNode(string path)
		{
			if (TopNode == null || TopNode.SelectSingleNode(path, NameSpaceManager) == null)
			{
				return false;
			}
			else
			{
				return true;
			}
		}
		internal bool? GetXmlNodeBoolNullable(string path)
		{
			var value = GetXmlNodeString(path);
			if (string.IsNullOrEmpty(value))
			{
				return null;
			}
			return GetXmlNodeBool(path);
		}
		internal bool GetXmlNodeBool(string path)
		{
			return GetXmlNodeBool(path, false);
		}
		internal bool GetXmlNodeBool(string path, bool blankValue)
		{
			string value = GetXmlNodeString(path);
			if (value == "1" || value == "-1" || value.Equals("true",StringComparison.InvariantCultureIgnoreCase))
			{
				return true;
			}
			else if (value == "")
			{
				return blankValue;
			}
			else
			{
				return false;
			}
		}
		internal int GetXmlNodeInt(string path)
		{
			int i;
			if (int.TryParse(GetXmlNodeString(path), out i))
			{
				return i;
			}
			else
			{
				return int.MinValue;
			}
		}
        internal int? GetXmlNodeIntNull(string path)
        {
            int i;
            string s = GetXmlNodeString(path);
            if (s!="" && int.TryParse(s, out i))
            {
                return i;
            }
            else
            {
                return null;
            }
        }

		internal decimal GetXmlNodeDecimal(string path)
		{
			decimal d;
			if (decimal.TryParse(GetXmlNodeString(path), NumberStyles.Any, CultureInfo.InvariantCulture, out d))
			{
				return d;
			}
			else
			{
				return 0;
			}
		}
        internal decimal? GetXmlNodeDecimalNull(string path)
        {
            decimal d;
            if (decimal.TryParse(GetXmlNodeString(path), NumberStyles.Any, CultureInfo.InvariantCulture, out d))
            {
                return d;
            }
            else
            {
                return null;
            }
        }
        internal double? GetXmlNodeDoubleNull(string path)
		{
			string s = GetXmlNodeString(path);
			if (s == "")
			{
				return null;
			}
			else
			{
				double v;
				if (double.TryParse(s, NumberStyles.Number, CultureInfo.InvariantCulture, out v))
				{
					return v;
				}
				else
				{
					return null;
				}
			}
		}
		internal double GetXmlNodeDouble(string path)
		{
			string s = GetXmlNodeString(path);
			if (s == "")
			{
				return double.NaN;
			}
			else
			{
				double v;
				if (double.TryParse(s, NumberStyles.Number, CultureInfo.InvariantCulture, out v))
				{
					return v;
				}
				else
				{
					return double.NaN;
				}
			}
		}
    internal string GetXmlNodeString(XmlNode node, string path)
    {
      if (node == null)
      {
        return "";
      }

      XmlNode nameNode = node.SelectSingleNode(path, NameSpaceManager);

      if (nameNode != null)
      {
        if (nameNode.NodeType == XmlNodeType.Attribute)
        {
          return nameNode.Value != null ? nameNode.Value : "";
        }
        else
        {
          return nameNode.InnerText;
        }
      }
      else
      {
        return "";
      }
    }
		internal string GetXmlNodeString(string path)
		{
            return GetXmlNodeString(TopNode, path);
		}
		internal static Uri GetNewUri(Packaging.ZipPackage package, string sUri)
		{
			return GetNewUri(package, sUri, 1);
		}
        internal static Uri GetNewUri(Packaging.ZipPackage package, string sUri, int id)
		{
			Uri uri;
			do
			{
				uri = new Uri(string.Format(sUri, id++), UriKind.Relative);
			}
			while (package.PartExists(uri));
			return uri;
		}
		/// <summary>
		/// Insert the new node before any of the nodes in the comma separeted list
		/// </summary>
		/// <param name="parentNode">Parent node</param>
		/// <param name="beforeNodes">comma separated list containing nodes to insert after. Left to right order</param>
		/// <param name="newNode">The new node to be inserterd</param>
		internal void InserAfter(XmlNode parentNode, string beforeNodes, XmlNode newNode)
		{
			string[] nodePaths = beforeNodes.Split(',');

			foreach (string nodePath in nodePaths)
			{
				XmlNode node = parentNode.SelectSingleNode(nodePath, NameSpaceManager);
				if (node != null)
				{
					parentNode.InsertAfter(newNode, node);
					return;
				}
			}
			parentNode.InsertAfter(newNode, null);
		}
        internal static void LoadXmlSafe(XmlDocument xmlDoc, Stream stream)
        {
            XmlReaderSettings settings = new XmlReaderSettings();
            //Disable entity parsing (to aviod xmlbombs, External Entity Attacks etc).
            settings.ProhibitDtd = true;
            XmlReader reader = XmlReader.Create(stream, settings);
            xmlDoc.Load(reader);
        }
        internal static void LoadXmlSafe(XmlDocument xmlDoc, string xml, Encoding encoding)
        {
            var stream = new MemoryStream(encoding.GetBytes(xml));
            LoadXmlSafe(xmlDoc, stream);
        }
	}
}
