﻿using System.Globalization;
using OfficeOpenXml.Packaging;
using OfficeOpenXml.Table.PivotTable;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;

namespace OfficeOpenXml.Drawing.Chart
{
    /// <summary>
    /// Provides access to bubble chart specific properties
    /// </summary>
    public sealed class ExcelBubbleChart : ExcelChart
    {
        internal ExcelBubbleChart(ExcelDrawings drawings, XmlNode node, eChartType type, ExcelChart topChart, ExcelPivotTable PivotTableSource) :
            base(drawings, node, type, topChart, PivotTableSource)
        {
            ShowNegativeBubbles = false;
            BubbleScale = 100;
            _chartSeries = new ExcelBubbleChartSeries(this, drawings.NameSpaceManager, _chartNode, PivotTableSource!=null);
            //SetTypeProperties();
        }

        internal ExcelBubbleChart(ExcelDrawings drawings, XmlNode node, eChartType type, bool isPivot) :
            base(drawings, node, type, isPivot)
        {
            _chartSeries = new ExcelBubbleChartSeries(this, drawings.NameSpaceManager, _chartNode, isPivot);
            //SetTypeProperties();
        }
        internal ExcelBubbleChart(ExcelDrawings drawings, XmlNode node, Uri uriChart, ZipPackagePart part, XmlDocument chartXml, XmlNode chartNode) :
            base(drawings, node, uriChart, part, chartXml, chartNode)
        {
            _chartSeries = new ExcelBubbleChartSeries(this, _drawings.NameSpaceManager, _chartNode, false);
            //SetTypeProperties();
        }
        internal ExcelBubbleChart(ExcelChart topChart, XmlNode chartNode) :
            base(topChart, chartNode)
        {
            _chartSeries = new ExcelBubbleChartSeries(this, _drawings.NameSpaceManager, _chartNode, false);
        }
        string BUBBLESCALE_PATH = "c:bubbleScale/@val";
        /// <summary>
        /// Specifies the scale factor for the bubble chart. Can range from 0 to 300, corresponding to a percentage of the default size,
        /// </summary>
        public int BubbleScale
        {
            get
            {
                return _chartXmlHelper.GetXmlNodeInt(BUBBLESCALE_PATH);
            }
            set
            {
                if(value < 0 && value > 300)
                {
                    throw(new ArgumentOutOfRangeException("Bubblescale out of range. 0-300 allowed"));
                }
                _chartXmlHelper.SetXmlNodeString(BUBBLESCALE_PATH, value.ToString());
            }
        }
        string SHOWNEGBUBBLES_PATH = "c:showNegBubbles/@val";
        /// <summary>
        /// Specifies the scale factor for the bubble chart. Can range from 0 to 300, corresponding to a percentage of the default size,
        /// </summary>
        public bool ShowNegativeBubbles
        {
            get
            {
                return _chartXmlHelper.GetXmlNodeBool(SHOWNEGBUBBLES_PATH);
            }
            set
            {
                _chartXmlHelper.SetXmlNodeBool(BUBBLESCALE_PATH, value, true);
            }
        }
        string BUBBLE3D_PATH = "c:bubble3D/@val";
        /// <summary>
        /// Specifies if the bubblechart is three dimensional
        /// </summary>
        public bool Bubble3D
        {
            get
            {
                return _chartXmlHelper.GetXmlNodeBool(BUBBLE3D_PATH);
            }
            set
            {
                _chartXmlHelper.SetXmlNodeBool(BUBBLE3D_PATH, value);
                ChartType = value ? eChartType.Bubble3DEffect : eChartType.Bubble;
            }
        }
        string SIZEREPRESENTS_PATH = "c:sizeRepresents/@val";
        /// <summary>
        /// Specifies the scale factor for the bubble chart. Can range from 0 to 300, corresponding to a percentage of the default size,
        /// </summary>
        public eSizeRepresents SizeRepresents
        {
            get
            {
                var v = _chartXmlHelper.GetXmlNodeString(SIZEREPRESENTS_PATH).ToLower(CultureInfo.InvariantCulture);
                if (v == "w")
                {
                    return eSizeRepresents.Width;
                }
                else
                {
                    return eSizeRepresents.Area;
                }
            }
            set
            {
                _chartXmlHelper.SetXmlNodeString(SIZEREPRESENTS_PATH, value == eSizeRepresents.Width ? "w" : "area");
            }
        }
        public new ExcelBubbleChartSeries Series
        {
            get
            {

                return (ExcelBubbleChartSeries)_chartSeries;
            }
        }
        internal override eChartType GetChartType(string name)
        {
            if (Bubble3D)
            {
                return eChartType.Bubble3DEffect;
            }
            else
            {
                return eChartType.Bubble;
            }
        }
    }
}
