/*******************************************************************************
 * 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
 * *******************************************************************************/
using System;
using System.Xml;
using System.Text.RegularExpressions;
using System.Drawing;
using System.Collections.Generic;
using OfficeOpenXml.Drawing.Vml;
using System.IO;
using OfficeOpenXml.Compatibility;
using OfficeOpenXml.Drawing;
using OfficeOpenXml.Utils;
namespace OfficeOpenXml
{    
    /// <summary>
    /// How a picture will be aligned in the header/footer
    /// </summary>
    public enum PictureAlignment
    {
        /// <summary>
        /// The picture will be added to the left aligned text
        /// </summary>
        Left,
        /// <summary>
        /// The picture will be added to the centered text
        /// </summary>
        Centered,
        /// <summary>
        /// The picture will be added to the right aligned text
        /// </summary>
        Right
    }
    #region class ExcelHeaderFooterText
	/// <summary>
    /// Print header and footer 
    /// </summary>
	public class ExcelHeaderFooterText
	{
        ExcelWorksheet _ws;
        string _hf;
        internal ExcelHeaderFooterText(XmlNode TextNode, ExcelWorksheet ws, string hf)
        {
            _ws = ws;
            _hf = hf;
            if (TextNode == null || string.IsNullOrEmpty(TextNode.InnerText)) return;
            string text = TextNode.InnerText;
            string code = text.Substring(0, 2);  
            int startPos=2;
            for (int pos=startPos;pos<text.Length-2;pos++)
            {
                string newCode = text.Substring(pos, 2);
                if (newCode == "&C" || newCode == "&R")
                {
                    SetText(code, text.Substring(startPos, pos-startPos));
                    startPos = pos+2;
                    pos = startPos;
                    code = newCode;
                }
            }
            SetText(code, text.Substring(startPos, text.Length - startPos));
        }
        private void SetText(string code, string text)
        {
            switch (code)
            {
                case "&L":
                    LeftAlignedText=text;
                    break;
                case "&C":
                    CenteredText=text;
                    break;
                default:
                    RightAlignedText=text;
                    break;
            }
        }
		/// <summary>
		/// Get/set the text to appear on the left hand side of the header (or footer) on the worksheet.
		/// </summary>
		public string LeftAlignedText = null;
		/// <summary>
        /// Get/set the text to appear in the center of the header (or footer) on the worksheet.
		/// </summary>
		public string CenteredText = null;
		/// <summary>
        /// Get/set the text to appear on the right hand side of the header (or footer) on the worksheet.
		/// </summary>
		public string RightAlignedText = null;
        /// <summary>
        /// Inserts a picture at the end of the text in the header or footer
        /// </summary>
        /// <param name="Picture">The image object containing the Picture</param>
        /// <param name="Alignment">Alignment. The image object will be inserted at the end of the Text.</param>
        public ExcelVmlDrawingPicture InsertPicture(Image Picture, PictureAlignment Alignment)
        {
            string id = ValidateImage(Alignment);
            
            //Add the image
#if (Core)
            var img=ImageCompat.GetImageAsByteArray(Picture);
#else
            ImageConverter ic = new ImageConverter();
            byte[] img = (byte[])ic.ConvertTo(Picture, typeof(byte[]));
#endif
            var ii = _ws.Workbook._package.AddImage(img);

            return AddImage(Picture, id, ii);
        }
        /// <summary>
        /// Inserts a picture at the end of the text in the header or footer
        /// </summary>
        /// <param name="PictureFile">The image object containing the Picture</param>
        /// <param name="Alignment">Alignment. The image object will be inserted at the end of the Text.</param>
        public ExcelVmlDrawingPicture InsertPicture(FileInfo PictureFile, PictureAlignment Alignment)
        {
            string id = ValidateImage(Alignment);

            Image Picture;
            try
            {
                if (!PictureFile.Exists)
                {
                    throw (new FileNotFoundException(string.Format("{0} is missing", PictureFile.FullName)));
                }
                Picture = Image.FromFile(PictureFile.FullName);
            }
            catch (Exception ex)
            {
                throw (new InvalidDataException("File is not a supported image-file or is corrupt", ex));
            }

            string contentType = ExcelPicture.GetContentType(PictureFile.Extension);
            var uriPic = XmlHelper.GetNewUri(_ws._package.Package, "/xl/media/"+PictureFile.Name.Substring(0, PictureFile.Name.Length-PictureFile.Extension.Length) + "{0}" + PictureFile.Extension);
#if (Core)
            var imgBytes=ImageCompat.GetImageAsByteArray(Picture);
#else
            var ic = new ImageConverter();
            byte[] imgBytes = (byte[])ic.ConvertTo(Picture, typeof(byte[]));
#endif
            var ii = _ws.Workbook._package.AddImage(imgBytes, uriPic, contentType);

            return AddImage(Picture, id, ii);
        }

