/*******************************************************************************
 * 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                      Total rewrite               2010-03-01
 * Jan K�llman		    License changed GPL-->LGPL  2011-12-27
 * Raziq York                       Added Created & Modified    2014-08-20
 *******************************************************************************/
using System;
using System.Xml;
using System.IO;
using System.Globalization;
using OfficeOpenXml.Utils;

namespace OfficeOpenXml
{
    /// <summary>
    /// Provides access to the properties bag of the package
    /// </summary>
    public sealed class OfficeProperties : XmlHelper
    {
        #region Private Properties
        private XmlDocument _xmlPropertiesCore;
        private XmlDocument _xmlPropertiesExtended;
        private XmlDocument _xmlPropertiesCustom;

        private Uri _uriPropertiesCore = new Uri("/docProps/core.xml", UriKind.Relative);
        private Uri _uriPropertiesExtended = new Uri("/docProps/app.xml", UriKind.Relative);
        private Uri _uriPropertiesCustom = new Uri("/docProps/custom.xml", UriKind.Relative);

        XmlHelper _coreHelper;
        XmlHelper _extendedHelper;
        XmlHelper _customHelper;
        private ExcelPackage _package;
        #endregion

        #region ExcelProperties Constructor
        /// <summary>
        /// Provides access to all the office document properties.
        /// </summary>
        /// <param name="package"></param>
        /// <param name="ns"></param>
        internal OfficeProperties(ExcelPackage package, XmlNamespaceManager ns) :
            base(ns)
        {
            _package = package;

            _coreHelper = XmlHelperFactory.Create(ns, CorePropertiesXml.SelectSingleNode("cp:coreProperties", NameSpaceManager));
            _extendedHelper = XmlHelperFactory.Create(ns, ExtendedPropertiesXml);
            _customHelper = XmlHelperFactory.Create(ns, CustomPropertiesXml);

        }
        #endregion
        #region CorePropertiesXml
        /// <summary>
        /// Provides access to the XML document that holds all the code 
        /// document properties.
        /// </summary>
        public XmlDocument CorePropertiesXml
        {
            get
            {
                if (_xmlPropertiesCore == null)
                {
                    string xml = string.Format("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><cp:coreProperties xmlns:cp=\"{0}\" xmlns:dc=\"{1}\" xmlns:dcterms=\"{2}\" xmlns:dcmitype=\"{3}\" xmlns:xsi=\"{4}\"></cp:coreProperties>",
                        ExcelPackage.schemaCore,
                        ExcelPackage.schemaDc,
                        ExcelPackage.schemaDcTerms,
                        ExcelPackage.schemaDcmiType,
                        ExcelPackage.schemaXsi);

                    _xmlPropertiesCore = GetXmlDocument(xml, _uriPropertiesCore, @"application/vnd.openxmlformats-package.core-properties+xml", @"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties");
                }
                return (_xmlPropertiesCore);
            }
        }

        private XmlDocument GetXmlDocument(string startXml, Uri uri, string contentType, string relationship)
        {
            XmlDocument xmlDoc;
            if (_package.Package.PartExists(uri))
                xmlDoc = _package.GetXmlFromUri(uri);
            else
            {
                xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(startXml);

                // Create a the part and add to the package
                Packaging.ZipPackagePart part = _package.Package.CreatePart(uri, contentType);

                // Save it to the package
                StreamWriter stream = new StreamWriter(part.GetStream(FileMode.Create, FileAccess.Write));
                xmlDoc.Save(stream);
                //stream.Close();

                // create the relationship between the workbook and the new shared strings part
                _package.Package.CreateRelationship(UriHelper.GetRelativeUri(new Uri("/xl", UriKind.Relative), uri), Packaging.TargetMode.Internal, relationship);
            }
            return xmlDoc;
        }
        #endregion
        #region Core Properties
        const string TitlePath = "dc:title";
        /// <summary>
        /// Gets/sets the title property of the document (core property)
        /// </summary>
        public string Title
        {
            get { return _coreHelper.GetXmlNodeString(TitlePath); }
            set { _coreHelper.SetXmlNodeString(TitlePath, value); }
        }

        const string SubjectPath = "dc:subject";
        /// <summary>
        /// Gets/sets the subject property of the document (core property)
        /// </summary>
        public string Subject
        {
            get { return _coreHelper.GetXmlNodeString(SubjectPath); }
            set { _coreHelper.SetXmlNodeString(SubjectPath, value); }
        }

