Namespace UI
    Public Class Msg
        Public ButtonList As New List(Of Button)
        Public ButtonResults As New Dictionary(Of Button, DialogResult)

        Private PressedButtonValue As Button

        Public Property PressedButton() As Button
            Get
                Return PressedButtonValue
            End Get
            Set(ByVal Value As Button)
                PressedButtonValue = Value
            End Set
        End Property

        Public Function AddButton(ByVal text As String, ByVal result As DialogResult) As Button
            If result = DialogResult.None Then
                Throw New ArgumentException("The Form class seem to not return DialogResult.None nor does it close.")
            End If

            Dim ret As New Button
            ret.Text = text
            ButtonList.Add(ret)
            ButtonResults(ret) = result
            Return ret
        End Function

        Public Function Show() As DialogResult
            If Not CheckedList Is Nothing AndAlso _
                CheckedList.Contains(StringHelp.GetMD5Hash(Text)) Then

                Return DialogResult.None
            End If

            Dim f As New MessageBoxForm(Me)

            Dim ret As DialogResult = f.ShowDialog()
            Application.DoEvents()
            f.Dispose()

            PressedButton = f.PressedButton

            If CheckedList IsNot Nothing AndAlso Checked Then
                CheckedList.Add(StringHelp.GetMD5Hash(Text))
            End If

            Return ret
        End Function

        Private FontValue As Font

        Public Property Font() As Font
            Get
                If FontValue Is Nothing Then
                    FontValue = Control.DefaultFont
                End If

                Return FontValue
            End Get
            Set(ByVal value As Font)
                FontValue = value
            End Set
        End Property

        Private TextColorValue As Color = Color.Black

        Public Property TextColor() As Color
            Get
                Return TextColorValue
            End Get
            Set(ByVal Value As Color)
                TextColorValue = Value
            End Set
        End Property

        Private TextValue As String

        Public Property Text() As String
            Get
                Return TextValue
            End Get
            Set(ByVal value As String)
                TextValue = value
            End Set
        End Property

        Private TitleValue As String

        Public Property Title() As String
            Get
                Return TitleValue
            End Get
            Set(ByVal value As String)
                TitleValue = value
            End Set
        End Property

        Private ImageValue As Image

        Public Property Image() As Image
            Get
                Return ImageValue
            End Get
            Set(ByVal value As Image)
                ImageValue = value
            End Set
        End Property

        Private CheckBoxTextValue As String

        Public Property CheckBoxText() As String
            Get
                If CheckBoxTextValue Is Nothing Then
                    CheckBoxTextValue = "Don't show this again"
                End If

                Return CheckBoxTextValue
            End Get
            Set(ByVal Value As String)
                CheckBoxTextValue = Value
            End Set
        End Property

        Private ShowCheckBoxValue As Boolean

        Public Property ShowCheckBox() As Boolean
            Get
                Return ShowCheckBoxValue
            End Get
            Set(ByVal value As Boolean)
                ShowCheckBoxValue = value
            End Set
        End Property

        Private CheckedValue As Boolean

        Public Property Checked() As Boolean
            Get
                Return CheckedValue
            End Get
            Set(ByVal value As Boolean)
                CheckedValue = value
            End Set
        End Property

        Private CheckedListValue As List(Of String)

        Public Property CheckedList() As List(Of String)
            Get
                Return CheckedListValue
            End Get
            Set(ByVal value As List(Of String))
                If Not value Is Nothing Then
                    ShowCheckBox = True
                End If

                CheckedListValue = value
            End Set
        End Property

        Public WriteOnly Property Buttons() As MessageBoxButtons
            Set(ByVal Value As MessageBoxButtons)
                Select Case Value
                    Case MessageBoxButtons.OK
                        AddButton("OK", DialogResult.OK)
                    Case MessageBoxButtons.OKCancel
                        AddButton("OK", DialogResult.OK)
                        AddButton("Cancel", DialogResult.Cancel)
                    Case MessageBoxButtons.YesNo
                        AddButton("Yes", DialogResult.Yes)
                        AddButton("No", DialogResult.No)
                    Case MessageBoxButtons.YesNoCancel
                        AddButton("Yes", DialogResult.Yes)
                        AddButton("No", DialogResult.No)
                        AddButton("Cancel", DialogResult.Cancel)
                    Case MessageBoxButtons.RetryCancel
                        AddButton("Retry", DialogResult.Retry)
                        AddButton("Cancel", DialogResult.Cancel)
                    Case Else
                        Throw New NotImplementedException()
                End Select
            End Set
        End Property

        Public WriteOnly Property Icon() As MsgIcon
            Set(ByVal Value As MsgIcon)
                Select Case Value
                    Case MsgIcon.Error
                        Image = SystemIcons.Error.ToBitmap
                    Case MsgIcon.Info
                        Image = My.Resources.Info32
                    Case MsgIcon.Question
                        Image = My.Resources.Help32
                    Case MsgIcon.Warning
                        Image = My.Resources.Warning32
                    Case Else
                        Throw New NotImplementedException("Only basic icons are implemented.")
                End Select
            End Set
        End Property

        Public Shared Function Show( _
            ByVal text As String, _
            ByVal icon As MsgIcon) As DialogResult

            Return Show(text, icon, MessageBoxButtons.OK)
        End Function

        Public Shared Function Show( _
            ByVal text As String, _
            ByVal icon As MsgIcon, _
            ByVal buttons As MessageBoxButtons) As DialogResult

            Return Show(text, Application.ProductName, icon, buttons, Nothing)
        End Function

        Public Shared Function Show( _
            ByVal text As String, _
            ByVal checkedList As List(Of String)) As DialogResult

            Return Show(text, Application.ProductName, _
                MsgIcon.Info, MessageBoxButtons.OK, checkedList)
        End Function

        Public Shared Function Show( _
            ByVal text As String, _
            ByVal title As String, _
            ByVal checkedList As List(Of String)) As DialogResult

            Return Show(text, title, MsgIcon.Info, _
                MessageBoxButtons.OK, checkedList)
        End Function

        Public Shared Function Show( _
            ByVal text As String, _
            ByVal icon As MsgIcon, _
            ByVal buttons As MessageBoxButtons, _
            ByVal checkedList As List(Of String)) As DialogResult

            Return Show(text, Application.ProductName, MsgIcon.Info, _
                MessageBoxButtons.OK, checkedList)
        End Function

        Public Shared Function Show( _
            ByVal text As String, _
            ByVal title As String, _
            ByVal icon As MsgIcon) As DialogResult

            Return Show(text, title, icon, MessageBoxButtons.OK, Nothing)
        End Function

        Public Shared Function Show( _
            ByVal text As String, _
            ByVal title As String, _
            ByVal icon As MsgIcon, _
            ByVal buttons As MessageBoxButtons) As DialogResult

            Return Show(text, title, icon, buttons, Nothing)
        End Function

        Public Shared Function Show( _
            ByVal text As String, _
            ByVal title As String, _
            ByVal icon As MsgIcon, _
            ByVal buttons As MessageBoxButtons, _
            ByVal checkedList As List(Of String)) As DialogResult

            If checkedList IsNot Nothing AndAlso _
                checkedList.Contains( _
                StringHelp.GetMD5Hash(text)) Then

                Return DialogResult.None
            End If

            Dim wrapper As New Msg

            wrapper.Text = text
            wrapper.Title = title
            wrapper.Icon = icon
            wrapper.Buttons = buttons
            wrapper.CheckedList = checkedList

            Return wrapper.Show
        End Function
    End Class

    Public Enum MsgIcon
        [Error]
        Warning
        Question
        Info
    End Enum
End Namespace