Option Strict On

Imports System.Xml.Serialization

Namespace Mbark.Sensors

    <XmlType("RuntimeSensorTaskAttemptCollection")> Public Class SensorTaskAttemptCollection
        Implements ICollection

        Friend Function CreateDefinition(ByVal parentTask As SensorTask) As SensorTaskAttemptCollectionDefinition

            mParentTask = parentTask

            Dim newDef As New SensorTaskAttemptCollectionDefinition
            ReDim newDef.AttemptDefinitions(mAttempts.Count - 1)

            For i As Integer = 0 To mAttempts.Count - 1
                newDef.AttemptDefinitions(i) = Item(i).CreateDefinition(parentTask)
            Next

            Return newDef
        End Function

        Private mAttempts As New ArrayList
        Private mParentTask As SensorTask

        Public Function IndexOf(ByVal attempt As SensorTaskAttempt) As Integer
            If mAttempts.IndexOf(attempt) = -1 Then
                For i As Integer = 0 To mAttempts.Count - 1
                    ' We must use Item(i) instead of mAttempts(i) to trigger the overload
                    If Item(i).Equals(attempt) Then Return i
                Next
            Else
                Return mAttempts.IndexOf(attempt)
            End If
            Return -1
        End Function

        Public ReadOnly Property AttemptsWithThumbnails() As Integer
            Get
                Dim count As Integer
                For i As Integer = 0 To mAttempts.Count - 1
                    If Not Item(i).ThumbnailImage Is Nothing Then count += 1
                Next
                Return count
            End Get
        End Property

        Public Sub Insert(ByVal index As Integer, ByVal attempt As SensorTaskAttempt)
            If attempt Is Nothing Then Throw New ArgumentNullException("attempt")
            If attempt.ParentTask Is Nothing Then Debugging.Break()
            attempt.WireParentTask(mParentTask)

            ' If the task was unstarted, it's suspended now
            If mParentTask.Status = SensorTaskStatus.Unstarted Then mParentTask.Status = SensorTaskStatus.Suspended
            mAttempts.Insert(index, attempt)
        End Sub

        Public Sub Add(ByVal attempt As SensorTaskAttempt)
            If attempt Is Nothing Then Throw New ArgumentNullException("attempt")
            Insert(mAttempts.Count, attempt)
        End Sub
        Default Public Property Item(ByVal index As Integer) As SensorTaskAttempt
            Get
                Return DirectCast(mAttempts(index), SensorTaskAttempt)
            End Get
            Set(ByVal value As SensorTaskAttempt)
                mAttempts(index) = value
            End Set
        End Property


        Public Sub Remove(ByVal attempt As SensorTaskAttempt)
            mAttempts.Remove(attempt)

            ' If the task was finished, it's now suspended
            If mAttempts.Count = 0 AndAlso mParentTask.Status = SensorTaskStatus.Done Then mParentTask.Status = SensorTaskStatus.Suspended
        End Sub

        Public Function Contains(ByVal attempt As SensorTaskAttempt) As Boolean
            Return mAttempts.IndexOf(attempt) <> -1
        End Function

        Public Sub New(ByVal parentTask As SensorTask)
            mParentTask = parentTask
        End Sub

#Region "ICollection Implementation"
        Public ReadOnly Property Count() As Integer Implements ICollection.count
            Get
                Return mAttempts.Count
            End Get
        End Property

        Public Sub CopyTo(ByVal array As System.Array, ByVal index As Integer) Implements System.Collections.ICollection.CopyTo
            mAttempts.CopyTo(array, index)
        End Sub

        Public Sub CopyTo(ByVal attempts As SensorTaskAttemptCollection, ByVal index As Integer)
            If attempts Is Nothing Then Throw New ArgumentNullException("attempts")
            mAttempts.CopyTo(attempts.mAttempts.ToArray, index)
        End Sub

        Public ReadOnly Property IsSynchronized() As Boolean Implements System.Collections.ICollection.IsSynchronized
            Get
                Return mAttempts.IsSynchronized
            End Get
        End Property

        Public ReadOnly Property SyncRoot() As Object Implements System.Collections.ICollection.SyncRoot
            Get
                Return mAttempts.SyncRoot
            End Get
        End Property

        Public Function GetEnumerator() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
            Return mAttempts.GetEnumerator
        End Function
#End Region
    End Class

    <XmlType("Attempts"), Serializable()> _
    Public Class SensorTaskAttemptCollectionDefinition
        Implements ICloneable

        Private mAttemptDefinitions() As SensorTaskAttemptDefinition
        <XmlElement("Attempt")> Property AttemptDefinitions() As SensorTaskAttemptDefinition()
            Get
                If mAttemptDefinitions Is Nothing Then
                    mAttemptDefinitions = New SensorTaskAttemptDefinition() {}
                End If
                Return mAttemptDefinitions
            End Get
            Set(ByVal value As SensorTaskAttemptDefinition())
                mAttemptDefinitions = value
            End Set
        End Property

        Public Function Clone() As Object Implements System.ICloneable.Clone
            Dim newDef As New SensorTaskAttemptCollectionDefinition
            ReDim newDef.AttemptDefinitions(AttemptDefinitions.Length - 1)
            For i As Integer = 0 To AttemptDefinitions.Length - 1
                newDef.AttemptDefinitions(i) = AttemptDefinitions(i).DeepCopy
            Next
            Return newDef
        End Function

        Public Function DeepCopy() As SensorTaskAttemptCollectionDefinition
            Return DirectCast(Clone(), SensorTaskAttemptCollectionDefinition)
        End Function

        Public Function CreateSensorTaskAttemptCollection(ByVal parentTask As SensorTask) As SensorTaskAttemptCollection
            Dim attempts As New SensorTaskAttemptCollection(parentTask)
            For i As Integer = 0 To AttemptDefinitions.Length - 1
                attempts.Add(AttemptDefinitions(i).CreateTaskAttempt(parentTask))
            Next
            Return attempts
        End Function

    End Class

End Namespace
