Imports System.ComponentModel
Imports System.Drawing
Imports System.Windows.Forms
Imports DevExpress.Accessibility
Imports DevExpress.XtraEditors
Imports DevExpress.XtraEditors.Drawing
Imports DevExpress.XtraEditors.Registrator
Imports DevExpress.XtraEditors.Repository
Imports DevExpress.XtraEditors.ViewInfo
Imports DevExpress.XtraEditors.Controls

<ToolboxItem(True)>
Public Class LookupControl2
    Inherits GridLookUpEdit

    Public Delegate Sub SelectedValuesChangedHandler(sender As Object, SelectedValues As List(Of String))
    Public Event SelectedValuesChanged As SelectedValuesChangedHandler

    Public Property AllowAddNewValues As Boolean
    Public Property PreventDuplicates As Boolean
    Public Property DataSource As DataTable

    Public Property MultiSelect As Boolean
        Get
            Return _Multiselect
        End Get
        Set(value As Boolean)
            SetDropdownButtonEnabled(value)
            _MultiSelect = value
        End Set
    End Property

    Public Property SelectedValues As List(Of String)
        Get
            Return _SelectedValues
        End Get
        Set(value As List(Of String))
            UpdateSelectedValues(value)
        End Set
    End Property

    Public Overloads Property [ReadOnly] As Boolean
        Get
            Return _ReadOnly
        End Get
        Set(value As Boolean)
            SetFormButtonEnabled(Not value)
            _ReadOnly = value
        End Set
    End Property

    Private ReadOnly _LookupFormButton As EditorButton

    Private Const TAG_DROPDOWN = "openDropdown"
    Private Const TAG_BUTTON_LOOKUP_FORM = "openLookupForm"
    Private Const TEXT_NO_RECORDS = "Keine Datensätze ausgewählt"
    Private Const TEXT_ONE_RECORD = "Ein Datensatz ausgewählt"
    Private Const TEXT_N_RECORDS = "{0} Datensätze ausgewählt"

    Private _SelectedValues As New List(Of String)
    Private _MultiSelect As Boolean

    Friend WithEvents GridView1 As DevExpress.XtraGrid.Views.Grid.GridView
    Friend WithEvents GridView2 As DevExpress.XtraGrid.Views.Grid.GridView
    Private _ReadOnly As Boolean = False

    Shared Sub New()
        RepositoryItemLookupControl2.RegisterLookupControl2()
    End Sub

    Public Sub New()
        MyClass.New(MultiSelect:=False)
    End Sub

    Public Sub New(MultiSelect As Boolean)
        _LookupFormButton = New EditorButton() With {
            .Kind = ButtonPredefines.Ellipsis,
            .Tag = TAG_BUTTON_LOOKUP_FORM
        }

        Properties.Buttons.Item(0).Tag = TAG_DROPDOWN
        Properties.Buttons.AddRange({_LookupFormButton})
        Properties.NullText = TEXT_NO_RECORDS

        AddHandler ButtonClick, AddressOf HandleButtonClick
        AddHandler EditValueChanging, AddressOf HandleEditValueChanging
        AddHandler QueryPopUp, AddressOf HandleQueryPopup
    End Sub

    Private Sub SetFormButtonEnabled(Enabled As Boolean)
        Dim oButton As EditorButton = Properties.Buttons.
            Where(Function(b) b.Tag = TAG_BUTTON_LOOKUP_FORM).
            FirstOrDefault()

        If oButton IsNot Nothing Then
            oButton.Enabled = Enabled
        End If
    End Sub

    Private Sub SetDropdownButtonEnabled(Enabled As Boolean)
        Dim oButton As EditorButton = Properties.Buttons.
            Where(Function(b) b.Tag = TAG_DROPDOWN).
            FirstOrDefault()

        If oButton IsNot Nothing Then
            oButton.Enabled = Enabled
        End If
    End Sub

    ''' <summary>
    ''' Prevents popup from opening when multiselect is false
    ''' </summary>
    Private Sub HandleQueryPopup(sender As Object, e As CancelEventArgs)
        If MultiSelect = False Then
            e.Cancel = True
        End If
    End Sub

    ''' <summary>
    ''' Prevents Editvalue changing when multiselect is true
    ''' </summary>
    Private Sub HandleEditValueChanging(sender As Object, e As ChangingEventArgs)
        If MultiSelect Then
            e.Cancel = True
        End If
    End Sub

    ''' <summary>
    ''' Handles opening frmLookup when ellipsis button is clicked
    ''' </summary>
    Private Sub HandleButtonClick(sender As Object, e As ButtonPressedEventArgs)
        Select Case e.Button.Tag
            Case TAG_BUTTON_LOOKUP_FORM
                Using oForm = GetLookupForm()
                    Dim oResult = oForm.ShowDialog()

                    If oResult = Windows.Forms.DialogResult.OK Then
                        Dim oValues = oForm.SelectedValues
                        UpdateSelectedValues(oValues)
                    End If
                End Using
        End Select
    End Sub

    Private Sub UpdateSelectedValues(Values As List(Of String))
        If Values Is Nothing Then
            Exit Sub
        End If

        Values.RemoveAll(Function(v) String.IsNullOrEmpty(v))

        If MultiSelect = True Then
            Properties.DataSource = Values

            Select Case Values.Count
                Case 0
                    Properties.NullText = TEXT_NO_RECORDS
                Case 1
                    Properties.NullText = TEXT_ONE_RECORD
                Case Else
                    Properties.NullText = String.Format(TEXT_N_RECORDS, Values.Count)
            End Select
        Else
            Properties.NullText = Values.FirstOrDefault()
            Text = Values.FirstOrDefault()
            EditValue = Nothing
        End If

        _SelectedValues = Values

        RaiseEvent SelectedValuesChanged(Me, Values)
    End Sub

    Private Function GetLookupForm() As frmLookupGrid
        Dim oForm As New frmLookupGrid() With {
            .MultiSelect = MultiSelect,
            .AddNewValues = AllowAddNewValues,
            .PreventDuplicates = PreventDuplicates,
            .DataSource = DataSource,
            .SelectedValues = SelectedValues,
            .StartPosition = FormStartPosition.Manual,
            .Location = PointToScreen(New Point(Width, 0))
        }

        Return oForm
    End Function

    <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)>
    Public Shadows ReadOnly Property Properties As RepositoryItemLookupControl2
        Get
            Return TryCast(MyBase.Properties, RepositoryItemLookupControl2)
        End Get
    End Property

    Public Overrides ReadOnly Property EditorTypeName As String
        Get
            Return RepositoryItemLookupControl2.CustomEditName
        End Get
    End Property
End Class

<UserRepositoryItem("RegisterLookupControl2")>
Public Class RepositoryItemLookupControl2
    Inherits RepositoryItemGridLookUpEdit

    Shared Sub New()
        RegisterLookupControl2()
    End Sub

    Public Const CustomEditName As String = "LookupControl2"

    Public Overrides ReadOnly Property EditorTypeName As String
        Get
            Return CustomEditName
        End Get
    End Property

    Public Shared Sub RegisterLookupControl2()
        Dim img As Image = Nothing
        EditorRegistrationInfo.Default.Editors.Add(New EditorClassInfo(CustomEditName, GetType(LookupControl2), GetType(RepositoryItemLookupControl2), GetType(GridLookUpEditBaseViewInfo), New ButtonEditPainter(), True, img, GetType(ButtonEditAccessible)))
    End Sub

    Public Overrides Sub Assign(item As RepositoryItem)
        BeginUpdate()
        Try
            MyBase.Assign(item)
            Dim source As RepositoryItemLookupControl2 = TryCast(item, RepositoryItemLookupControl2)
            If source Is Nothing Then
                Return
            End If
        Finally
            EndUpdate()
        End Try
    End Sub
End Class
