﻿/*******************************************************************************
 * 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		Added		2009-10-01
 * 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 OfficeOpenXml.Table.PivotTable;
namespace OfficeOpenXml.Drawing.Chart
{
    public sealed class ExcelBubbleChartSeries : ExcelChartSeries
    {
        internal ExcelBubbleChartSeries(ExcelChart chart, XmlNamespaceManager ns, XmlNode node, bool isPivot)
           : base(chart,ns,node, isPivot)
        {
            //_chartSeries = new ExcelChartSeries(this, _drawings.NameSpaceManager, _chartNode, isPivot);
        }
        public ExcelChartSerie Add(ExcelRangeBase Serie, ExcelRangeBase XSerie, ExcelRangeBase BubbleSize)
        {
            return base.AddSeries(Serie.FullAddressAbsolute, XSerie.FullAddressAbsolute, BubbleSize.FullAddressAbsolute);
        }
        public ExcelChartSerie Add(string SerieAddress, string XSerieAddress, string BubbleSizeAddress)
        {
            return base.AddSeries(SerieAddress, XSerieAddress, BubbleSizeAddress);
        }
    }
    /// <summary>
   /// Collection class for chart series
   /// </summary>
    public class ExcelChartSeries : XmlHelper, IEnumerable
    {
       List<ExcelChartSerie> _list=new List<ExcelChartSerie>();
       internal ExcelChart _chart;
       XmlNode _node;
       XmlNamespaceManager _ns;
       internal ExcelChartSeries(ExcelChart chart, XmlNamespaceManager ns, XmlNode node, bool isPivot)
           : base(ns,node)
       {
           _ns = ns;
           _chart=chart;
           _node=node;
           _isPivot = isPivot;
           SchemaNodeOrder = new string[] { "view3D", "plotArea", "barDir", "grouping", "scatterStyle", "varyColors", "ser", "explosion", "dLbls", "firstSliceAng", "holeSize", "shape", "legend", "axId" };
           foreach(XmlNode n in node.SelectNodes("c:ser",ns))
           {
               ExcelChartSerie s;
               if (chart.ChartNode.LocalName == "scatterChart")
               {
                   s = new ExcelScatterChartSerie(this, ns, n, isPivot);
               }
               else if (chart.ChartNode.LocalName == "lineChart")
               {
                   s = new ExcelLineChartSerie(this, ns, n, isPivot);
               }
               else if (chart.ChartNode.LocalName == "pieChart" ||
                        chart.ChartNode.LocalName == "ofPieChart" ||
                        chart.ChartNode.LocalName == "pie3DChart" ||
                        chart.ChartNode.LocalName == "doughnutChart")                                                                       
               {
                   s = new ExcelPieChartSerie(this, ns, n, isPivot);
               }
               else
               {
                   s = new ExcelChartSerie(this, ns, n, isPivot);
               }
               _list.Add(s);
           }
       }

       #region IEnumerable Members

       public IEnumerator GetEnumerator()
       {
           return (_list.GetEnumerator());
       }
       /// <summary>
       /// Returns the serie at the specified position.  
       /// </summary>
       /// <param name="PositionID">The position of the series.</param>
       /// <returns></returns>
       public ExcelChartSerie this[int PositionID]
       {
           get
           {
               return (_list[PositionID]);
           }
       }
       public int Count
       {
           get
           {
               return _list.Count;
           }
       }
       /// <summary>
       /// Delete the chart at the specific position
       /// </summary>
       /// <param name="PositionID">Zero based</param>
       public void Delete(int PositionID)
       {
           ExcelChartSerie ser = _list[PositionID];
           ser.TopNode.ParentNode.RemoveChild(ser.TopNode);
           _list.RemoveAt(PositionID);
       }
       #endregion
       /// <summary>
       /// A reference to the chart object
       /// </summary>
       public ExcelChart Chart
       {
           get
           {
               return _chart;
           }
       }
       #region "Add Series"

       /// <summary>
       /// Add a new serie to the chart. Do not apply to pivotcharts.
       /// </summary>
       /// <param name="Serie">The Y-Axis range</param>
       /// <param name="XSerie">The X-Axis range</param>
       /// <returns></returns>
       public virtual ExcelChartSerie Add(ExcelRangeBase Serie, ExcelRangeBase XSerie)
       {
           if (_chart.PivotTableSource != null)
           {
               throw (new InvalidOperationException("Can't add a serie to a pivotchart"));
           }
           return AddSeries(Serie.FullAddressAbsolute, XSerie.FullAddressAbsolute,"");
       }
       /// <summary>
       /// Add a new serie to the chart.Do not apply to pivotcharts.
       /// </summary>
       /// <param name="SerieAddress">The Y-Axis range</param>
       /// <param name="XSerieAddress">The X-Axis range</param>
       /// <returns></returns>
       public virtual ExcelChartSerie Add(string SerieAddress, string XSerieAddress)
       {
           if (_chart.PivotTableSource != null)
           {
               throw (new InvalidOperationException("Can't add a serie to a pivotchart"));
           }
           return AddSeries(SerieAddress, XSerieAddress, "");
       }
       internal protected ExcelChartSerie AddSeries(string SeriesAddress, string XSeriesAddress, string bubbleSizeAddress)
        {
               XmlElement ser = _node.OwnerDocument.CreateElement("ser", ExcelPackage.schemaChart);
               XmlNodeList node = _node.SelectNodes("c:ser", _ns);
               if (node.Count > 0)
               {
                   _node.InsertAfter(ser, node[node.Count-1]);
               }
               else
               {
                   InserAfter(_node, "c:varyColors,c:grouping,c:barDir,c:scatterStyle", ser);
                }
               int idx = FindIndex();
               ser.InnerXml = string.Format("<c:idx val=\"{1}\" /><c:order val=\"{1}\" /><c:tx><c:strRef><c:f></c:f><c:strCache><c:ptCount val=\"1\" /></c:strCache></c:strRef></c:tx>{5}{0}{2}{3}{4}", AddExplosion(Chart.ChartType), idx, AddScatterPoint(Chart.ChartType), AddAxisNodes(Chart.ChartType), AddSmooth(Chart.ChartType), AddMarker(Chart.ChartType));
               ExcelChartSerie serie;
               switch (Chart.ChartType)
               {
                   case eChartType.Bubble:
                   case eChartType.Bubble3DEffect:
                       serie = new ExcelBubbleChartSerie(this, NameSpaceManager, ser, _isPivot)
                       {
                           Bubble3D=Chart.ChartType==eChartType.Bubble3DEffect,
                           Series = SeriesAddress,
                           XSeries = XSeriesAddress,
                           BubbleSize = bubbleSizeAddress                            
                       };
                       break;
                   case eChartType.XYScatter:
                   case eChartType.XYScatterLines:
                   case eChartType.XYScatterLinesNoMarkers:
                   case eChartType.XYScatterSmooth:
                   case eChartType.XYScatterSmoothNoMarkers:
                       serie = new ExcelScatterChartSerie(this, NameSpaceManager, ser, _isPivot);
                       break;
                   case eChartType.Radar:
                   case eChartType.RadarFilled:
                   case eChartType.RadarMarkers:
                       serie = new ExcelRadarChartSerie(this, NameSpaceManager, ser, _isPivot);
                       break;
                   case eChartType.Surface:
                   case eChartType.SurfaceTopView:
                   case eChartType.SurfaceTopViewWireframe:
                   case eChartType.SurfaceWireframe:
                       serie = new ExcelSurfaceChartSerie(this, NameSpaceManager, ser, _isPivot);
                       break;
                   case eChartType.Pie:
                   case eChartType.Pie3D:
                   case eChartType.PieExploded:
                   case eChartType.PieExploded3D:
                   case eChartType.PieOfPie:
                   case eChartType.Doughnut:
                   case eChartType.DoughnutExploded:
                   case eChartType.BarOfPie:
                       serie = new ExcelPieChartSerie(this, NameSpaceManager, ser, _isPivot);
                       break;
                   case eChartType.Line:
                   case eChartType.LineMarkers:
                   case eChartType.LineMarkersStacked:
                   case eChartType.LineMarkersStacked100:
                   case eChartType.LineStacked:
                   case eChartType.LineStacked100:
                       serie = new ExcelLineChartSerie(this, NameSpaceManager, ser, _isPivot);
                       if (Chart.ChartType == eChartType.LineMarkers ||
                           Chart.ChartType == eChartType.LineMarkersStacked ||
                           Chart.ChartType == eChartType.LineMarkersStacked100)
                       {
                           ((ExcelLineChartSerie)serie).Marker = eMarkerStyle.Square;
                       }
                       ((ExcelLineChartSerie)serie).Smooth = ((ExcelLineChart)Chart).Smooth;
                       break;
                   case eChartType.BarClustered:
                   case eChartType.BarStacked:
                   case eChartType.BarStacked100:
                   case eChartType.ColumnClustered:
                   case eChartType.ColumnStacked:
                   case eChartType.ColumnStacked100:
                   case eChartType.BarClustered3D:
                   case eChartType.BarStacked3D:
                   case eChartType.BarStacked1003D:
                   case eChartType.ColumnClustered3D:
                   case eChartType.ColumnStacked3D:
                   case eChartType.ColumnStacked1003D:
                   case eChartType.ConeBarClustered:
                   case eChartType.ConeBarStacked:
                   case eChartType.ConeBarStacked100:
                   case eChartType.ConeCol:
                   case eChartType.ConeColClustered:
                   case eChartType.ConeColStacked:
                   case eChartType.ConeColStacked100:
                   case eChartType.CylinderBarClustered:
                   case eChartType.CylinderBarStacked:
                   case eChartType.CylinderBarStacked100:
                   case eChartType.CylinderCol:
                   case eChartType.CylinderColClustered:
                   case eChartType.CylinderColStacked:
                   case eChartType.CylinderColStacked100:
                   case eChartType.PyramidBarClustered:
                   case eChartType.PyramidBarStacked:
                   case eChartType.PyramidBarStacked100:
                   case eChartType.PyramidCol:
                   case eChartType.PyramidColClustered:
                   case eChartType.PyramidColStacked:
                   case eChartType.PyramidColStacked100:
                       serie = new ExcelBarChartSerie(this, NameSpaceManager, ser, _isPivot);
                       ((ExcelBarChartSerie)serie).InvertIfNegative=false;
                       break;
                   default:
                       serie = new ExcelChartSerie(this, NameSpaceManager, ser, _isPivot);
                       break;
               }               
               serie.Series = SeriesAddress;
               serie.XSeries = XSeriesAddress;                     
           _list.Add(serie);
               return serie;
        }
       bool _isPivot;
       internal void AddPivotSerie(ExcelPivotTable pivotTableSource)
       {
           var r=pivotTableSource.WorkSheet.Cells[pivotTableSource.Address.Address];
           _isPivot = true;
           AddSeries(r.Offset(0, 1, r._toRow - r._fromRow + 1, 1).FullAddressAbsolute, r.Offset(0, 0, r._toRow - r._fromRow + 1, 1).FullAddressAbsolute,"");
       }
       private int FindIndex()
       {    
           int ret = 0, newID=0;
           if (_chart.PlotArea.ChartTypes.Count > 1)
           {
               foreach (var chart in _chart.PlotArea.ChartTypes)
               {
                   if (newID>0)
                   {
                       foreach (ExcelChartSerie serie in chart.Series)
                       {
                           serie.SetID((++newID).ToString());
                       }
                   }
                   else
                   {
                       if (chart == _chart)
                       {
                           ret += _list.Count + 1;
                           newID=ret;
                       }
                       else
                       {
                           ret += chart.Series.Count;
                       }
                   }
               }
               return ret-1;
           }
           else
           {
               return _list.Count;
           }
       }
       #endregion
       #region "Xml init Functions"
       private string AddMarker(eChartType chartType)
       {
           if (chartType == eChartType.Line ||
               chartType == eChartType.LineStacked ||
               chartType == eChartType.LineStacked100 ||
               chartType == eChartType.XYScatterLines ||
               chartType == eChartType.XYScatterSmooth ||
               chartType == eChartType.XYScatterLinesNoMarkers ||
               chartType == eChartType.XYScatterSmoothNoMarkers)
           {
               return "<c:marker><c:symbol val=\"none\" /></c:marker>";
           }
           else
           {
               return "";
           }
       }
       private string AddScatterPoint(eChartType chartType)
       {
           if (chartType == eChartType.XYScatter)
           {
               return "<c:spPr><a:ln w=\"28575\"><a:noFill /></a:ln></c:spPr>";
           }
           else
           {
               return "";
           }
       }
       private string AddAxisNodes(eChartType chartType)
       {
           if ( chartType == eChartType.XYScatter ||
                chartType == eChartType.XYScatterLines ||
                chartType == eChartType.XYScatterLinesNoMarkers ||
                chartType == eChartType.XYScatterSmooth ||
                chartType == eChartType.XYScatterSmoothNoMarkers || 
                chartType == eChartType.Bubble ||
                chartType == eChartType.Bubble3DEffect)
           {
               return "<c:xVal /><c:yVal />";
           }
           else
           {
               return "<c:val />";
           }
       }

       private string AddExplosion(eChartType chartType)
       {
           if (chartType == eChartType.PieExploded3D ||
              chartType == eChartType.PieExploded ||
               chartType == eChartType.DoughnutExploded)
           {
               return "<c:explosion val=\"25\" />"; //Default 25;
           }
           else
           {
               return "";
           }
       }
       private string AddSmooth(eChartType chartType)
       {
           if (chartType == eChartType.XYScatterSmooth ||
              chartType == eChartType.XYScatterSmoothNoMarkers)
           {
               return "<c:smooth val=\"1\" />"; //Default 25;
           }
           else
           {
               return "";
           }
       }
        #endregion
    }
}