        private ExcelVmlDrawingPicture AddImage(Image Picture, string id, ExcelPackage.ImageInfo ii)
        {
            double width = Picture.Width * 72 / Picture.HorizontalResolution,      //Pixel --> Points
                   height = Picture.Height * 72 / Picture.VerticalResolution;      //Pixel --> Points
            //Add VML-drawing            
            return _ws.HeaderFooter.Pictures.Add(id, ii.Uri, "", width, height);
        }
        private string ValidateImage(PictureAlignment Alignment)
        {
            string id = string.Concat(Alignment.ToString()[0], _hf);
            foreach (ExcelVmlDrawingPicture image in _ws.HeaderFooter.Pictures)
            {
                if (image.Id == id)
                {
                    throw (new InvalidOperationException("A picture already exists in this section"));
                }
            }
            //Add the image placeholder to the end of the text
            switch (Alignment)
            {
                case PictureAlignment.Left:
                    LeftAlignedText += ExcelHeaderFooter.Image;
                    break;
                case PictureAlignment.Centered:
                    CenteredText += ExcelHeaderFooter.Image;
                    break;
                default:
                    RightAlignedText += ExcelHeaderFooter.Image;
                    break;
            }
            return id;
        }
	}
	#endregion

	#region ExcelHeaderFooter
	/// <summary>
	/// Represents the Header and Footer on an Excel Worksheet
	/// </summary>
	public sealed class ExcelHeaderFooter : XmlHelper
	{
		#region Static Properties
		/// <summary>
        /// The code for "current page #"
		/// </summary>
		public const string PageNumber = @"&P";
		/// <summary>
        /// The code for "total pages"
		/// </summary>
		public const string NumberOfPages = @"&N";
        /// <summary>
        /// The code for "text font color"
        /// RGB Color is specified as RRGGBB
        /// Theme Color is specified as TTSNN where TT is the theme color Id, S is either "+" or "-" of the tint/shade value, NN is the tint/shade value.
        /// </summary>
        public const string FontColor = @"&K";
		/// <summary>
        /// The code for "sheet tab name"
		/// </summary>
		public const string SheetName = @"&A";
		/// <summary>
        /// The code for "this workbook's file path"
		/// </summary>
		public const string FilePath = @"&Z";
		/// <summary>
        /// The code for "this workbook's file name"
		/// </summary>
		public const string FileName = @"&F";
		/// <summary>
        /// The code for "date"
		/// </summary>
		public const string CurrentDate = @"&D";
		/// <summary>
        /// The code for "time"
		/// </summary>
		public const string CurrentTime = @"&T";
        /// <summary>
        /// The code for "picture as background"
        /// </summary>
        public const string Image = @"&G";
        /// <summary>
        /// The code for "outline style"
        /// </summary>
        public const string OutlineStyle = @"&O";
        /// <summary>
        /// The code for "shadow style"
        /// </summary>
        public const string ShadowStyle = @"&H";
		#endregion

		#region ExcelHeaderFooter Private Properties
		internal ExcelHeaderFooterText _oddHeader;
        internal ExcelHeaderFooterText _oddFooter;
		internal ExcelHeaderFooterText _evenHeader;
        internal ExcelHeaderFooterText _evenFooter;
        internal ExcelHeaderFooterText _firstHeader;
        internal ExcelHeaderFooterText _firstFooter;
        private ExcelWorksheet _ws;
        #endregion

		#region ExcelHeaderFooter Constructor
		/// <summary>
		/// ExcelHeaderFooter Constructor
		/// </summary>
		/// <param name="nameSpaceManager"></param>
        /// <param name="topNode"></param>
        /// <param name="ws">The worksheet</param>
		internal ExcelHeaderFooter(XmlNamespaceManager nameSpaceManager, XmlNode topNode, ExcelWorksheet ws) :
            base(nameSpaceManager, topNode)
		{
            _ws = ws;
            SchemaNodeOrder = new string[] { "headerFooter", "oddHeader", "oddFooter", "evenHeader", "evenFooter", "firstHeader", "firstFooter" };
		}
		#endregion

