' D. de Haas
' Amsterdam, Netherlands
' 29 October 2002
' ddhadam@yahoo.com

Option Explicit On 
Option Strict On

Imports System
Imports System.Collections

Public Class HighScore
    Implements IEnumerable
    ' Keeping track of the scores

    Private Scores As ArrayList
    Private HighScoreFile As String

    ' ScoreItem for HighScore list
    <Serializable()> Public Structure ScoreItem
        Implements IComparable

        Public Name As String
        Public Level As Integer
        Public Lines As Integer
        Public Score As Integer

        Public Overrides Function ToString() As String
            ' Returns ScoreItem as a string

            Dim sb As New Text.StringBuilder()

            sb.Append(Me.Name)
            sb.Append(" - Score: ")
            sb.Append(Me.Score.ToString)
            sb.Append(" - Lines: ")
            sb.Append(Me.Lines.ToString)
            sb.Append(" - Level: ")
            sb.Append(Me.Level.ToString)

            Return sb.ToString
        End Function

        Public Function CompareTo(ByVal obj As Object) As Integer Implements System.IComparable.CompareTo
            ' Make ScoreItem to Sort descending

            ' Me equals Obj
            If Me.Score = CType(obj, ScoreItem).Score AndAlso Me.Lines = CType(obj, ScoreItem).Lines AndAlso Me.Level = CType(obj, ScoreItem).Level Then Return 0

            ' Me less than Obj
            If Me.Score < CType(obj, ScoreItem).Score Then Return 1
            If Me.Score = CType(obj, ScoreItem).Score AndAlso Me.Lines < CType(obj, ScoreItem).Lines Then Return 1
            If Me.Score = CType(obj, ScoreItem).Score AndAlso Me.Lines = CType(obj, ScoreItem).Lines AndAlso Me.Level < CType(obj, ScoreItem).Level Then Return 1

            ' Me greater than Obj
            If Me.Score > CType(obj, ScoreItem).Score Then Return -1
            If Me.Score = CType(obj, ScoreItem).Score AndAlso Me.Lines > CType(obj, ScoreItem).Lines Then Return -1
            If Me.Score = CType(obj, ScoreItem).Score AndAlso Me.Lines = CType(obj, ScoreItem).Lines AndAlso Me.Level > CType(obj, ScoreItem).Level Then Return -1
        End Function
    End Structure

    '==== Events

    '==== Constructors

    Public Sub New(ByVal file As String)
        ' Create a new HighScore list

        Scores = New ArrayList()

        HighScoreFile = file

        Me.Load()
    End Sub

    Public Function GetEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
        ' Makes it possible to use a For Each on the HighScore object

        Return Scores.GetEnumerator
    End Function

    '==== Private Methods/Functions

    Private Sub Load()
        ' Load list from disk

        If IO.File.Exists(HighScoreFile) Then
            ' File exists, lets open it

            Dim fs As New IO.FileStream(HighScoreFile, IO.FileMode.Open)
            Dim bf As New Runtime.Serialization.Formatters.Binary.BinaryFormatter()

            Scores = CType(bf.Deserialize(fs), ArrayList)

            fs.Close()
        End If
    End Sub

    '==== Public Functions

    Public Overloads Function Add(ByVal name As String, ByVal score As Integer, ByVal lines As Integer, ByVal level As Integer) As Integer
        ' Adds a new score to the list

        Dim sc As ScoreItem

        sc.Name = name
        sc.Score = score
        sc.Lines = lines
        sc.Level = level

        ' Use overload version of Add
        Return Me.Add(sc)
    End Function

    Public Overloads Function Add(ByVal score As ScoreItem) As Integer
        ' Adds a new score to the list

        Scores.Add(score)

        ' Sort list after inserting a new score
        Scores.Sort()

        Return Scores.IndexOf(score)
    End Function

    '==== Public Methodes

    Public Sub Save()
        ' Save list to disk

        Dim fs As New IO.FileStream(HighScoreFile, IO.FileMode.Create)
        Dim bf As New Runtime.Serialization.Formatters.Binary.BinaryFormatter()

        bf.Serialize(fs, Scores)

        fs.Close()
    End Sub

End Class
