#region << Using Directives >>
using System;
#endregion

namespace Volpe.Cafe.EspressoUI.Charts
{
    /// <summary>
    /// Provides information for a single data series.
    /// </summary>
    [Serializable]
    class DataSeries
    {

        #region /*** Ctors ***/

        /// <summary>
        /// Initializes a new instance of the <see cref="DataSeries"/> class.
        /// </summary>
        /// <param name="name">Specifies the name of the series displayed in the chart's legend.</param>
        public DataSeries(string name) : this(name, AxisType.Primary, ChartStyle.Default, true, null, null) { }
        /// <summary>
        /// Initializes a new instance of the <see cref="DataSeries"/> class.
        /// </summary>
        /// <param name="name">Specifies the name of the series displayed in the chart's legend.</param>
        /// <param name="axis">Specifies whether the series uses primary or secondary values axis.</param>
        /// <param name="style">Specifies the display style of the series.</param>
        /// <param name="visible">Specifies whether the series should be displayed on the chart.</param>
        /// <param name="xValues">Specifies the category values for the series (typically, the X-Axis).</param>
        /// <param name="values">Specifies the axis values for the series (typically, the Y-Axis).</param>
        public DataSeries(string name, AxisType axis, ChartStyle style, bool visible, double[] xValues, double[] values)
        {
            this.Name                 = name;
            this.Axis                 = axis;
            this.Style                = style;
            this.Visible              = visible;
            this.ColorIndex           = -1;
            this.AlternateValueColors = false;
            //
            this.SetXYValues(xValues, values, 3);
        }

        #endregion

        #region /*** Methods ***/

        void SetXYValues(double[] newXValues, double[] newValues, int flags)
        {
            // flags: 1 = set X; 2 = set Y; 3 = set both
            double[] xValues = ((flags & 1) == 1) ? newXValues : this._xValues;
            double[] yValues = ((flags & 2) == 2) ? newValues  : this._values;

            // if both x/y values are present, the x values array must be >= y values array (to ensure all data points fit)
            if (xValues != null && yValues != null && (xValues.Length < yValues.Length))
            {
                throw new ArgumentOutOfRangeException("XValues|Values",
                    "When specifying XValues, the number of elements must be equal to or greater than the number of Values.");
            }

            // set new x/y
            this._xValues = xValues;
            this._values  = yValues;
        }

        #endregion

        #region /*** Properties ***/

        /// <summary>Get or sets the name of the series displayed in the chart's legend.</summary>
        public string Name { get; set; }
        /// <summary>Get or sets whether the series uses primary or secondary values axis.</summary>
        public AxisType Axis { get; set; }
        /// <summary>Get whether the series uses primary values axis.</summary>
        public bool IsPrimaryAxis { get { return this.Axis == AxisType.Primary; } }
        /// <summary>Get whether the series uses secondary values axis.</summary>
        public bool IsSecondaryAxis { get { return this.Axis == AxisType.Secondary; } }
        /// <summary>Get or sets the display style of the series.</summary>
        public ChartStyle Style { get; set; }
        /// <summary>Gets or sets whether the series should be displayed on the chart.</summary>
        public bool Visible { get; set; }
        /// <summary>Gets or sets the color index to use for the series, or -1, to auto-choose one.</summary>
        public int ColorIndex { get; set; }
        /// <summary>Gets or sets whether to alternate colors for each series value. If this property is set to false (default),
        ///   a single color will be used for all values within the series.</summary>
        public bool AlternateValueColors { get; set; }
        /// <summary>Get or sets the category values for the series (typically, the X-Axis).</summary>
        /// <remarks>If this property is null, the category values will be inhertied from the first data-series defined for the
        ///   chart. If this instance represents the first data-series, or if the first series' values are also null, the category
        ///   values will be auto-incremented starting with 1 (as such: 1, 2, 3, ...).</remarks>
        public double[] XValues { get { return this._xValues; } set { this.SetXYValues(value, null, 1); } }
        /// <summary>Get or sets the axis values for the series (typically, the Y-Axis).</summary>
        public double[] Values { get { return this._values; } set { this.SetXYValues(null, value, 2); } }

        #endregion

        #region /*** Variables ***/

        double[] _xValues;
        double[] _values;

        #endregion

    }
}