		#region alignWithMargins
        const string alignWithMarginsPath="@alignWithMargins";
        /// <summary>
		/// Gets/sets the alignWithMargins attribute
		/// </summary>
		public bool AlignWithMargins
		{
			get
			{
                return GetXmlNodeBool(alignWithMarginsPath);
			}
			set
			{
                SetXmlNodeString(alignWithMarginsPath, value ? "1" : "0");
			}
		}
		#endregion

        #region differentOddEven
        const string differentOddEvenPath = "@differentOddEven";
        /// <summary>
		/// Gets/sets the flag that tells Excel to display different headers and footers on odd and even pages.
		/// </summary>
		public bool differentOddEven
		{
			get
			{
                return GetXmlNodeBool(differentOddEvenPath);
			}
			set
			{
                SetXmlNodeString(differentOddEvenPath, value ? "1" : "0");
			}
		}
		#endregion

		#region differentFirst
        const string differentFirstPath = "@differentFirst";

		/// <summary>
		/// Gets/sets the flag that tells Excel to display different headers and footers on the first page of the worksheet.
		/// </summary>
		public bool differentFirst
		{
			get
			{
                return GetXmlNodeBool(differentFirstPath);
			}
			set
			{
                SetXmlNodeString(differentFirstPath, value ? "1" : "0");
			}
		}
		#endregion

