Namespace ControlLoader

    Public Class _BaseControl

        'Public Shared Function ReplaceSqlCommandPlaceholders(sqlCommand As String, recordId As Integer, parentRecordId As Integer, entity_ID As Integer)
        '    sqlCommand = sqlCommand.Replace("@RECORD_ID", recordId)
        '    sqlCommand = sqlCommand.Replace("@RECORDID", recordId)
        '    Dim sql As String = "SELECT FORM_ID FROM TBPMO_RECORD WHERE FORM_ID = "
        '    ss()
        '    sqlCommand = sqlCommand.Replace("@ENTITY_ID", recordId)
        '    sqlCommand = sqlCommand.Replace("@PARENTRECORD_ID", parentRecordId)
        '    sqlCommand = sqlCommand.Replace("@PARENTRECORDID", parentRecordId)

        '    Return sqlCommand
        'End Function

        Public Shared Function LoadAutoValue(control As System.Windows.Forms.Control, RecordId As Integer, ParentRecordId As Integer, entity_ID As Integer)
            Try
                Dim AutoValue As String = String.Empty
                Dim ControlId As Integer = DirectCast(control.Tag, ClassControlMetadata).Id
                Dim CONNID = MYDB_ECM.GetScalarValue(String.Format("SELECT CONNECTION_ID_1 FROM TBPMO_CONTROL WHERE GUID = {0}", ControlId))
                Dim SQL As String = MYDB_ECM.GetScalarValue(String.Format("SELECT SQL_COMMAND_1 FROM TBPMO_CONTROL WHERE GUID = {0}", ControlId))
                SQL = ClassControlValues.ReplaceSqlCommandPlaceholders(SQL, RecordId, ParentRecordId, entity_ID)

                If SQL = "" Or IsDBNull(SQL) Then
                    Return Nothing
                End If

                'If Not IsNothing(CONNID) Then
                '    AutoValue = ClassDatabase.Execute_ScalarWithConnection(CONNID, SQL)
                'Else
                AutoValue = MYDB_ECM.GetScalarValue(SQL)
                ' End If
                ' AutoValue = MYDB_ECM.GetScalarValue(SQL)

                If String.IsNullOrEmpty(AutoValue) Or IsDBNull(AutoValue) Then
                    Return Nothing
                End If

                Return AutoValue
            Catch ex As Exception
                LOGGER.Warn("Unexpected Error in LoadAutoValue: " & ex.Message)
                Return Nothing
            End Try


        End Function

    End Class

    Public Class _ListControl : Inherits _BaseControl

        Public Shared Function GetDynamicValue(controlId As Integer, formId As Integer, connID As Object, sqlCommand As String) As DynamicValue
            Dim returnValue As DynamicValue

            returnValue.StaticList = CheckForStaticList(controlId)
            returnValue.DataTable = GetSqlList(controlId, formId, connID, sqlCommand)

            Return returnValue
        End Function

        Private Shared Function CheckForStaticList(controlId As Integer) As List(Of String)
            Try
                ' Der alte SQL Befehl hat nicht wirklich nach der StaticList geschaut o_O
                ' Dim SQL As String = String.Format("SELECT VALUE FROM VWPMO_VALUES WHERE CONTROL_ID = {0} AND RECORD_ID = {1}", controlId, recordId)
                Dim SQL As String = String.Format("SELECT STATIC_LIST FROM TBPMO_CONTROL WHERE GUID = {0}", controlId)
                Dim staticList As String = MYDB_ECM.GetScalarValue(SQL)

                If IsNothing(staticList) Or String.IsNullOrWhiteSpace(staticList) Then
                    Return Nothing
                Else
                    Return New List(Of String)(staticList.Split(";").ToArray())
                End If
            Catch ex As Exception
                MsgBox("Error in CheckForStaticList: " & vbNewLine & ex.Message)
                Return Nothing
            End Try
        End Function

        Public Shared Function GetSqlList(controlId As Integer, formId As Integer, connection_Id As Object, sqlCommand As String) As DataTable
            Try
                If sqlCommand Is Nothing Or sqlCommand = String.Empty Then
                    Return Nothing
                End If

                Dim cached As DataTable = ClassControlValueCache.LoadFromCache(sqlCommand)
                Dim final As DataTable

                If cached Is Nothing Then
                    'If Not IsDBNull(connection_Id) Then
                    '    final = ClassDatabase.MSSQL_ReturnDTWithConnection(connection_Id, sqlCommand)
                    'Else
                    final = MYDB_ECM.GetDatatable(sqlCommand)
                    'End If
                    ClassControlValueCache.SaveToCache(sqlCommand, final)
                    Console.WriteLine("CACHE MISS")
                Else
                    final = cached
                    Console.WriteLine("CACHE HIT")
                End If

                Return final
            Catch ex As Exception
                MsgBox("Error in GetSqlList: " & vbNewLine & ex.Message)
                Return Nothing
            End Try
        End Function

        Overloads Shared Sub SetDataSource(control As DevExpress.XtraGrid.GridControl, dt As DataTable)
            Try
                Dim columnCount As Integer = dt.Columns.Count
                Dim rowCount As Integer = dt.Rows.Count

                ' Zuerst die Datasource leeren und neu setzen
                control.DataSource = Nothing
                control.DataSource = dt

                ' Wir müssen PopulateColumns und RefreshData nach dem Setzen der Datasource aufrufen
                ' ansonsten wird das Grid leer bleiben und die neuen Daten nicht anzeigen
                control.MainView.PopulateColumns()
                control.MainView.RefreshData()

                'Jetzt noch den Columnname ändern
                Dim gridview = DirectCast(control.MainView, DevExpress.XtraGrid.Views.Grid.GridView)

                Dim caption As String = MYDB_ECM.GetScalarValue(String.Format("SELECT COL_NAME FROM TBPMO_CONTROL WHERE GUID = {0}", DirectCast(control.Tag, ClassControlMetadata).Id))
                gridview.Columns(0).Caption = caption
            Catch ex As Exception
                MsgBox("Error in SetDataSource - GridControl: " & ex.Message, MsgBoxStyle.Critical)
            End Try
        End Sub

        Overloads Shared Sub SetDataSource(control As CustomComboBox, dt As DataTable)
            Dim sw As New SW("SetDataSource CustomComboBox")
            Dim columnCount As Integer = dt.Columns.Count

            control.BeginUpdate()
            PerfomanceHelper.SuspendDraw(control)

            ' Damit beim Setzen von DisplayMember und ValueMember kein Fehler auftritt, 
            ' muss die Datasource zunächst geleert werden und der selected index auf -1 gesetzt werden.
            control.DataSource = Nothing
            control.SelectedIndex = -1

            ' Es ist wichtig, dass DisplayMember und ValueMember VOR der DataSource festgelegt werden,
            ' Dadurch ist das Laden der Datasource um einiges SCHNELLER
            If columnCount = 1 Then
                control.DisplayMember = dt.Columns(0).ColumnName
                control.ValueMember = dt.Columns(0).ColumnName
            ElseIf columnCount = 2 Then
                control.DisplayMember = dt.Columns(1).ColumnName
                control.ValueMember = dt.Columns(0).ColumnName
            End If

            ' Als letztes setzen wir die DataSource
            control.DataSource = dt

            PerfomanceHelper.ResumeDraw(control)
            control.EndUpdate()

            sw.Done()
        End Sub

        Overloads Shared Sub SetDataSource(control As DevExpress.XtraEditors.CheckedListBoxControl, dt As DataTable)
            Dim columnCount As Integer = dt.Columns.Count

            ' Damit beim Setzen von DisplayMember und ValueMember kein Fehler auftritt, 
            ' muss die Datasource zunächst geleert werden und der selected index auf -1 gesetzt werden.
            control.DataSource = Nothing
            control.SelectedIndex = -1

            ' Es ist wichtig, dass DisplayMember und ValueMember VOR der DataSource festgelegt werden,
            ' Dadurch ist das Laden der Datasource um einiges SCHNELLER
            If columnCount = 1 Then
                control.DisplayMember = dt.Columns(0).ColumnName
                control.ValueMember = dt.Columns(0).ColumnName
            ElseIf columnCount = 2 Then
                control.DisplayMember = dt.Columns(1).ColumnName
                control.ValueMember = dt.Columns(0).ColumnName
            End If

            ' Als letztes setzen wir die DataSource
            control.DataSource = dt
        End Sub

        Overloads Shared Sub SetDataSource(control As DevExpress.XtraEditors.ListBoxControl, dt As DataTable)
            Dim columnCount As Integer = dt.Columns.Count

            ' Damit beim Setzen von DisplayMember und ValueMember kein Fehler auftritt, 
            ' muss die Datasource zunächst geleert werden und der selected index auf -1 gesetzt werden.
            control.DataSource = Nothing
            control.SelectedIndex = -1

            ' Es ist wichtig, dass DisplayMember und ValueMember VOR der DataSource festgelegt werden,
            ' Dadurch ist das Laden der Datasource um einiges SCHNELLER
            If columnCount = 1 Then
                control.DisplayMember = dt.Columns(0).ColumnName
                control.ValueMember = dt.Columns(0).ColumnName
            ElseIf columnCount = 2 Then
                control.DisplayMember = dt.Columns(1).ColumnName
                control.ValueMember = dt.Columns(0).ColumnName
            End If

            ' Als letztes setzen wir die DataSource
            control.DataSource = dt
        End Sub

        Overloads Shared Sub SetDataSource(control As System.Windows.Forms.DataGridView, dt As DataTable)
            control.DataSource = dt
        End Sub

    End Class

    Public Structure DynamicValue
        Public StaticList As List(Of String)
        Public DataTable As DataTable
    End Structure

    Public Class Label : Inherits _BaseControl

        Public Shared Sub LoadValue(control As System.Windows.Forms.Label, recordId As Integer, parentRecordId As Integer, value As String, entity_ID As Integer, Optional VARIABLE_VALUE As Boolean = False)
            Dim Sql
            Dim ControlId As Integer
            Try
                ControlId = DirectCast(control.Tag, ClassControlMetadata).Id
                Dim autoValue

                Dim drarray() As DataRow = CURRENT_SQL_AUTO_VALUES_DT.Select("GUID = " & ControlId)
                If drarray.Length > 0 Then
                    Dim ID
                    Try
                        ID = drarray(0)("CONNECTION_ID_1").ToString
                    Catch ex As Exception
                        ID = drarray(0)("CONNECTION_ID").ToString
                    End Try

                    'If Not IsNothing(ID) Then
                    '    Sql = drarray(0)("SQL_COMMAND_1").ToString
                    '    Sql = ClassControlValues.ReplaceSqlCommandPlaceholders(Sql, recordId, parentRecordId, entity_ID)
                    '    autoValue = ClassDatabase.Execute_ScalarWithConnection(ID, Sql)
                    'Else
                    autoValue = MYDB_ECM.GetScalarValue(Sql)
                    'End If
                    If IsNothing(autoValue) Then
                        If VARIABLE_VALUE = True Then
                            control.Text = value
                        Else
                            Sql = String.Format("SELECT GUID FROM TBPMO_CONTROL_SCREEN WHERE CONTROL_ID = {0} AND SCREEN_ID = {1}", ControlId, CURRENT_SCREEN_ID)
                            Dim ctrl_screen_id = MYDB_ECM.GetScalarValue(Sql)
                            If ctrl_screen_id > 0 Then
                                Sql = String.Format("SELECT CAPTION FROM TBPMO_CONTROL_LANGUAGE WHERE CONTROL_SCREEN_ID = {0} AND LANGUAGE_TYPE = '{1}'", ctrl_screen_id, USER_LANGUAGE)
                                Dim labelText As String = MYDB_ECM.GetScalarValue(SQL)
                                control.Text = labelText
                            End If
                        End If
                    Else
                        If IsDBNull(autoValue) Then
                            control.Text = "ATTENTION: result of select was dbnull"
                        Else
                            control.Text = autoValue
                        End If

                    End If
                End If
            Catch ex As Exception
                MsgBox("Unexpected Error in LoadValueMain:" & vbNewLine & ex.Message, MsgBoxStyle.Critical)
                LOGGER.Warn("Unexpected Error in LoadValueMain: " & ex.Message)
                LOGGER.Warn(String.Format("ControlID: {0}" & vbNewLine & "recordid: {1}" & vbNewLine & "parentRecordId: {2}" & vbNewLine & "value: {3}" & vbNewLine & "entity_ID: {4}" & vbNewLine & "VARIABLE_VALUE: {5}", ControlId, recordId, parentRecordId, value, entity_ID, VARIABLE_VALUE))
            End Try

        End Sub

    End Class

    Public Class Checkbox : Inherits _BaseControl

        Public Shared Sub LoadValue(control As System.Windows.Forms.CheckBox, value As String)
            Try
                Dim result As Boolean = False
                Boolean.TryParse(value, result)
                control.Checked = result
            Catch ex As Exception
                MsgBox("Unexpected Error in LoadValue1:" & vbNewLine & ex.Message)
                LOGGER.Warn("Unexpected Error in LoadValue1: " & ex.Message)
            End Try

        End Sub

    End Class

    Public Class RadioButton : Inherits _BaseControl

        Public Shared Sub LoadValue(control As System.Windows.Forms.RadioButton, value As String)
            Try
                Dim result As Boolean = False
                Boolean.TryParse(value, result)
                control.Checked = result
            Catch ex As Exception
                MsgBox("Unexpected Error in LoadValue2:" & vbNewLine & ex.Message)
                LOGGER.Warn("Unexpected Error in LoadValue2: " & ex.Message)
            End Try

        End Sub

    End Class

    Public Class TextBox : Inherits _BaseControl

        Public Shared Sub LoadValue(control As System.Windows.Forms.TextBox, recordId As Integer, parentRecordId As Integer, value As String, entity_ID As Integer, Optional VARIABLE_VALUE As Boolean = False)
            Try
                Dim ControlMeta As ClassControlMetadata = DirectCast(control.Tag, ClassControlMetadata)
                Dim ControlId As Integer = ControlMeta.Id
                Dim ControlFormat As String = ControlMeta.Format

                If CURRENT_RECORD_ENABLED = False Then
                    If ControlFormat = "Currency" Then
                        control.Text = ClassHelper.Format_Currency(value, USER_LANGUAGE)
                    Else
                        control.Text = value
                    End If
                Else
                    If VARIABLE_VALUE = True Then
                        If ControlFormat = "Currency" Then
                            control.Text = ClassHelper.Format_Currency(value, USER_LANGUAGE)
                        Else
                            control.Text = value
                        End If
                    Else
                        Dim drarray() As DataRow = CURRENT_SQL_AUTO_VALUES_DT.Select("GUID = " & ControlId)
                        If drarray.Length > 0 Then
                            Dim autoValue
                            Dim ID
                            Try
                                ID = drarray(0)("CONNECTION_ID_1").ToString
                            Catch ex As Exception
                                ID = drarray(0)("CONNECTION_ID").ToString
                            End Try


                            Dim Sql = drarray(0)("SQL_COMMAND").ToString
                            'If Not IsNothing(ID) Then
                            '    autoValue = ClassDatabase.Execute_ScalarWithConnection(ID, Sql)
                            'Else
                            autoValue = MYDB_ECM.GetScalarValue(Sql)
                            'End If
                            ' AutoValue = MYDB_ECM.GetScalarValue(SQL)

                            If String.IsNullOrEmpty(autoValue) Or IsDBNull(autoValue) Then
                                control.Text = value
                            Else
                                control.Text = autoValue
                            End If

                        End If
                        'If USER_WAN = True Then 'WENN in einer WAN-Umgebung betrieben

                        'Else 'in LAN-Umgebung
                        '    Dim autoValue = LoadAutoValue(control, recordId, parentRecordId, entity_ID)
                        '    If IsNothing(autoValue) Then
                        '        control.Text = value
                        '    Else
                        '        control.Text = autoValue
                        '    End If
                        'End If

                    End If
                End If

            Catch ex As Exception
                MsgBox("Unexpected Error in LoadValue3:" & vbNewLine & ex.Message)
                LOGGER.Warn("Unexpected Error in LoadValue3: " & ex.Message)
            End Try

        End Sub

    End Class

    Public Class DateTimePicker : Inherits _BaseControl

        Public Shared Sub LoadValue(control As DevExpress.XtraEditors.DateEdit, value As String)
            If String.IsNullOrWhiteSpace(value) Or value = "00:00:00" Then
                control.DateTime = DateTime.MinValue
            Else
                If Not DateTime.TryParse(value, control.DateTime) Then
                    control.DateTime = DateTime.MinValue
                End If
            End If
        End Sub

    End Class

    Public Class Combobox : Inherits _ListControl

        Public Shared Sub LoadValue(control As CustomComboBox, recordId As Integer, parentRecordId As Integer, value As String)
            control.Text = value
        End Sub

        Public Shared Sub LoadList(control As CustomComboBox, formId As Integer, connID As Object, SQLCommand As String)
            Try
                Dim sw As New SW("LoadList CustomComboBox")
                Dim sw1 As New SW("GetDynamicValue CustomComboBox")
                Dim dynamic As DynamicValue = GetDynamicValue(DirectCast(control.Tag, ClassControlMetadata).Id, formId, connID, SQLCommand)
                sw1.Done()

                If dynamic.StaticList IsNot Nothing Then
                    control.DataSource = dynamic.StaticList
                End If

                If dynamic.DataTable IsNot Nothing AndAlso dynamic.DataTable.Rows.Count > 0 Then
                    SetDataSource(control, dynamic.DataTable)
                    CalculateDropdownWidth(control, dynamic.DataTable)
                End If
                sw.Done()
            Catch ex As Exception
                MsgBox("Error in Combobox.LoadList:" & vbNewLine & ex.Message)
            End Try
        End Sub

        Private Shared Sub CalculateDropdownWidth(control As CustomComboBox, dt As DataTable)
            Try
                Const WIDEST_WIDTH As Integer = 300
                Dim FinalWidth As Integer = WIDEST_WIDTH
                Dim index As Integer = 1
                If dt.Columns.Count = 1 Then
                    index = 0
                End If
                For Each row As DataRow In dt.Rows
                    'Die Breite der Dropdown-List anpassen
                    Using g As Graphics = control.CreateGraphics()
                        Dim valueWidth As Integer = g.MeasureString(row.Item(index).ToString(), control.Font).Width
                        If valueWidth + 30 > FinalWidth Then
                            FinalWidth = valueWidth + 30
                        End If
                        g.Dispose()
                    End Using
                Next

                If FinalWidth > WIDEST_WIDTH Then
                    control.DropDownWidth = Math.Max(FinalWidth, control.Width)
                End If
            Catch ex As Exception
                MsgBox("Error in CalculateDropdownWidth:" & vbNewLine & ex.Message)
            End Try
        End Sub

    End Class

    Public Class CheckedListBox : Inherits _ListControl

        Public Shared Sub LoadValue(control As DevExpress.XtraEditors.CheckedListBoxControl, values As List(Of Object))

            If IsNothing(values) Then
                Exit Sub
            End If

            CURRENT_RECORD_ENABLED = False
            control.UnCheckAll()

            For Each v As String In values
                'For i As Integer = 0 To control.ItemCount - 1

                '    Console.WriteLine(control.GetItemText(i))
                'Next i
                Dim posBefore As Integer = 0
                While (control.FindStringExact(v, posBefore) > -1)
                    Dim pos = control.FindStringExact(v, posBefore)

                    ' Wenn v gefunden wurde, anhaken
                    If pos >= 0 Then
                        control.SetItemCheckState(pos, CheckState.Checked)
                        posBefore = pos + 1
                    End If
                    ' Verhindere Endlosschleife
                    If pos = 100 Then
                        Exit While
                    End If
                End While
            Next
        End Sub

        Public Shared Sub LoadList(control As DevExpress.XtraEditors.CheckedListBoxControl, formId As Integer, conn_Id As Object, SQLCommand As String)
            Try
                Dim sw As New SW("LoadList CheckedListBoxControl")

                Dim dynamic As DynamicValue = GetDynamicValue(DirectCast(control.Tag, ClassControlMetadata).Id, formId, conn_Id, SQLCommand)

                If dynamic.StaticList IsNot Nothing Then
                    control.Items.Clear()
                    For Each item In dynamic.StaticList
                        control.Items.Add(item)
                    Next
                    'control.DataSource = dynamic.StaticList
                End If

                If dynamic.DataTable IsNot Nothing AndAlso dynamic.DataTable.Rows.Count > 0 Then
                    'control.Items.Clear()
                    SetDataSource(control, dynamic.DataTable)
                End If

                sw.Done()
            Catch ex As Exception
                MsgBox("Error in CheckedListBox.LoadList:" & vbNewLine & ex.Message)
            End Try
        End Sub

    End Class

    Public Class ListBox : Inherits _ListControl

        Public Shared Sub LoadValue(control As DevExpress.XtraEditors.ListBoxControl, value As String)
            If IsNothing(value) Then
                Exit Sub
            End If

            control.SelectedIndex = control.FindStringExact(value)
        End Sub

        Public Shared Sub LoadList(control As DevExpress.XtraEditors.ListBoxControl, formId As Integer, ConnId As Object, SQLCommand As String)
            Dim sw As New SW("LoadList ListBoxControl")

            Dim dynamic As DynamicValue = GetDynamicValue(DirectCast(control.Tag, ClassControlMetadata).Id, formId, ConnId, SQLCommand)

            If dynamic.StaticList IsNot Nothing Then
                control.DataSource = dynamic.StaticList
            End If

            If dynamic.DataTable IsNot Nothing AndAlso dynamic.DataTable.Rows.Count > 0 Then
                SetDataSource(control, dynamic.DataTable)
            End If

            sw.Done()
        End Sub

    End Class

    Public Class DataGridView : Inherits _ListControl

        Public Shared Sub LoadValue(control As System.Windows.Forms.DataGridView, values As List(Of Object))
            control.Rows.Clear()
            For Each item In values
                control.Rows.Add(item.ToString)
            Next
        End Sub

    End Class

    Public Class DataGridViewCheckable : Inherits _ListControl
        Public Shared Sub LoadList(control As DevExpress.XtraGrid.GridControl, formId As Integer, ConnId As Object, SQLCommand As String)
            Dim sw As New SW("LoadList GridControl")

            Dim dynamic As DynamicValue = GetDynamicValue(DirectCast(control.Tag, ClassControlMetadata).Id, formId, ConnId, SQLCommand)

            If dynamic.StaticList IsNot Nothing Then
                control.DataSource = dynamic.StaticList
            End If

            If dynamic.DataTable IsNot Nothing AndAlso dynamic.DataTable.Rows.Count > 0 Then
                SetDataSource(control, dynamic.DataTable)
            End If


        End Sub

        Public Shared Sub LoadValue(control As DevExpress.XtraGrid.GridControl, values As List(Of Object))
            Dim gridview As DevExpress.XtraGrid.Views.Grid.GridView = control.MainView
            Dim focused As Boolean = False
            For i As Integer = 0 To gridview.RowCount - 1
                Dim fieldName As String = gridview.Columns(0).FieldName
                Dim rowhandle As Integer = gridview.GetRowHandle(i)
                Dim rowvalue As String = gridview.GetRowCellValue(rowhandle, fieldName)
                If values.Contains(rowvalue) Then
                    If focused = False Then
                        gridview.FocusedRowHandle = rowhandle
                        focused = True
                    End If
                    gridview.SelectRow(rowhandle)
                End If
            Next
        End Sub

    End Class

End Namespace
