﻿/*******************************************************************************
 * 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		        2010-06-01
 * Jan Källman		License changed GPL-->LGPL 2011-12-16
 *******************************************************************************/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Xml;
using OfficeOpenXml.Drawing.Chart;
namespace OfficeOpenXml.Drawing
{
    /// <summary>
    /// Text anchoring
    /// </summary>
    public enum eTextAnchoringType
    {
        Bottom,
        Center,
        Distributed,
        Justify,
        Top
    }
    /// <summary>
    /// Vertical text type
    /// </summary>
    public enum eTextVerticalType
    {
        EastAsianVertical,
        Horizontal,
        MongolianVertical,
        Vertical,
        Vertical270,
        WordArtVertical,
        WordArtVerticalRightToLeft

    }
    /// <summary>
    /// How the drawing will be resized.
    /// </summary>
    public enum eEditAs
    {
        /// <summary>
        /// Specifies that the current start and end positions shall
        /// be maintained with respect to the distances from the
        /// absolute start point of the worksheet.
        /// </summary>
        Absolute,
        /// <summary>
        /// Specifies that the current drawing shall move with its
        ///row and column (i.e. the object is anchored to the
        /// actual from row and column), but that the size shall
        ///remain absolute.
        /// </summary>
        OneCell,
        /// <summary>
        /// Specifies that the current drawing shall move and
        /// resize to maintain its row and column anchors (i.e. the
        /// object is anchored to the actual from and to row and column).
        /// </summary>
        TwoCell
    }
    /// <summary>
    /// Base class for twoanchored drawings. 
    /// Drawings are Charts, shapes and Pictures.
    /// </summary>
    public class ExcelDrawing : XmlHelper, IDisposable 
    {
        /// <summary>
        /// Position of the a drawing.
        /// </summary>
        public class ExcelPosition : XmlHelper
        {
            XmlNode _node;
            XmlNamespaceManager _ns;            
            internal ExcelPosition(XmlNamespaceManager ns, XmlNode node) :
                base (ns,node)
            {
                _node = node;
                _ns = ns;
            }
            const string colPath="xdr:col";
            public int Column
            {
                get
                {
                    return GetXmlNodeInt(colPath);
                }
                set
                {
                    SetXmlNodeString(colPath, value.ToString());
                }
            }
            const string rowPath="xdr:row";
            public int Row
            {
                get
                {
                    return GetXmlNodeInt(rowPath);
                }
                set
                {
                    SetXmlNodeString(rowPath, value.ToString());
                }
            }
            const string colOffPath = "xdr:colOff";
            /// <summary>
            /// Column Offset
            /// 
            /// EMU units   1cm         =   1/360000 
            ///             1US inch    =   1/914400
            ///             1pixel      =   1/9525
            /// </summary>
            public int ColumnOff
            {
                get
                {
                    return GetXmlNodeInt(colOffPath);
                }
                set
                {
                    SetXmlNodeString(colOffPath, value.ToString());
                }
            }
            const string rowOffPath = "xdr:rowOff";
            /// <summary>
            /// Row Offset
            /// 
            /// EMU units   1cm         =   1/360000 
            ///             1US inch    =   1/914400
            ///             1pixel      =   1/9525
            /// </summary>
            public int RowOff
            {
                get
                {
                    return GetXmlNodeInt(rowOffPath);
                }
                set
                {
                    SetXmlNodeString(rowOffPath, value.ToString());
                }
            }
        }
        protected ExcelDrawings _drawings;
        protected XmlNode _topNode;
        string _nameXPath;
        protected internal int _id;
        const float STANDARD_DPI = 96;
        public const int EMU_PER_PIXEL = 9525;