		#region ExcelHeaderFooter Public Properties
		/// <summary>
		/// Provides access to the header on odd numbered pages of the document.
		/// If you want the same header on both odd and even pages, then only set values in this ExcelHeaderFooterText class.
		/// </summary>
		public ExcelHeaderFooterText OddHeader 
        { 
            get 
            {
                if (_oddHeader == null)
                {
                    _oddHeader = new ExcelHeaderFooterText(TopNode.SelectSingleNode("d:oddHeader", NameSpaceManager), _ws, "H");
                }
                return _oddHeader; } 
        }
		/// <summary>
		/// Provides access to the footer on odd numbered pages of the document.
		/// If you want the same footer on both odd and even pages, then only set values in this ExcelHeaderFooterText class.
		/// </summary>
		public ExcelHeaderFooterText OddFooter 
        { 
            get 
            {
                if (_oddFooter == null)
                {
                    _oddFooter = new ExcelHeaderFooterText(TopNode.SelectSingleNode("d:oddFooter", NameSpaceManager), _ws, "F"); ;
                }
                return _oddFooter; 
            } 
        }
		// evenHeader and evenFooter set differentOddEven = true
		/// <summary>
		/// Provides access to the header on even numbered pages of the document.
		/// </summary>
		public ExcelHeaderFooterText EvenHeader 
        { 
            get 
            {
                if (_evenHeader == null)
                {
                    _evenHeader = new ExcelHeaderFooterText(TopNode.SelectSingleNode("d:evenHeader", NameSpaceManager), _ws, "HEVEN");
                    differentOddEven = true;
                }
                return _evenHeader; 
            } 
        }
		/// <summary>
		/// Provides access to the footer on even numbered pages of the document.
		/// </summary>
		public ExcelHeaderFooterText EvenFooter
        { 
            get 
            {
                if (_evenFooter == null)
                {
                    _evenFooter = new ExcelHeaderFooterText(TopNode.SelectSingleNode("d:evenFooter", NameSpaceManager), _ws, "FEVEN");
                    differentOddEven = true;
                }
                return _evenFooter ; 
            } 
        }
		/// <summary>
		/// Provides access to the header on the first page of the document.
		/// </summary>
		public ExcelHeaderFooterText FirstHeader
        { 
            get 
            {
                if (_firstHeader == null)
                {
                    _firstHeader = new ExcelHeaderFooterText(TopNode.SelectSingleNode("d:firstHeader", NameSpaceManager), _ws, "HFIRST"); 
                     differentFirst = true;
                }
                return _firstHeader; 
            } 
        }
		/// <summary>
		/// Provides access to the footer on the first page of the document.
		/// </summary>
		public ExcelHeaderFooterText FirstFooter
        { 
            get 
            {
                if (_firstFooter == null)
                {
                    _firstFooter = new ExcelHeaderFooterText(TopNode.SelectSingleNode("d:firstFooter", NameSpaceManager), _ws, "FFIRST"); 
                    differentFirst = true;
                }
                return _firstFooter; 
            } 
        }
        private ExcelVmlDrawingPictureCollection _vmlDrawingsHF = null;
        /// <summary>
        /// Vml drawings. Underlaying object for Header footer images
        /// </summary>
        public ExcelVmlDrawingPictureCollection Pictures
        {
            get
            {
                if (_vmlDrawingsHF == null)
                {
                    var vmlNode = _ws.WorksheetXml.SelectSingleNode("d:worksheet/d:legacyDrawingHF/@r:id", NameSpaceManager);
                    if (vmlNode == null)
                    {
                        _vmlDrawingsHF = new ExcelVmlDrawingPictureCollection(_ws._package, _ws, null);
                    }
                    else
                    {
                        if (_ws.Part.RelationshipExists(vmlNode.Value))
                        {
                            var rel = _ws.Part.GetRelationship(vmlNode.Value);
                            var vmlUri = UriHelper.ResolvePartUri(rel.SourceUri, rel.TargetUri);

                            _vmlDrawingsHF = new ExcelVmlDrawingPictureCollection(_ws._package, _ws, vmlUri);
                            _vmlDrawingsHF.RelId = rel.Id;
                        }
                    }
                }
                return _vmlDrawingsHF;
            }
        }
		#endregion
		#region Save  //  ExcelHeaderFooter
		/// <summary>
		/// Saves the header and footer information to the worksheet XML
		/// </summary>
		internal void Save()
		{
			if (_oddHeader != null)
			{
                SetXmlNodeString("d:oddHeader", GetText(OddHeader));
			}
			if (_oddFooter != null)
			{
                SetXmlNodeString("d:oddFooter", GetText(OddFooter));
			}

			// only set evenHeader and evenFooter 
			if (differentOddEven)
			{
				if (_evenHeader != null)
				{
                    SetXmlNodeString("d:evenHeader", GetText(EvenHeader));
				}
				if (_evenFooter != null)
				{
                    SetXmlNodeString("d:evenFooter", GetText(EvenFooter));
				}
			}

			// only set firstHeader and firstFooter
			if (differentFirst)
			{
				if (_firstHeader != null)
				{
                    SetXmlNodeString("d:firstHeader", GetText(FirstHeader));
				}
				if (_firstFooter != null)
				{
                    SetXmlNodeString("d:firstFooter", GetText(FirstFooter));
				}
			}
		}
        internal void SaveHeaderFooterImages()
        {
            if (_vmlDrawingsHF != null)
            {
                if (_vmlDrawingsHF.Count == 0)
                {
                    if (_vmlDrawingsHF.Uri != null)
                    {
                        _ws.Part.DeleteRelationship(_vmlDrawingsHF.RelId);
                        _ws._package.Package.DeletePart(_vmlDrawingsHF.Uri);
                    }
                }
                else
                {
                    if (_vmlDrawingsHF.Uri == null)
                    {
                        _vmlDrawingsHF.Uri = XmlHelper.GetNewUri(_ws._package.Package, @"/xl/drawings/vmlDrawing{0}.vml");
                    }
                    if (_vmlDrawingsHF.Part == null)
                    {
                        _vmlDrawingsHF.Part = _ws._package.Package.CreatePart(_vmlDrawingsHF.Uri, "application/vnd.openxmlformats-officedocument.vmlDrawing", _ws._package.Compression);
                        var rel = _ws.Part.CreateRelationship(UriHelper.GetRelativeUri(_ws.WorksheetUri, _vmlDrawingsHF.Uri), Packaging.TargetMode.Internal, ExcelPackage.schemaRelationships + "/vmlDrawing");
                        _ws.SetHFLegacyDrawingRel(rel.Id);
                        _vmlDrawingsHF.RelId = rel.Id;
                        foreach (ExcelVmlDrawingPicture draw in _vmlDrawingsHF)
                        {
                            rel = _vmlDrawingsHF.Part.CreateRelationship(UriHelper.GetRelativeUri(_vmlDrawingsHF.Uri, draw.ImageUri), Packaging.TargetMode.Internal, ExcelPackage.schemaRelationships + "/image");
                            draw.RelId = rel.Id;
                        }
                    }
                    _vmlDrawingsHF.VmlDrawingXml.Save(_vmlDrawingsHF.Part.GetStream());
                }
            }
        }
		private string GetText(ExcelHeaderFooterText headerFooter)
		{
			string ret = "";
			if (headerFooter.LeftAlignedText != null)
				ret += "&L" + headerFooter.LeftAlignedText;
			if (headerFooter.CenteredText != null)
				ret += "&C" + headerFooter.CenteredText;
			if (headerFooter.RightAlignedText != null)
				ret += "&R" + headerFooter.RightAlignedText;
			return ret;
		}
		#endregion
	}
	#endregion
}
