Imports System.ComponentModel
Imports System.Text
Imports System.Drawing.Design

Imports Stax.UI
Imports Stax.Win32

Namespace UI.Design
    <ProvideProperty("KeyData", GetType(ToolStripItem)), _
    ProvideProperty("TipTitle", GetType(ToolStripItem)), _
    ProvideProperty("TipText", GetType(ToolStripItem))> _
    Public Class ToolStripItemExtender
        Inherits Component
        Implements IExtenderProvider, ISupportInitialize

        Private Items As New Dictionary(Of ToolStripItem, Item)

        Public Function CanExtend(ByVal obj As Object) As Boolean Implements IExtenderProvider.CanExtend
            Return TypeOf obj Is ToolStripItem
        End Function

        <Category("ToolStripItemExtender"), DefaultValue(GetType(Keys), "None")> _
        Public Function GetKeyData(ByVal tsi As ToolStripItem) As Keys
            If Items.ContainsKey(tsi) Then
                Return Items(tsi).KeyData
            End If

            Return Keys.None
        End Function

        Public Sub SetKeyData(ByVal tsi As ToolStripItem, ByVal value As Keys)
            Dim item As Item

            If Items.ContainsKey(tsi) Then
                item = Items(tsi)
            Else
                item = New Item
                Items(tsi) = item
            End If

            item.KeyData = value
        End Sub

        <Category("ToolStripItemExtender"), DefaultValue("")> _
        Public Function GetTipTitle(ByVal tsi As ToolStripItem) As String
            If Items.ContainsKey(tsi) AndAlso _
                Not Items(tsi).TipTitle Is Nothing Then

                Return Items(tsi).TipTitle
            End If

            Return ""
        End Function

        Public Sub SetTipTitle(ByVal tsi As ToolStripItem, ByVal value As String)
            Dim item As Item

            If Items.ContainsKey(tsi) Then
                item = Items(tsi)
            Else
                item = New Item
                Items(tsi) = item
            End If

            item.TipTitle = value
        End Sub

        <Category("ToolStripItemExtender"), DefaultValue(""), _
        Editor(GetType(StringEditor), GetType(UITypeEditor))> _
        Public Function GetTipText(ByVal tsi As ToolStripItem) As String
            If Items.ContainsKey(tsi) AndAlso _
                Not Items(tsi).TipText Is Nothing Then

                Return Items(tsi).TipText
            End If

            Return ""
        End Function

        Public Sub SetTipText(ByVal tsi As ToolStripItem, ByVal value As String)
            Dim item As Item

            If Items.ContainsKey(tsi) Then
                item = Items(tsi)
            Else
                item = New Item
                Items(tsi) = item
            End If

            item.TipText = value
        End Sub

        Private Class Item
            Private KeyDataValue As Keys

            Public Property KeyData() As Keys
                Get
                    Return KeyDataValue
                End Get
                Set(ByVal Value As Keys)
                    KeyDataValue = Value
                End Set
            End Property

            Private TipTitleValue As String

            Public Property TipTitle() As String
                Get
                    Return TipTitleValue
                End Get
                Set(ByVal Value As String)
                    TipTitleValue = Value
                End Set
            End Property

            Private TipTextValue As String

            Public Property TipText() As String
                Get
                    Return TipTextValue
                End Get
                Set(ByVal Value As String)
                    TipTextValue = Value
                End Set
            End Property
        End Class

        Public Sub BeginInit() Implements ISupportInitialize.BeginInit
        End Sub

        Public Sub EndInit() Implements ISupportInitialize.EndInit
            If Not DesignMode AndAlso Not OwnerValue Is Nothing Then
                AddHandler OwnerValue.KeyDown, AddressOf KeyDown

                For Each i As ToolStripItem In Items.Keys
                    Dim item As Item = Items(i)

                    If TypeOf i Is ToolStripMenuItem Then
                        If item.KeyData <> Keys.None Then
                            Dim mi As ToolStripMenuItem = CType(i, ToolStripMenuItem)
                            mi.ShortcutKeyDisplayString = KeysHelp.GetKeyString(item.KeyData)
                        End If
                    ElseIf TypeOf i Is ToolStripButton Then
                        Dim tsb As ToolStripButton = CType(i, ToolStripButton)

                        If item.KeyData <> Keys.None Then
                            tsb.ToolTipText = item.TipText + " (" + KeysHelp.GetKeyString(item.KeyData) + ")"
                        Else
                            tsb.ToolTipText = item.TipText
                        End If
                    End If
                Next
            End If
        End Sub

        Private OwnerValue As Control

        Public Property Owner() As Control
            Get
                Return OwnerValue
            End Get
            Set(ByVal Value As Control)
                OwnerValue = Value
            End Set
        End Property

        Private Sub KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs)
            For Each i As ToolStripItem In Items.Keys
                Dim item As Item = Items(i)

                If item.KeyData = e.KeyData Then
                    i.PerformClick()
                End If
            Next
        End Sub

        Public Function GetTips() As StringPairList
            Dim list As New StringPairList

            For Each i As ToolStripItem In Items.Keys
                Dim item As Item = Items(i)

                If Not item.TipText Is Nothing AndAlso _
                    item.TipText <> "" Then

                    Dim sp As New StringPair
                    sp.Value = item.TipText

                    If item.TipTitle Is Nothing Then
                        sp.Name = i.Text

                        If sp.Name.EndsWith("...") Then
                            sp.Name = sp.Name.TrimEnd("."c)
                        End If
                    Else
                        sp.Name = item.TipTitle
                    End If

                    list.Add(sp)
                End If
            Next

            Return list
        End Function

        Public Function GetKeys() As StringPairList
            Dim list As New StringPairList

            For Each i As ToolStripItem In Items.Keys
                Dim item As Item = Items(i)

                If Not item.KeyData = Keys.None Then
                    Dim sp As New StringPair
                    sp.Value = KeysHelp.GetKeyString(item.KeyData)

                    If item.TipTitle Is Nothing Then
                        sp.Name = i.Text

                        If sp.Name.EndsWith("...") Then
                            sp.Name = sp.Name.TrimEnd("."c)
                        End If
                    Else
                        sp.Name = item.TipTitle
                    End If

                    list.Add(sp)
                End If
            Next

            Return list
        End Function
    End Class
End Namespace