' *
' * The project site is at: http://sourceforge.jp/projects/fishbornas/
' *
' * First author tiritomato 2012.
' *
' * Distributed under the FishbornArchiveShelf License (See
' *  file "Licenses/License.txt" contained in a project, or the following link.
' *  http://sourceforge.jp/projects/fishbornas/scm/svn/blobs/head/trunk/Licenses/License.txt)
' *
' * 2012.06.07 Initial Revision (tiritomato)
' *

Partial Public Class Logic

    ''' <summary>
    ''' 
    ''' </summary>
    ''' <typeparam name="TArgs"></typeparam>
    ''' <remarks></remarks>
    Public Class UniqueEvents(Of TArgs As EventArgs)

        Public Sub Clear()
            SyncLock Payload
                Payload.Clear()
            End SyncLock
        End Sub

        Public Function Contains(ByVal d As EventHandler(Of TArgs)) As Boolean
            SyncLock Payload
                Contains = Contains(GetInvocationList(d))
            End SyncLock
        End Function

        Public Function Add(ByVal d As EventHandler(Of TArgs)) As Boolean
            Add = False
            Dim list As System.Collections.Generic.List(Of EventHandler(Of TArgs)) = GetInvocationList(d)
            SyncLock Payload
                If 0 < list.Count And Contains(list) = False Then
                    Payload.AddRange(list)
                    Add = True
                End If
            End SyncLock
        End Function

        Public Sub Remove(ByVal d As EventHandler(Of TArgs))
            Dim list As System.Collections.Generic.List(Of EventHandler(Of TArgs)) = GetInvocationList(d)
            SyncLock Payload
                For Each item As EventHandler(Of TArgs) In list
                    If Payload.Contains(item) Then Payload.Remove(item)
                Next
            End SyncLock
        End Sub

        Public Sub Invoke(ByVal sender As Object, ByVal e As EventArgs)
            Dim localcopy() As EventHandler(Of TArgs) = Nothing
            SyncLock Payload
                If 0 < Payload.Count Then
                    ReDim localcopy(Payload.Count - 1)
                    Payload.CopyTo(localcopy, 0)
                End If
            End SyncLock
            If localcopy IsNot Nothing Then
                For Each d As EventHandler(Of TArgs) In localcopy
                    d(sender, e)
                Next
            End If
        End Sub

        Public Sub Invoke(ByVal sender As Object, ByVal e As TArgs)
            Invoke(sender, CType(e, EventArgs))
        End Sub

        ' private implements /////////////////////////////////////////////////////////////////////////////////////////////////////////////

        Private Payload As New System.Collections.Generic.List(Of EventHandler(Of TArgs))

        Private Function Contains(ByVal list As System.Collections.Generic.IEnumerable(Of EventHandler(Of TArgs))) As Boolean
            Contains = False
            If list Is Nothing Then Exit Function
            For Each item As EventHandler(Of TArgs) In list
                If Payload.Contains(item) Then
                    Contains = True
                    Exit For
                End If
            Next
        End Function

        Private Shared Function GetInvocationList(ByVal d As EventHandler(Of TArgs)) As System.Collections.Generic.List(Of EventHandler(Of TArgs))

            Dim ret As New System.Collections.Generic.List(Of EventHandler(Of TArgs))
            GetInvocationList = ret
            If d Is Nothing Then Exit Function

            Dim list As System.Delegate() = d.GetInvocationList
            For Each item As System.Delegate In list
                Dim try_result As EventHandler(Of TArgs) = TryCast(item, EventHandler(Of TArgs))
                If try_result IsNot Nothing AndAlso ret.Contains(try_result) = False Then ret.Add(try_result)
            Next

        End Function

    End Class

End Class