        const string AuthorPath = "dc:creator";
        /// <summary>
        /// Gets/sets the author property of the document (core property)
        /// </summary>
        public string Author
        {
            get { return _coreHelper.GetXmlNodeString(AuthorPath); }
            set { _coreHelper.SetXmlNodeString(AuthorPath, value); }
        }

        const string CommentsPath = "dc:description";
        /// <summary>
        /// Gets/sets the comments property of the document (core property)
        /// </summary>
        public string Comments
        {
            get { return _coreHelper.GetXmlNodeString(CommentsPath); }
            set { _coreHelper.SetXmlNodeString(CommentsPath, value); }
        }

        const string KeywordsPath = "cp:keywords";
        /// <summary>
        /// Gets/sets the keywords property of the document (core property)
        /// </summary>
        public string Keywords
        {
            get { return _coreHelper.GetXmlNodeString(KeywordsPath); }
            set { _coreHelper.SetXmlNodeString(KeywordsPath, value); }
        }

        const string LastModifiedByPath = "cp:lastModifiedBy";
        /// <summary>
        /// Gets/sets the lastModifiedBy property of the document (core property)
        /// </summary>
        public string LastModifiedBy
        {
            get { return _coreHelper.GetXmlNodeString(LastModifiedByPath); }
            set
            {
                _coreHelper.SetXmlNodeString(LastModifiedByPath, value);
            }
        }

        const string LastPrintedPath = "cp:lastPrinted";
        /// <summary>
        /// Gets/sets the lastPrinted property of the document (core property)
        /// </summary>
        public string LastPrinted
        {
            get { return _coreHelper.GetXmlNodeString(LastPrintedPath); }
            set { _coreHelper.SetXmlNodeString(LastPrintedPath, value); }
        }

        const string CreatedPath = "dcterms:created";

        /// <summary>
	    /// Gets/sets the created property of the document (core property)
	    /// </summary>
	    public DateTime Created
	    {
	        get
	        {
	            DateTime date;
	            return DateTime.TryParse(_coreHelper.GetXmlNodeString(CreatedPath), out date) ? date : DateTime.MinValue;
	        }
	        set
	        {
	            var dateString = value.ToUniversalTime().ToString("s", CultureInfo.InvariantCulture) + "Z";
	            _coreHelper.SetXmlNodeString(CreatedPath, dateString);
                _coreHelper.SetXmlNodeString(CreatedPath + "/@xsi:type", "dcterms:W3CDTF");
	        }
	    }

        const string CategoryPath = "cp:category";
        /// <summary>
        /// Gets/sets the category property of the document (core property)
        /// </summary>
        public string Category
        {
            get { return _coreHelper.GetXmlNodeString(CategoryPath); }
            set { _coreHelper.SetXmlNodeString(CategoryPath, value); }
        }

        const string ContentStatusPath = "cp:contentStatus";
        /// <summary>
        /// Gets/sets the status property of the document (core property)
        /// </summary>
        public string Status
        {
            get { return _coreHelper.GetXmlNodeString(ContentStatusPath); }
            set { _coreHelper.SetXmlNodeString(ContentStatusPath, value); }
        }
        #endregion

        #region Extended Properties
        #region ExtendedPropertiesXml
        /// <summary>
        /// Provides access to the XML document that holds the extended properties of the document (app.xml)
        /// </summary>
        public XmlDocument ExtendedPropertiesXml
        {
            get
            {
                if (_xmlPropertiesExtended == null)
                {
                    _xmlPropertiesExtended = GetXmlDocument(string.Format("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><Properties xmlns:vt=\"{0}\" xmlns=\"{1}\"></Properties>",
                            ExcelPackage.schemaVt,
                            ExcelPackage.schemaExtended),
                        _uriPropertiesExtended,
                        @"application/vnd.openxmlformats-officedocument.extended-properties+xml",
                        @"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties");
                }
                return (_xmlPropertiesExtended);
            }
        }
        #endregion

        const string ApplicationPath = "xp:Properties/xp:Application";
        /// <summary>
        /// Gets/Set the Application property of the document (extended property)
        /// </summary>
        public string Application
        {
            get { return _extendedHelper.GetXmlNodeString(ApplicationPath); }
            set { _extendedHelper.SetXmlNodeString(ApplicationPath, value); }
        }

