Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Linq

Namespace Nexamas.UI.Visualization

    ''' <summary>
    ''' Immutable chart series. It is data only and does not own rendering, controls, or data querying.
    ''' </summary>
    Friend NotInheritable Class MASChartSeries

        Private ReadOnly _points As IReadOnlyList(Of MASChartDataPoint)

        Friend Sub New(seriesKey As String,
                       label As String,
                       points As IEnumerable(Of MASChartDataPoint))
            Me.SeriesKey = MASChartDataPoint.NormalizeText(seriesKey)
            Me.Label = MASChartDataPoint.NormalizeText(label)
            If Me.Label.Length = 0 Then Me.Label = Me.SeriesKey
            _points = New ReadOnlyCollection(Of MASChartDataPoint)(NormalizePoints(points))
        End Sub

        Friend ReadOnly Property SeriesKey As String
        Friend ReadOnly Property Label As String

        Friend ReadOnly Property Points As IReadOnlyList(Of MASChartDataPoint)
            Get
                Return _points
            End Get
        End Property

        Friend ReadOnly Property PointCount As Integer
            Get
                Return _points.Count
            End Get
        End Property

        Friend ReadOnly Property IsValid As Boolean
            Get
                Return SeriesKey.Length > 0 AndAlso Label.Length > 0 AndAlso PointCount > 0 AndAlso _points.All(Function(point) point.IsValid)
            End Get
        End Property

        Friend ReadOnly Property MinValue As Double
            Get
                If PointCount = 0 Then Return 0.0R
                Return _points.Min(Function(point) point.Value)
            End Get
        End Property

        Friend ReadOnly Property MaxValue As Double
            Get
                If PointCount = 0 Then Return 0.0R
                Return _points.Max(Function(point) point.Value)
            End Get
        End Property

        Friend ReadOnly Property PositiveValueTotal As Double
            Get
                Return _points.Where(Function(point) point.Value > 0.0R).Sum(Function(point) point.Value)
            End Get
        End Property

        Friend Shared Function Create(seriesKey As String,
                                      label As String,
                                      ParamArray points As MASChartDataPoint()) As MASChartSeries
            Return New MASChartSeries(seriesKey, label, points)
        End Function

        Private Shared Function NormalizePoints(points As IEnumerable(Of MASChartDataPoint)) As List(Of MASChartDataPoint)
            Dim result As New List(Of MASChartDataPoint)()
            If points Is Nothing Then Return result

            For Each point As MASChartDataPoint In points
                If point IsNot Nothing Then result.Add(point)
            Next

            Return result
        End Function

    End Class

End Namespace
