Imports System.Threading.Tasks
Imports System.Text
Imports System.Linq
Imports System.Data
Imports System.Collections.Generic
Imports System
Imports C1.Chart
Imports System.Collections

Class DataCreator
    Public Delegate Function MathActionDouble(num As Double) As Double
    Public Delegate Function MathActionInt(num As Integer) As Double

    Public Shared Function CreateSimpleChartTypes() As Dictionary(Of ChartType, String)
        Dim types As New Dictionary(Of ChartType, String)()
        types = New Dictionary(Of ChartType, String)()
        types.Add(ChartType.Column, Strings.Column)
        types.Add(ChartType.Bar, Strings.Bar)
        types.Add(ChartType.Line, Strings.Line)
        types.Add(ChartType.Scatter, Strings.Scatter)
        types.Add(ChartType.LineSymbols, Strings.LineSymbols)
        types.Add(ChartType.Area, Strings.Area)
        types.Add(ChartType.Spline, Strings.Spline)
        types.Add(ChartType.SplineArea, Strings.SplineArea)
        types.Add(ChartType.SplineSymbols, Strings.SplineSymbols)

        Return types
    End Function

    Public Shared Function CreateFinancialChartTypes() As Dictionary(Of ChartType, String)
        Dim types As New Dictionary(Of ChartType, String)()
        types.Add(ChartType.Candlestick, Strings.Candlestick)
        types.Add(ChartType.HighLowOpenClose, Strings.HighLowOpenClose)

        Return types
    End Function

    Public Shared Function Create([function] As MathActionDouble, from As Double, [to] As Double, [step] As Double) As List(Of DataPoint)
        Dim result As New List(Of DataPoint)()
        Dim count As Double = ([to] - from) / [step]

        Dim r As Double = from
        While r < [to]
            result.Add(New DataPoint() With {
                .XVals = r,
                .YVals = [function](r)
            })
            r += [step]
        End While
        Return result
    End Function

    Public Shared Function Create([function] As MathActionInt, from As Integer, [to] As Integer, [step] As Integer) As List(Of DataPoint)
        Dim result As New List(Of DataPoint)()
        Dim count As Double = ([to] - from) / [step]

        Dim r As Integer = from
        While r < [to]
            result.Add(New DataPoint() With {
                .XVals = r,
                .YVals = [function](r)
            })
            r += [step]
        End While
        Return result
    End Function

    Public Shared Function Create(functionX As MathActionDouble, functionY As MathActionDouble, ptsCount As Integer) As List(Of DataPoint)
        Dim result As New List(Of DataPoint)()

        Dim i As Double = 0
        While i < ptsCount
            result.Add(New DataPoint() With {
                .XVals = functionX(i),
                .YVals = functionY(i)
            })
            i += 1
        End While
        Return result
    End Function

    Public Shared Function Create(coef As String(), ptsCount As Integer) As List(Of DataPoint)
        Dim result As New List(Of DataPoint)()

        Dim x As Double() = New Double(ptsCount) {}
        Dim y As Double() = New Double(ptsCount) {}
        Dim rnd As New Random()
        Dim c As Double() = StringToCoeff(coef(rnd.[Next](coef.Length)))

        Dim i As Integer = 1
        While i < ptsCount
            Dim pt As DataPoint = Iterate(x(i - 1), y(i - 1), c)
            result.Add(pt)
            x(i) = pt.XVals
            y(i) = pt.YVals
            i += 1
        End While

        Return result
    End Function

    Public Shared Function CreateFruit() As List(Of FruitDataItem)
        Dim fruits() As String = {"Oranges", "Apples", "Pears", "Bananas"}
        Dim count As Integer = fruits.Length
        Dim result As New List(Of FruitDataItem)()
        Dim rnd As New Random()
        Dim i As Integer = 0
        While i < count
            result.Add(New FruitDataItem() With {
                .Fruit = fruits(i),
                .March = rnd.[Next](20),
                .April = rnd.[Next](20),
                .May = rnd.[Next](20)
            })
            i += 1
        End While
        Return result
    End Function

    Public Shared Function CreateWaterfallData() As List(Of WaterfallItem)
        Dim rnd As New Random
        Dim items As New List(Of WaterfallItem)
        Dim names() As String = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}
        For Each name As String In names
            items.Add(New WaterfallItem With {
                      .Name = name,
                      .Value = Math.Round((0.5 - rnd.NextDouble()) * 1000)})
        Next
        Return items
    End Function

    Public Shared Function CreateChartTypesForErrorBar() As IDictionary(Of ChartType, String)
        Dim types As Dictionary(Of ChartType, String) = New Dictionary(Of ChartType, String)
        types.Add(ChartType.Column, Strings.Column)
            types.Add(ChartType.Line, Strings.Line)
            types.Add(ChartType.Scatter, Strings.Scatter)
            types.Add(ChartType.LineSymbols, Strings.LineSymbols)
            types.Add(ChartType.Area, Strings.Area)
            types.Add(ChartType.Spline, Strings.Spline)
            types.Add(ChartType.SplineArea, Strings.SplineArea)
            types.Add(ChartType.SplineSymbols, Strings.SplineSymbols)
        Return types
    End Function

    Public Shared Function CreateQuartileCalculations() As List(Of String)
        Return [Enum].GetNames(GetType(QuartileCalculation)).ToList()
    End Function

    Public Shared Function CreateSchoolScoreData() As List(Of ClassScore)
        Dim result As New List(Of ClassScore)
        result.Add(New ClassScore() With {.ClassName = "English", .SchoolA = 46, .SchoolB = 53, .SchoolC = 66})
        result.Add(New ClassScore() With {.ClassName = "Physics", .SchoolA = 61, .SchoolB = 55, .SchoolC = 65})
        result.Add(New ClassScore() With {.ClassName = "English", .SchoolA = 58, .SchoolB = 56, .SchoolC = 67})
        result.Add(New ClassScore() With {.ClassName = "Math", .SchoolA = 58, .SchoolB = 51, .SchoolC = 64})
        result.Add(New ClassScore() With {.ClassName = "English", .SchoolA = 63, .SchoolB = 53, .SchoolC = 45})
        result.Add(New ClassScore() With {.ClassName = "English", .SchoolA = 63, .SchoolB = 50, .SchoolC = 65})
        result.Add(New ClassScore() With {.ClassName = "Math", .SchoolA = 60, .SchoolB = 45, .SchoolC = 67})
        result.Add(New ClassScore() With {.ClassName = "Math", .SchoolA = 62, .SchoolB = 53, .SchoolC = 66})
        result.Add(New ClassScore() With {.ClassName = "Physics", .SchoolA = 63, .SchoolB = 54, .SchoolC = 64})
        result.Add(New ClassScore() With {.ClassName = "English", .SchoolA = 63, .SchoolB = 52, .SchoolC = 67})
        result.Add(New ClassScore() With {.ClassName = "Physics", .SchoolA = 69, .SchoolB = 66, .SchoolC = 71})
        result.Add(New ClassScore() With {.ClassName = "Physics", .SchoolA = 48, .SchoolB = 67, .SchoolC = 50})
        result.Add(New ClassScore() With {.ClassName = "Physics", .SchoolA = 54, .SchoolB = 50, .SchoolC = 56})
        result.Add(New ClassScore() With {.ClassName = "Physics", .SchoolA = 60, .SchoolB = 56, .SchoolC = 64})
        result.Add(New ClassScore() With {.ClassName = "Math", .SchoolA = 71, .SchoolB = 65, .SchoolC = 50})
        result.Add(New ClassScore() With {.ClassName = "Math", .SchoolA = 48, .SchoolB = 70, .SchoolC = 72})
        result.Add(New ClassScore() With {.ClassName = "Math", .SchoolA = 53, .SchoolB = 40, .SchoolC = 80})
        result.Add(New ClassScore() With {.ClassName = "Math", .SchoolA = 60, .SchoolB = 56, .SchoolC = 67})
        result.Add(New ClassScore() With {.ClassName = "Math", .SchoolA = 61, .SchoolB = 56, .SchoolC = 45})
        result.Add(New ClassScore() With {.ClassName = "English", .SchoolA = 63, .SchoolB = 58, .SchoolC = 64})
        result.Add(New ClassScore() With {.ClassName = "Physics", .SchoolA = 59, .SchoolB = 54, .SchoolC = 65})
        Return result

    End Function

    Public Shared Function CreateSales() As Sale()
        Dim countries As String() = {"US", "Germany", "UK", "Japan", "Italy", "Greece", "China", "France", "Russia"}
        Dim count As Integer = countries.Length
        Dim result As Sale() = New Sale(count - 1) {}
        Dim rnd As Random = New Random()
        Dim i As Integer = 0
        While i < count
            result(i) = New Sale() With {
                .Country = countries(i),
                .Sales = rnd.[Next](60)
            }
            i += 1
        End While
        Return result
    End Function

    Public Shared Function CreateForPlotAreas() As PlotAreasSampleDataItem()
        Dim data As PlotAreasSampleDataItem() = New PlotAreasSampleDataItem(19) {}
        Dim i As Integer = 0
        While i < 20
            Dim ac As Double = i
            Dim ve As Double = ac * i
            Dim di As Double = 0.5 * ac * i * i
            data(i) = New PlotAreasSampleDataItem() With
                {
                    .Acceleration = ac,
                    .Velocity = ve,
                    .Distance = di,
                    .Time = i
                }
            i += 1
        End While

        Return data
    End Function

    Public Shared Function Sinus(x As Double) As Double
        Return Math.Sin(x)
    End Function

    Public Shared Function Test1(x As Double) As Double
        Return (Math.Pow(-x, 2 / 3) + Math.Sqrt(Math.Pow(x, 4 / 3) - 4 * Math.Pow(x, 2) + 4)) / 2
    End Function

    Shared Function Iterate(x As Double, y As Double, c As Double()) As DataPoint
        Dim x1 As Double = c(0) + c(1) * x + c(2) * x * x + c(3) * x * y + c(4) * y + c(5) * y * y
        Dim y1 As Double = c(6) + c(7) * x + c(8) * x * x + c(9) * x * y + c(10) * y + c(11) * y * y

        Return New DataPoint() With {
            .XVals = x1,
            .YVals = y1
        }
    End Function

    Shared Function StringToCoeff(s As String) As Double()
        Dim len As Integer = s.Length
        Dim c As Double() = New Double(len) {}
        Dim i As Integer = 0
        While i < len
            c(i) = -1.2 + 0.1 * (AscW(s(i)) - AscW("A"))
            i += 1
        End While

        Return c
    End Function
End Class

Public Class FruitDataItem
    Public Property Fruit() As String
    Public Property March() As Double
    Public Property April() As Double
    Public Property May() As Double
End Class

Public Class DataPoint
    Public Property XVals() As Double
    Public Property YVals() As Double
End Class

Public Class WaterfallItem
    Public Property Name() As String
    Public Property Value() As Double
End Class

Public Class ClassScore
    Public Property ClassName() As String
    Public Property SchoolA() As Double
    Public Property SchoolB() As Double
    Public Property SchoolC() As Double
End Class

Public Class Sale
    Public Property Country() As String
    Public Property Sales() As Integer
End Class

Public Class PlotAreasSampleDataItem
    Public Property Acceleration() As Double
    Public Property Velocity() As Double
    Public Property Distance() As Double
    Public Property Time() As Integer
End Class