        internal ExcelDrawing(ExcelDrawings drawings, XmlNode node, string nameXPath) :
            base(drawings.NameSpaceManager, node)
        {
            _drawings = drawings;
            _topNode = node;
            _id = drawings.Worksheet.Workbook._nextDrawingID++;
            XmlNode posNode = node.SelectSingleNode("xdr:from", drawings.NameSpaceManager);
            if (node != null)
            {
                From = new ExcelPosition(drawings.NameSpaceManager, posNode);
            }
            posNode = node.SelectSingleNode("xdr:to", drawings.NameSpaceManager);
            if (node != null)
            {
                To = new ExcelPosition(drawings.NameSpaceManager, posNode);
            }
            else
            {
                To = null;
            }
            _nameXPath = nameXPath;
            SchemaNodeOrder = new string[] { "from", "to", "graphicFrame", "sp", "clientData"  };
        }
        /// <summary>
        /// The name of the drawing object
        /// </summary>
        public string Name 
        {
            get
            {
                try
                {
                    if (_nameXPath == "") return "";
                    return GetXmlNodeString(_nameXPath);
                }
                catch
                {
                    return ""; 
                }
            }
            set
            {
                try
                {
                    if (_nameXPath == "") throw new NotImplementedException();
                    SetXmlNodeString(_nameXPath, value);
                }
                catch
                {
                    throw new NotImplementedException();
                }
            }
        }
        /// <summary>
        /// How Excel resize drawings when the column width is changed within Excel.
        /// The width of drawings are currently NOT resized in EPPLus when the column width changes
        /// </summary>
        public eEditAs EditAs
        {
            get
            {
                try
                {
                    string s = GetXmlNodeString("@editAs");
                    if (s == "")
                    {
                        return eEditAs.TwoCell;
                    }
                    else
                    {
                        return (eEditAs)Enum.Parse(typeof(eEditAs), s,true);
                    }
                }
                catch
                {
                    return eEditAs.TwoCell;
                }
            }
            set
            {
                string s=value.ToString();
                SetXmlNodeString("@editAs", s.Substring(0,1).ToLower(CultureInfo.InvariantCulture)+s.Substring(1,s.Length-1));
            }
        }
        const string lockedPath="xdr:clientData/@fLocksWithSheet";
        /// <summary>
        /// Lock drawing
        /// </summary>
        public bool Locked
        {
            get
            {
                return GetXmlNodeBool(lockedPath, true);
            }
            set
            {
                SetXmlNodeBool(lockedPath, value);
            }
        }
        const string printPath = "xdr:clientData/@fPrintsWithSheet";
        /// <summary>
        /// Print drawing with sheet
        /// </summary>
        public bool Print
        {
            get
            {
                return GetXmlNodeBool(printPath, true);
            }
            set
            {
                SetXmlNodeBool(printPath, value);
            }
        }        /// <summary>
        /// Top Left position
        /// </summary>
        public ExcelPosition From { get; set; }
        /// <summary>
        /// Bottom right position
        /// </summary>
        public ExcelPosition To
        {
            get;
            set;
        }
        /// <summary>
        /// Add new Drawing types here
        /// </summary>
        /// <param name="drawings">The drawing collection</param>
        /// <param name="node">Xml top node</param>
        /// <returns>The Drawing object</returns>
        internal static ExcelDrawing GetDrawing(ExcelDrawings drawings, XmlNode node)
        {
            if (node.SelectSingleNode("xdr:sp", drawings.NameSpaceManager) != null)
            {
                return new ExcelShape(drawings, node);
            }
            else if (node.SelectSingleNode("xdr:pic", drawings.NameSpaceManager) != null)
            {
                return new ExcelPicture(drawings, node);
            }
            else if (node.SelectSingleNode("xdr:graphicFrame", drawings.NameSpaceManager) != null)
            {
                return ExcelChart.GetChart(drawings, node);
            }
            else
            {
                return new ExcelDrawing(drawings, node, "");
            }
        }
        internal string Id
        {
            get { return _id.ToString(); }
        }
        internal static string GetTextAchoringText(eTextAnchoringType value)
        {
            switch (value)
            {
                case eTextAnchoringType.Bottom:
                    return "b";
                case eTextAnchoringType.Center:
                    return "ctr";
                case eTextAnchoringType.Distributed:
                    return "dist";
                case eTextAnchoringType.Justify:
                    return "just";
                default:
                    return "t";
            }
        }
        internal static eTextAnchoringType GetTextAchoringEnum(string text)
        {
            switch (text)
            {
                case "b":
                    return eTextAnchoringType.Bottom;
                case "ctr":
                    return eTextAnchoringType.Center;
                case "dist":
                    return eTextAnchoringType.Distributed;
                case "just":
                    return eTextAnchoringType.Justify;
                default:
                    return eTextAnchoringType.Top;
            }
        }
        internal static string GetTextVerticalText(eTextVerticalType value)
        {
            switch (value)
            {
                case eTextVerticalType.EastAsianVertical:
                    return "eaVert";
                case eTextVerticalType.MongolianVertical:
                    return "mongolianVert";
                case eTextVerticalType.Vertical:
                    return "vert";
                case eTextVerticalType.Vertical270:
                    return "vert270";
                case eTextVerticalType.WordArtVertical:
                    return "wordArtVert";
                case eTextVerticalType.WordArtVerticalRightToLeft:
                    return "wordArtVertRtl";
                default:
                    return "horz";
            }
        }
        internal static eTextVerticalType GetTextVerticalEnum(string text)
        {
            switch (text)
            {
                case "eaVert":
                    return eTextVerticalType.EastAsianVertical;
                case "mongolianVert":
                    return eTextVerticalType.MongolianVertical;
                case "vert":
                    return eTextVerticalType.Vertical;
                case "vert270":
                    return eTextVerticalType.Vertical270;
                case "wordArtVert":
                    return eTextVerticalType.WordArtVertical;
                case "wordArtVertRtl":
                    return eTextVerticalType.WordArtVerticalRightToLeft;
                default:
                    return eTextVerticalType.Horizontal;
            }
        }
        #region "Internal sizing functions"
        internal int GetPixelLeft()
        {
            ExcelWorksheet ws = _drawings.Worksheet;
            decimal mdw = ws.Workbook.MaxFontWidth;

            int pix = 0;
            for (int col = 0; col < From.Column; col++)
            {
                pix += (int)decimal.Truncate(((256 * GetColumnWidth(col + 1) + decimal.Truncate(128 / (decimal)mdw)) / 256) * mdw);
            }
            pix += From.ColumnOff / EMU_PER_PIXEL;
            return pix;
        }
        internal int GetPixelTop()
        {
            ExcelWorksheet ws = _drawings.Worksheet;
            int pix = 0;
            for (int row = 0; row < From.Row; row++)
            {
                pix += (int)(GetRowWidth(row + 1) / 0.75);
            }
            pix += From.RowOff / EMU_PER_PIXEL;
            return pix;
        }
        internal int GetPixelWidth()
        {
            ExcelWorksheet ws = _drawings.Worksheet;
            decimal mdw = ws.Workbook.MaxFontWidth;

            int pix = -From.ColumnOff / EMU_PER_PIXEL;
            for (int col = From.Column + 1; col <= To.Column; col++)
            {
                pix += (int)decimal.Truncate(((256 * GetColumnWidth(col) + decimal.Truncate(128 / (decimal)mdw)) / 256) * mdw);
            }
            pix += To.ColumnOff / EMU_PER_PIXEL;
            return pix;
        }
        internal int GetPixelHeight()
        {
            ExcelWorksheet ws = _drawings.Worksheet;

            int pix = -(From.RowOff / EMU_PER_PIXEL);
            for (int row = From.Row + 1; row <= To.Row; row++)
            {
                pix += (int)(GetRowWidth(row) / 0.75);
            }
            pix += To.RowOff / EMU_PER_PIXEL;
            return pix;
        }

