﻿/*******************************************************************************
 * 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.Linq;
using IronSoftware.Drawing;
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, AnyBitmap 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, AnyBitmap 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;
            }
    }
}