        const string HyperlinkBasePath = "xp:Properties/xp:HyperlinkBase";
        /// <summary>
        /// Gets/sets the HyperlinkBase property of the document (extended property)
        /// </summary>
        public Uri HyperlinkBase
        {
            get { return new Uri(_extendedHelper.GetXmlNodeString(HyperlinkBasePath), UriKind.Absolute); }
            set { _extendedHelper.SetXmlNodeString(HyperlinkBasePath, value.AbsoluteUri); }
        }

        const string AppVersionPath = "xp:Properties/xp:AppVersion";
        /// <summary>
        /// Gets/Set the AppVersion property of the document (extended property)
        /// </summary>
        public string AppVersion
        {
            get { return _extendedHelper.GetXmlNodeString(AppVersionPath); }
            set { _extendedHelper.SetXmlNodeString(AppVersionPath, value); }
        }
        const string CompanyPath = "xp:Properties/xp:Company";

        /// <summary>
        /// Gets/sets the Company property of the document (extended property)
        /// </summary>
        public string Company
        {
            get { return _extendedHelper.GetXmlNodeString(CompanyPath); }
            set { _extendedHelper.SetXmlNodeString(CompanyPath, value); }
        }

        const string ManagerPath = "xp:Properties/xp:Manager";
        /// <summary>
        /// Gets/sets the Manager property of the document (extended property)
        /// </summary>
        public string Manager
        {
            get { return _extendedHelper.GetXmlNodeString(ManagerPath); }
            set { _extendedHelper.SetXmlNodeString(ManagerPath, value); }
        }

        const string ModifiedPath = "dcterms:modified";
	    /// <summary>
	    /// Gets/sets the modified property of the document (core property)
	    /// </summary>
	    public DateTime Modified
	    {
	        get
	        {
	            DateTime date;
	            return DateTime.TryParse(_coreHelper.GetXmlNodeString(ModifiedPath), out date) ? date : DateTime.MinValue;
	        }
	        set
	        {
	            var dateString = value.ToUniversalTime().ToString("s", CultureInfo.InvariantCulture) + "Z";
	            _coreHelper.SetXmlNodeString(ModifiedPath, dateString);
                _coreHelper.SetXmlNodeString(ModifiedPath + "/@xsi:type", "dcterms:W3CDTF");
	        }
	    }

        #region Get and Set Extended Properties
        private string GetExtendedPropertyValue(string propertyName)
        {
            string retValue = null;
            string searchString = string.Format("xp:Properties/xp:{0}", propertyName);
            XmlNode node = ExtendedPropertiesXml.SelectSingleNode(searchString, NameSpaceManager);
            if (node != null)
            {
                retValue = node.InnerText;
            }
            return retValue;
        }
        #endregion
        #endregion

        #region Custom Properties

        #region CustomPropertiesXml
        /// <summary>
        /// Provides access to the XML document which holds the document's custom properties
        /// </summary>
        public XmlDocument CustomPropertiesXml
        {
            get
            {
                if (_xmlPropertiesCustom == null)
                {
                    _xmlPropertiesCustom = GetXmlDocument(string.Format("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\" ?><Properties xmlns:vt=\"{0}\" xmlns=\"{1}\"></Properties>",
                            ExcelPackage.schemaVt,
                            ExcelPackage.schemaCustom),
                         _uriPropertiesCustom, 
                         @"application/vnd.openxmlformats-officedocument.custom-properties+xml",
                         @"http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties");
                }
                return (_xmlPropertiesCustom);
            }
        }
        #endregion