        private decimal GetColumnWidth(int col)
        {
            ExcelWorksheet ws = _drawings.Worksheet;
            var column = ws._values.GetValue(0, col) as ExcelColumn;
            if (column == null)   //Check that the column exists
            {
                return (decimal)ws.DefaultColWidth;
            }
            else
            {
                return (decimal)ws.Column(col).VisualWidth;
            }
        }
        private double GetRowWidth(int row)
        {
            ExcelWorksheet ws = _drawings.Worksheet;
            object o = null;
            if (ws._values.Exists(row, 0, ref o) && o != null)   //Check that the row exists
            {
                var internalRow = (RowInternal)o;
                if (internalRow.Height >= 0)
                {
                    return internalRow.Height;
                }
            }
            return (double)ws.DefaultRowHeight;
        }
        internal void SetPixelTop(int pixels)
        {
            ExcelWorksheet ws = _drawings.Worksheet;
            decimal mdw = ws.Workbook.MaxFontWidth;
            int prevPix = 0;
            int pix = (int)(GetRowWidth(1) / 0.75);
            int row = 2;

            while (pix < pixels)
            {
                prevPix = pix;
                pix += (int)(GetRowWidth(row++) / 0.75);
            }

            if (pix == pixels)
            {
                From.Row = row - 1;
                From.RowOff = 0;
            }
            else
            {
                From.Row = row - 2;
                From.RowOff = (pixels - prevPix) * EMU_PER_PIXEL;
            }
        }
        internal void SetPixelLeft(int pixels)
        {
            ExcelWorksheet ws = _drawings.Worksheet;
            decimal mdw = ws.Workbook.MaxFontWidth;
            int prevPix = 0;
            int pix = (int)decimal.Truncate(((256 * GetColumnWidth(1) + decimal.Truncate(128 / (decimal)mdw)) / 256) * mdw);
            int col = 2;

            while (pix < pixels)
            {
                prevPix = pix;
                pix += (int)decimal.Truncate(((256 * GetColumnWidth(col++) + decimal.Truncate(128 / (decimal)mdw)) / 256) * mdw);
            }
            if (pix == pixels)
            {
                From.Column = col - 1;
                From.ColumnOff = 0;
            }
            else
            {
                From.Column = col - 2;
                From.ColumnOff = (pixels - prevPix) * EMU_PER_PIXEL;
            }
        }
        internal void SetPixelHeight(int pixels)
        {
            SetPixelHeight(pixels, STANDARD_DPI);
        }
        internal void SetPixelHeight(int pixels, float dpi)
        {
            ExcelWorksheet ws = _drawings.Worksheet;
            //decimal mdw = ws.Workbook.MaxFontWidth;
            pixels = (int)(pixels / (dpi / STANDARD_DPI) + .5);
            int pixOff = pixels - ((int)(ws.Row(From.Row + 1).Height / 0.75) - (int)(From.RowOff / EMU_PER_PIXEL));
            int prevPixOff = pixels;
            int row = From.Row + 1;

            while (pixOff >= 0)
            {
                prevPixOff = pixOff;
                pixOff -= (int)(GetRowWidth(++row) / 0.75);
            }
            To.Row = row - 1;
            if (From.Row == To.Row)
            {
                To.RowOff = From.RowOff + (pixels) * EMU_PER_PIXEL;
            }
            else
            {
                To.RowOff = prevPixOff * EMU_PER_PIXEL;
            }
        }
        internal void SetPixelWidth(int pixels)
        {
            SetPixelWidth(pixels, STANDARD_DPI);
        }
        internal void SetPixelWidth(int pixels, float dpi)
        {
            ExcelWorksheet ws = _drawings.Worksheet;
            decimal mdw = ws.Workbook.MaxFontWidth;

            pixels = (int)(pixels / (dpi / STANDARD_DPI) + .5);
            int pixOff = (int)pixels - ((int)decimal.Truncate(((256 * GetColumnWidth(From.Column + 1) + decimal.Truncate(128 / (decimal)mdw)) / 256) * mdw) - From.ColumnOff / EMU_PER_PIXEL);
            int prevPixOff = From.ColumnOff / EMU_PER_PIXEL + (int)pixels;
            int col = From.Column + 2;

            while (pixOff >= 0)
            {
                prevPixOff = pixOff;
                pixOff -= (int)decimal.Truncate(((256 * GetColumnWidth(col++) + decimal.Truncate(128 / (decimal)mdw)) / 256) * mdw);
            }

            To.Column = col - 2;
            To.ColumnOff = prevPixOff * EMU_PER_PIXEL;
        }
        #endregion
        #region "Public sizing functions"
        /// <summary>
        /// Set the top left corner of a drawing. 
        /// Note that resizing columns / rows after using this function will effect the position of the drawing
        /// </summary>
        /// <param name="PixelTop">Top pixel</param>
        /// <param name="PixelLeft">Left pixel</param>
        public void SetPosition(int PixelTop, int PixelLeft)
        {
            int width = GetPixelWidth();
            int height = GetPixelHeight();

            SetPixelTop(PixelTop);
            SetPixelLeft(PixelLeft);

            SetPixelWidth(width);
            SetPixelHeight(height);
        }
        /// <summary>
        /// Set the top left corner of a drawing. 
        /// Note that resizing columns / rows after using this function will effect the position of the drawing
        /// </summary>
        /// <param name="Row">Start row</param>
        /// <param name="RowOffsetPixels">Offset in pixels</param>
        /// <param name="Column">Start Column</param>
        /// <param name="ColumnOffsetPixels">Offset in pixels</param>
        public void SetPosition(int Row, int RowOffsetPixels, int Column, int ColumnOffsetPixels)
        {
            int width = GetPixelWidth();
            int height = GetPixelHeight();

            From.Row = Row;
            From.RowOff = RowOffsetPixels * EMU_PER_PIXEL;
            From.Column = Column;
            From.ColumnOff = ColumnOffsetPixels * EMU_PER_PIXEL;

            SetPixelWidth(width);
            SetPixelHeight(height);
        }
        /// <summary>
        /// Set size in Percent
        /// Note that resizing columns / rows after using this function will effect the size of the drawing
        /// </summary>
        /// <param name="Percent"></param>
        public virtual void SetSize(int Percent)
        {
            int width = GetPixelWidth();
            int height = GetPixelHeight();

            width = (int)(width * ((decimal)Percent / 100));
            height = (int)(height * ((decimal)Percent / 100));

            SetPixelWidth(width, 96);
            SetPixelHeight(height, 96);
        }
        /// <summary>
        /// Set size in pixels
        /// Note that resizing columns / rows after using this function will effect the size of the drawing
        /// </summary>
        /// <param name="PixelWidth">Width in pixels</param>
        /// <param name="PixelHeight">Height in pixels</param>
        public void SetSize(int PixelWidth, int PixelHeight)
        {
            SetPixelWidth(PixelWidth);
            SetPixelHeight(PixelHeight);
        }
        #endregion
        internal virtual void DeleteMe()
        {
            TopNode.ParentNode.RemoveChild(TopNode);
        }

        public virtual void Dispose()
        {
            _topNode = null;
        }
    }
}
