﻿/*******************************************************************************
 * 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-12-22
 * Jan Källman		License changed GPL-->LGPL 2011-12-16
 *******************************************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Collections;
using System.IO;
using System.Drawing;
using System.Linq;
using OfficeOpenXml.Drawing.Chart;
using OfficeOpenXml.Table.PivotTable;
using OfficeOpenXml.Utils;
namespace OfficeOpenXml.Drawing
{
    /// <summary>
    /// Collection for Drawing objects.
    /// </summary>
    public class ExcelDrawings : IEnumerable<ExcelDrawing>, IDisposable
    {
        private XmlDocument _drawingsXml=new XmlDocument();
        private Dictionary<string, int> _drawingNames;
        private List<ExcelDrawing> _drawings;
        internal class ImageCompare
        {
            internal byte[] image { get; set; }
            internal string relID { get; set; }

            internal bool Comparer(byte[] compareImg)
            {
                if (compareImg.Length != image.Length)
                {
                    return false;
                }

                for (int i = 0; i < image.Length; i++)
                {
                    if (image[i] != compareImg[i])
                    {
                        return false;
                    }
                }
                return true; //Equal
            }
        }
        //internal List<ImageCompare> _pics = new List<ImageCompare>();
        internal Dictionary<string, string> _hashes = new Dictionary<string, string>();
        internal ExcelPackage _package;
        internal Packaging.ZipPackageRelationship _drawingRelation = null;
        internal ExcelDrawings(ExcelPackage xlPackage, ExcelWorksheet sheet)
        {
                _drawingsXml = new XmlDocument();                
                _drawingsXml.PreserveWhitespace = false;
                _drawings = new List<ExcelDrawing>();
                _drawingNames = new Dictionary<string,int>(StringComparer.InvariantCultureIgnoreCase);
                _package = xlPackage;
                Worksheet = sheet;
                XmlNode node = sheet.WorksheetXml.SelectSingleNode("//d:drawing", sheet.NameSpaceManager);
                CreateNSM();
                if (node != null)
                {
                    _drawingRelation = sheet.Part.GetRelationship(node.Attributes["r:id"].Value);
                    _uriDrawing = UriHelper.ResolvePartUri(sheet.WorksheetUri, _drawingRelation.TargetUri);

                    _part = xlPackage.Package.GetPart(_uriDrawing);
                    XmlHelper.LoadXmlSafe(_drawingsXml, _part.GetStream()); 

                    AddDrawings();
                }
         }
        internal ExcelWorksheet Worksheet { get; set; }
        /// <summary>
        /// A reference to the drawing xml document
        /// </summary>
        public XmlDocument DrawingXml
        {
            get
            {
                return _drawingsXml;
            }
        }
        private void AddDrawings()
        {
            // Look inside all children for the drawings because they could be inside
            // Markup Compatibility AlternativeContent/Choice or AlternativeContent/Fallback nodes.
            // The code below currently pretends that loading all Choice alternative drawings doesn't cause a problem
            // elsewhere. This seems to be ok for the time being as encountered drawing files so far only seem to have
            // one Choice node (and no Fallback) underneath the AlternativeContent node. (Excel 2013 that is.)
            // This change prevents CodePlex issue #15028 from occurring. 
            // (the drawing xml part (that ONLY contained AlternativeContent nodes) was incorrectly being garbage collected when the package was saved)
            XmlNodeList list = _drawingsXml.SelectNodes("//*[self::xdr:twoCellAnchor or self::xdr:oneCellAnchor or self::xdr:absoluteAnchor]", NameSpaceManager);

            foreach (XmlNode node in list)
            {
                
                ExcelDrawing dr;
                switch(node.LocalName)
                {
                    case "oneCellAnchor":
                        dr = new ExcelDrawing(this, node, "xdr:sp/xdr:nvSpPr/xdr:cNvPr/@name");
                        break;
                    case "twoCellAnchor":
                        dr = ExcelDrawing.GetDrawing(this, node);
                        break;
                    case "absoluteAnchor":
                        dr = ExcelDrawing.GetDrawing(this, node);
                        break;
                    default: //"absoluteCellAnchor":
                        dr = null;
                        break;
                }
                if (dr != null)
                {
                    _drawings.Add(dr);
                    if (!_drawingNames.ContainsKey(dr.Name))
                    {
                        _drawingNames.Add(dr.Name, _drawings.Count - 1);
                    }
                }
            }
        }


        #region NamespaceManager
        /// <summary>
        /// Creates the NamespaceManager. 
        /// </summary>
        private void CreateNSM()
        {
            NameTable nt = new NameTable();
            _nsManager = new XmlNamespaceManager(nt);
            _nsManager.AddNamespace("a", ExcelPackage.schemaDrawings);
            _nsManager.AddNamespace("xdr", ExcelPackage.schemaSheetDrawings);
            _nsManager.AddNamespace("c", ExcelPackage.schemaChart);
            _nsManager.AddNamespace("r", ExcelPackage.schemaRelationships);
        }
        /// <summary>
        /// Provides access to a namespace manager instance to allow XPath searching
        /// </summary>
        XmlNamespaceManager _nsManager=null;
        public XmlNamespaceManager NameSpaceManager
        {
            get
            {
                return _nsManager;
            }
        }
        #endregion
        #region IEnumerable Members

        public IEnumerator GetEnumerator()
        {
            return (_drawings.GetEnumerator());
        }
        #region IEnumerable<ExcelDrawing> Members

        IEnumerator<ExcelDrawing> IEnumerable<ExcelDrawing>.GetEnumerator()
        {
            return (_drawings.GetEnumerator());
        }

        #endregion

        /// <summary>
        /// Returns the drawing at the specified position.  
        /// </summary>
        /// <param name="PositionID">The position of the drawing. 0-base</param>
        /// <returns></returns>
        public ExcelDrawing this[int PositionID]
        {
            get
            {
                return (_drawings[PositionID]);
            }
        }

        /// <summary>
        /// Returns the drawing matching the specified name
        /// </summary>
        /// <param name="Name">The name of the worksheet</param>
        /// <returns></returns>
        public ExcelDrawing this[string Name]
        {
            get
            {
                if (_drawingNames.ContainsKey(Name))
                {
                    return _drawings[_drawingNames[Name]];
                }
                else
                {
                    return null;
                }
            }
        }
        public int Count
        {
            get
            {
                if (_drawings == null)
                {
                    return 0;
                }
                else
                {
                    return _drawings.Count;
                }
            }
        }
        Packaging.ZipPackagePart _part=null;
        internal Packaging.ZipPackagePart Part
        {
            get
            {
                return _part;
            }        
        }
        Uri _uriDrawing=null;
        public Uri UriDrawing
        {
            get
            {
                return _uriDrawing;
            }
        }
        #endregion
        #region Add functions
            /// <summary>
            /// Add a new chart to the worksheet.
            /// Do not support Bubble-, Radar-, Stock- or Surface charts. 
            /// </summary>
            /// <param name="Name"></param>
            /// <param name="ChartType">Type of chart</param>
            /// <param name="PivotTableSource">The pivottable source for a pivotchart</param>    
            /// <returns>The chart</returns>
            public ExcelChart AddChart(string Name, eChartType ChartType, ExcelPivotTable PivotTableSource)
            {
                if(_drawingNames.ContainsKey(Name))
                {
                    throw new Exception("Name already exists in the drawings collection");
                }

                if (ChartType == eChartType.StockHLC ||
                    ChartType == eChartType.StockOHLC ||
                    ChartType == eChartType.StockVOHLC)
                {
                    throw(new NotImplementedException("Chart type is not supported in the current version"));
                }
                if (Worksheet is ExcelChartsheet && _drawings.Count > 0)
                {
                    throw new InvalidOperationException("Chart Worksheets can't have more than one chart");                
                }
                XmlElement drawNode = CreateDrawingXml();

                ExcelChart chart = ExcelChart.GetNewChart(this, drawNode, ChartType, null, PivotTableSource);
                chart.Name = Name;
                _drawings.Add(chart);
                _drawingNames.Add(Name, _drawings.Count - 1);
                return chart;
            }
            /// <summary>
            /// Add a new chart to the worksheet.
            /// Do not support Bubble-, Radar-, Stock- or Surface charts. 
            /// </summary>
            /// <param name="Name"></param>
            /// <param name="ChartType">Type of chart</param>
            /// <returns>The chart</returns>
            public ExcelChart AddChart(string Name, eChartType ChartType)
            {
                return AddChart(Name, ChartType, null);
            }
            /// <summary>
            /// Add a picure to the worksheet
            /// </summary>
            /// <param name="Name"></param>
            /// <param name="image">An image. Allways saved in then JPeg format</param>
            /// <returns></returns>
            public ExcelPicture AddPicture(string Name, Image image)
            {
               return AddPicture(Name, image, null);
            }
            /// <summary>
            /// Add a picure to the worksheet
            /// </summary>
            /// <param name="Name"></param>
            /// <param name="image">An image. Allways saved in then JPeg format</param>
            /// <param name="Hyperlink">Picture Hyperlink</param>
            /// <returns></returns>
            public ExcelPicture AddPicture(string Name, Image image, Uri Hyperlink)
            {
                if (image != null)
                {
                    if (_drawingNames.ContainsKey(Name))
                    {
                        throw new Exception("Name already exists in the drawings collection");
                    }
                    XmlElement drawNode = CreateDrawingXml();
                    drawNode.SetAttribute("editAs", "oneCell");
                    ExcelPicture pic = new ExcelPicture(this, drawNode, image, Hyperlink);
                    pic.Name = Name;
                    _drawings.Add(pic);
                    _drawingNames.Add(Name, _drawings.Count - 1);
                    return pic;
                }
                throw (new Exception("AddPicture: Image can't be null"));
            }
            /// <summary>
            /// Add a picure to the worksheet
            /// </summary>
            /// <param name="Name"></param>
            /// <param name="ImageFile">The image file</param>
            /// <returns></returns>
            public ExcelPicture AddPicture(string Name, FileInfo ImageFile)
            {
               return AddPicture(Name, ImageFile, null);
            }
            /// <summary>
            /// Add a picure to the worksheet
            /// </summary>
            /// <param name="Name"></param>
            /// <param name="ImageFile">The image file</param>
            /// <param name="Hyperlink">Picture Hyperlink</param>
            /// <returns></returns>
            public ExcelPicture AddPicture(string Name, FileInfo ImageFile, Uri Hyperlink)
            {
                if (Worksheet is ExcelChartsheet && _drawings.Count > 0)
                {
                    throw new InvalidOperationException("Chart worksheets can't have more than one drawing");
                }
                if (ImageFile != null)
               {
                  if (_drawingNames.ContainsKey(Name))
                  {
                     throw new Exception("Name already exists in the drawings collection");
                  }
                  XmlElement drawNode = CreateDrawingXml();
                  drawNode.SetAttribute("editAs", "oneCell");
                  ExcelPicture pic = new ExcelPicture(this, drawNode, ImageFile, Hyperlink);
                  pic.Name = Name;
                  _drawings.Add(pic);
                  _drawingNames.Add(Name, _drawings.Count - 1);
                  return pic;
               }
               throw (new Exception("AddPicture: ImageFile can't be null"));
            }

        /// <summary>
        /// Add a new shape to the worksheet
        /// </summary>
        /// <param name="Name">Name</param>
        /// <param name="Style">Shape style</param>
        /// <returns>The shape object</returns>
    
        public ExcelShape AddShape(string Name, eShapeStyle Style)
            {
                if (Worksheet is ExcelChartsheet && _drawings.Count > 0)
                {
                    throw new InvalidOperationException("Chart worksheets can't have more than one drawing");
                }
                if (_drawingNames.ContainsKey(Name))
                {
                    throw new Exception("Name already exists in the drawings collection");
                }
                XmlElement drawNode = CreateDrawingXml();

                ExcelShape shape = new ExcelShape(this, drawNode, Style);
                shape.Name = Name;
                shape.Style = Style;
                _drawings.Add(shape);
                _drawingNames.Add(Name, _drawings.Count - 1);
                return shape;
            }
        /// <summary>
        /// Add a new shape to the worksheet
        /// </summary>
        /// <param name="Name">Name</param>
        /// <param name="Source">Source shape</param>
        /// <returns>The shape object</returns>
        public ExcelShape AddShape(string Name, ExcelShape Source)
        {
            if (Worksheet is ExcelChartsheet && _drawings.Count > 0)
            {
                throw new InvalidOperationException("Chart worksheets can't have more than one drawing");
            }
            if (_drawingNames.ContainsKey(Name))
            {
                throw new Exception("Name already exists in the drawings collection");
            }
            XmlElement drawNode = CreateDrawingXml();
            drawNode.InnerXml = Source.TopNode.InnerXml;

            ExcelShape shape = new ExcelShape(this, drawNode);
            shape.Name = Name;
            shape.Style = Source.Style;
            _drawings.Add(shape);
            _drawingNames.Add(Name, _drawings.Count - 1);
            return shape;
        }
            private XmlElement CreateDrawingXml()
            {
                if (DrawingXml.OuterXml == "")
                {
                    DrawingXml.LoadXml(string.Format("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><xdr:wsDr xmlns:xdr=\"{0}\" xmlns:a=\"{1}\" />", ExcelPackage.schemaSheetDrawings, ExcelPackage.schemaDrawings));
                    _uriDrawing = new Uri(string.Format("/xl/drawings/drawing{0}.xml", Worksheet.SheetID),UriKind.Relative);

                    Packaging.ZipPackage package = Worksheet._package.Package;
                    _part = package.CreatePart(_uriDrawing, "application/vnd.openxmlformats-officedocument.drawing+xml", _package.Compression);

                    StreamWriter streamChart = new StreamWriter(_part.GetStream(FileMode.Create, FileAccess.Write));
                    DrawingXml.Save(streamChart);
                    streamChart.Close();
                    package.Flush();

                    _drawingRelation = Worksheet.Part.CreateRelationship(UriHelper.GetRelativeUri(Worksheet.WorksheetUri, _uriDrawing), Packaging.TargetMode.Internal, ExcelPackage.schemaRelationships + "/drawing");
                    XmlElement e = Worksheet.WorksheetXml.CreateElement("drawing", ExcelPackage.schemaMain);
                    e.SetAttribute("id",ExcelPackage.schemaRelationships, _drawingRelation.Id);

                    Worksheet.WorksheetXml.DocumentElement.AppendChild(e);
                    package.Flush();                    
                }
                XmlNode colNode = _drawingsXml.SelectSingleNode("//xdr:wsDr", NameSpaceManager);
                XmlElement drawNode;
                if (this.Worksheet is ExcelChartsheet)
                {
                    drawNode = _drawingsXml.CreateElement("xdr", "absoluteAnchor", ExcelPackage.schemaSheetDrawings);
                    XmlElement posNode = _drawingsXml.CreateElement("xdr", "pos", ExcelPackage.schemaSheetDrawings);
                    posNode.SetAttribute("y", "0");
                    posNode.SetAttribute("x", "0");
                    drawNode.AppendChild(posNode);
                    XmlElement extNode = _drawingsXml.CreateElement("xdr", "ext", ExcelPackage.schemaSheetDrawings);
                    extNode.SetAttribute("cy", "6072876");
                    extNode.SetAttribute("cx", "9299263");
                    drawNode.AppendChild(extNode);
                    colNode.AppendChild(drawNode);
                }
                else
                {
                    drawNode = _drawingsXml.CreateElement("xdr", "twoCellAnchor", ExcelPackage.schemaSheetDrawings);
                    colNode.AppendChild(drawNode);
                    //Add from position Element;
                    XmlElement fromNode = _drawingsXml.CreateElement("xdr", "from", ExcelPackage.schemaSheetDrawings);
                    drawNode.AppendChild(fromNode);
                    fromNode.InnerXml = "<xdr:col>0</xdr:col><xdr:colOff>0</xdr:colOff><xdr:row>0</xdr:row><xdr:rowOff>0</xdr:rowOff>";

                    //Add to position Element;
                    XmlElement toNode = _drawingsXml.CreateElement("xdr", "to", ExcelPackage.schemaSheetDrawings);
                    drawNode.AppendChild(toNode);
                    toNode.InnerXml = "<xdr:col>10</xdr:col><xdr:colOff>0</xdr:colOff><xdr:row>10</xdr:row><xdr:rowOff>0</xdr:rowOff>";
                }

                return drawNode;
            }
        #endregion
        #region Remove methods
            /// <summary>
            /// Removes a drawing.
            /// </summary>
            /// <param name="Index">The index of the drawing</param>
        public void Remove(int Index)
        {
            if (Worksheet is ExcelChartsheet && _drawings.Count > 0)
            {
                throw new InvalidOperationException("Can' remove charts from chart worksheets");
            }
            RemoveDrawing(Index);
        }

        internal void RemoveDrawing(int Index)
        {
            var draw = _drawings[Index];
            draw.DeleteMe();
            for (int i = Index + 1; i < _drawings.Count; i++)
            {
                _drawingNames[_drawings[i].Name]--;
            }
            _drawingNames.Remove(draw.Name);
            _drawings.Remove(draw);
        }
        /// <summary>
        /// Removes a drawing.
        /// </summary>
        /// <param name="Drawing">The drawing</param>
        public void Remove(ExcelDrawing Drawing)
        {
            Remove(_drawingNames[Drawing.Name]);
        }
        /// <summary>
        /// Removes a drawing.
        /// </summary>
        /// <param name="Name">The name of the drawing</param>
        public void Remove(string Name)
        {
            Remove(_drawingNames[Name]);
        }
        /// <summary>
        /// Removes all drawings from the collection
        /// </summary>
        public void Clear()
        {
            if (Worksheet is ExcelChartsheet && _drawings.Count > 0)
            {
                throw new InvalidOperationException("Can' remove charts from chart worksheets");
            }
            ClearDrawings();
        }

        internal void ClearDrawings()
        {
            while (Count > 0)
            {
                RemoveDrawing(0);
            }
        }
        #endregion
            internal void AdjustWidth(int[,] pos)
            {
                var ix = 0;
                //Now set the size for all drawings depending on the editAs property.
                foreach (OfficeOpenXml.Drawing.ExcelDrawing d in this)
                {
                    if (d.EditAs != Drawing.eEditAs.TwoCell)
                    {
                        if (d.EditAs == Drawing.eEditAs.Absolute)
                        {
                            d.SetPixelLeft(pos[ix, 0]);
                        }
                        d.SetPixelWidth(pos[ix, 1]);
                        
                    }
                    ix++;
                }
            }
            internal void AdjustHeight(int[,] pos)
            {
                var ix = 0;
                //Now set the size for all drawings depending on the editAs property.
                foreach (OfficeOpenXml.Drawing.ExcelDrawing d in this)
                {
                    if (d.EditAs != Drawing.eEditAs.TwoCell)
                    {
                        if (d.EditAs == Drawing.eEditAs.Absolute)
                        {
                            d.SetPixelTop(pos[ix, 0]);
                        }
                        d.SetPixelHeight(pos[ix, 1]);

                    }
                    ix++;
                }
            }
            internal int[,] GetDrawingWidths()
            {
                int[,] pos = new int[Count, 2];
                int ix = 0;
                //Save the size for all drawings
                foreach (ExcelDrawing d in this)
                {
                    pos[ix, 0] = d.GetPixelLeft();
                    pos[ix++, 1] = d.GetPixelWidth();
                }
                return pos;
            }
            internal int[,] GetDrawingHeight()
            {
                int[,] pos = new int[Count, 2];
                int ix = 0;
                //Save the size for all drawings
                foreach (ExcelDrawing d in this)
                {
                    pos[ix, 0] = d.GetPixelTop();
                    pos[ix++, 1] = d.GetPixelHeight();
                }
                return pos;
            }

            public void Dispose()
            {
                _drawingsXml = null;
                _hashes.Clear();
                _hashes = null;
                _part = null;
                _drawingNames.Clear();
                _drawingNames = null;
                _drawingRelation = null;
                foreach (var d in _drawings)
                {
                    d.Dispose();
                }
                _drawings.Clear();
                _drawings = null;
            }
    }
}