        #region Get and Set Custom Properties
        /// <summary>
        /// Gets the value of a custom property
        /// </summary>
        /// <param name="propertyName">The name of the property</param>
        /// <returns>The current value of the property</returns>
        public object GetCustomPropertyValue(string propertyName)
        {
            string searchString = string.Format("ctp:Properties/ctp:property[@name='{0}']", propertyName);
            XmlElement node = CustomPropertiesXml.SelectSingleNode(searchString, NameSpaceManager) as XmlElement;
            if (node != null)
            {
                string value = node.LastChild.InnerText;
                switch (node.LastChild.LocalName)
                {
                    case "filetime":
                        DateTime dt;
                        if (DateTime.TryParse(value, out dt))
                        {
                            return dt;
                        }
                        else
                        {
                            return null;
                        }
                    case "i4":
                        int i;
                        if (int.TryParse(value, out i))
                        {
                            return i;
                        }
                        else
                        {
                            return null;
                        }
                    case "r8":
                        double d;
                        if (double.TryParse(value, NumberStyles.Any, CultureInfo.InvariantCulture, out d))
                        {
                            return d;
                        }
                        else
                        {
                            return null;
                        }
                    case "bool":
                        if (value == "true")
                        {
                            return true;
                        }
                        else if (value == "false")
                        {
                            return false;
                        }
                        else
                        {
                            return null;
                        }
                    default:
                        return value;
                }
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// Allows you to set the value of a current custom property or create your own custom property.  
        /// </summary>
        /// <param name="propertyName">The name of the property</param>
        /// <param name="value">The value of the property</param>
        public void SetCustomPropertyValue(string propertyName, object value)
        {
            XmlNode allProps = CustomPropertiesXml.SelectSingleNode(@"ctp:Properties", NameSpaceManager);

            var prop = string.Format("ctp:Properties/ctp:property[@name='{0}']", propertyName);
            XmlElement node = CustomPropertiesXml.SelectSingleNode(prop, NameSpaceManager) as XmlElement;
            if (node == null)
            {
                int pid;
                var MaxNode = CustomPropertiesXml.SelectSingleNode("ctp:Properties/ctp:property[not(@pid <= preceding-sibling::ctp:property/@pid) and not(@pid <= following-sibling::ctp:property/@pid)]", NameSpaceManager);
                if (MaxNode == null)
                {
                    pid = 2;
                }
                else
                {
                    if (!int.TryParse(MaxNode.Attributes["pid"].Value, out pid))
                    {
                        pid = 2;
                    }
                    pid++;
                }
                node = CustomPropertiesXml.CreateElement("property", ExcelPackage.schemaCustom);
                node.SetAttribute("fmtid", "{D5CDD505-2E9C-101B-9397-08002B2CF9AE}");
                node.SetAttribute("pid", pid.ToString());  // custom property pid
                node.SetAttribute("name", propertyName);

                allProps.AppendChild(node);
            }
            else
            {
                while (node.ChildNodes.Count > 0) node.RemoveChild(node.ChildNodes[0]);
            }
            XmlElement valueElem;
            if (value is bool)
            {
                valueElem = CustomPropertiesXml.CreateElement("vt", "bool", ExcelPackage.schemaVt);
                valueElem.InnerText = value.ToString().ToLower(CultureInfo.InvariantCulture);
            }
            else if (value is DateTime)
            {
                valueElem = CustomPropertiesXml.CreateElement("vt", "filetime", ExcelPackage.schemaVt);
                valueElem.InnerText = ((DateTime)value).AddHours(-1).ToString("yyyy-MM-ddTHH:mm:ssZ");
            }
            else if (value is short || value is int)
            {
                valueElem = CustomPropertiesXml.CreateElement("vt", "i4", ExcelPackage.schemaVt);
                valueElem.InnerText = value.ToString();
            }
            else if (value is double || value is decimal || value is float || value is long)
            {
                valueElem = CustomPropertiesXml.CreateElement("vt", "r8", ExcelPackage.schemaVt);
                if (value is double)
                {
                    valueElem.InnerText = ((double)value).ToString(CultureInfo.InvariantCulture);
                }
                else if (value is float)
                {
                    valueElem.InnerText = ((float)value).ToString(CultureInfo.InvariantCulture);
                }
                else if (value is decimal)
                {
                    valueElem.InnerText = ((decimal)value).ToString(CultureInfo.InvariantCulture);
                }
                else
                {
                    valueElem.InnerText = value.ToString();
                }
            }
            else
            {
                valueElem = CustomPropertiesXml.CreateElement("vt", "lpwstr", ExcelPackage.schemaVt);
                valueElem.InnerText = value.ToString();
            }
            node.AppendChild(valueElem);
        }
        #endregion
        #endregion

        #region Save
        /// <summary>
        /// Saves the document properties back to the package.
        /// </summary>
        internal void Save()
        {
            if (_xmlPropertiesCore != null)
            {
                _package.SavePart(_uriPropertiesCore, _xmlPropertiesCore);
            }
            if (_xmlPropertiesExtended != null)
            {
                _package.SavePart(_uriPropertiesExtended, _xmlPropertiesExtended);
            }
            if (_xmlPropertiesCustom != null)
            {
                _package.SavePart(_uriPropertiesCustom, _xmlPropertiesCustom);
            }

        }
        #endregion

    }
}
