Imports DevExpress.XtraEditors.Controls
Imports System.Text.RegularExpressions

Public Class ClassControlValues

    Public Shared Function ControlHasValue(control As Control) As Boolean

        Select Case control.GetType()
            Case GetType(TextBox)
                Dim textbox As TextBox = DirectCast(control, TextBox)
                If textbox.Text.Trim() = String.Empty Then
                    Return False
                Else
                    Return True
                End If

            Case GetType(CustomComboBox)
                Dim combobox As CustomComboBox = DirectCast(control, CustomComboBox)
                If combobox.Text.Trim() = String.Empty Then
                    Return False
                Else
                    Return True
                End If

            Case GetType(CheckBox)
                Dim checkbox As CheckBox = DirectCast(control, CheckBox)
                Return checkbox.Checked

            Case GetType(RadioButton)
                Dim radiobutton As RadioButton = DirectCast(control, RadioButton)
                Return radiobutton.Checked

            Case GetType(DevExpress.XtraEditors.DateEdit)
                Dim datepicker As DevExpress.XtraEditors.DateEdit = DirectCast(control, DevExpress.XtraEditors.DateEdit)
                If IsDBNull(datepicker.EditValue) Then
                    Return False
                Else
                    Return True
                End If

            Case GetType(DevExpress.XtraEditors.ListBoxControl)
                Dim listbox As DevExpress.XtraEditors.ListBoxControl = DirectCast(control, DevExpress.XtraEditors.ListBoxControl)
                If listbox.SelectedIndex = -1 Then
                    Return False
                Else
                    Return True
                End If

            Case GetType(DevExpress.XtraEditors.CheckedListBoxControl)
                Dim checkedlistbox = DirectCast(control, DevExpress.XtraEditors.CheckedListBoxControl)
                If checkedlistbox.CheckedItemsCount = 0 Then
                    Return False
                Else
                    Return True
                End If

            Case GetType(PictureBox)
                Dim picturebox = DirectCast(control, PictureBox)
                If IsNothing(picturebox.BackgroundImage) Then
                    Return False
                Else
                    Return True
                End If

            Case Else
                Return True
        End Select

    End Function

    ' Überprüft, welche Controls "Required" sind
    Public Shared Function CheckRequiredControlValues(controls As Control.ControlCollection, Optional isGroupbox As Boolean = False) As List(Of String)
        Dim missingValues As New List(Of String)

        'If isGroupbox = True Then
        '    Dim radiobuttons As New List(Of RadioButton)
        '    Dim otherControls As New List(Of Control)

        '    ' Nach allen Radiobuttons suchen
        '    For Each c As Control In controls
        '        If TypeOf c Is RadioButton Then
        '            radiobuttons.Add(DirectCast(c, RadioButton))
        '        Else
        '            otherControls.Add(c)
        '        End If
        '    Next

        '    ' Wenn mindestens 1 MussFeld-Radiobutton in der Groupbox 
        '    Dim atLeastOneRadioButtonHasRequired = False
        '    For Each rb As RadioButton In radiobuttons
        '        If DirectCast(rb.Tag, ClassControlMetadata).Required = True Then
        '            atLeastOneRadioButtonHasRequired = True
        '            Exit For
        '        End If
        '    Next



        '    If atLeastOneRadioButtonHasRequired Then
        '        ' Alle RadioButtons die angeklickt wurden (ist meistens einer :o)
        '        Dim radioButtonsWithValue = (From rb As RadioButton In radiobuttons
        '                                    Where ControlHasValue(rb)
        '                                    Select rb.Name).ToArray()

        '        ' Wenn kein RadioButton angeklickt wurde, nehmen wir alle in einen String,
        '        ' da GENAU EINER angeklickt werden MUSS
        '        If radioButtonsWithValue Is Nothing Then
        '            Dim missingValue As String = String.Join(", ", radiobuttons)
        '            missingValues.Add(missingValue)
        '        End If
        '    End If
        'End If

        For Each Control As Control In controls

            Dim metadata = DirectCast(Control.Tag, ClassControlMetadata)

            ' Groupbox muss rekursiv überprüft werden
            If TypeOf Control Is GroupBox Then
                Dim groupbox As GroupBox = DirectCast(Control, GroupBox)
                Dim gbfields As List(Of String) = CheckRequiredControlValues(groupbox.Controls, True)
                missingValues.AddRange(gbfields)
                Continue For
            End If

            'Radio Buttons müssen nicht überprüft werden, da eine RadioButton Group
            'immer ein Control mit Checked = true hat
            If TypeOf Control Is RadioButton Then
                Continue For
            End If

            If IsNothing(metadata.Required) OrElse metadata.Required = False Then
                Continue For
            End If
            If Not ControlHasValue(Control) And Control.Enabled = True Then
                missingValues.Add(Control.Name)
            End If


        Next

        Return missingValues.Distinct().ToList()
    End Function

    Public Shared Sub LoadControlValues(RecordId As Integer, ParentRecordId As Integer, FormId As Integer, controls As Control.ControlCollection, Entity_ID As Integer, Optional isGroupbox As Boolean = False)
        Try
            Dim sw As New Stopwatch
            sw.Start()

            'Dim SQL As String = String.Format("SELECT * FROM VWPMO_VALUES WHERE VALUE <> '' AND RECORD_ID = {0}", RecordId)
            Dim SQL As String = String.Format("SELECT * FROM VWPMO_VALUES WHERE RECORD_ID = {0}", RecordId)
            Dim DT_ControlValues As DataTable = ClassDatabase.Return_Datatable(SQL, True)
            CURRENT_CONTROL_VALUES = DT_ControlValues
            Dim elapsed As Double
            elapsed = sw.Elapsed.TotalSeconds
            sw.Stop()
            If LogErrorsOnly = False Then ClassLogger.Add(String.Format(" >> Load VWPMO_VALUES via SQL took {0} to load", Format(elapsed, "0.000000000") & " seconds"), False)

            If controls.Count = 0 Then
                ClassLogger.Add("the control-Collection in LoadControlValuesNeu is empty!", True)
                If (Not isGroupbox) Then
                    ENTITY_RELOAD_AFT_CONTROL_LOAD = True
                End If
                Exit Sub
            End If

            ' Zuerst alle Controls leeren
            ClearControlValues(controls)
            sw.Start()
            ' Load all Hints for controls
            Dim SQLHint = "SELECT * FROM VWPMO_CONTROL_HINT WHERE FORM_ID = " & FormId
            Dim DT_Hints As DataTable = ClassDatabase.Return_Datatable(SQLHint, True)
            ' ' Hint in DT_Hints suchen der zur aktuellen controlId passt
            For Each row As DataRow In DT_Hints.Rows
                ClassControlValueCache.SaveHint(row.Item(1), row.Item(2))
            Next
            '  LoadControlHints(controls)
            elapsed = sw.Elapsed.TotalSeconds
            sw.Stop()
            If LogErrorsOnly = False Then ClassLogger.Add(String.Format(" >> LoadControlHints took {0} to load", Format(elapsed, "0.000000000") & " seconds"), False)
            sw.Start()
            For Each control As Control In controls
                PerfomanceHelper.SuspendDraw(control)

                Dim ControlId As Integer = DirectCast(control.Tag, ClassControlMetadata).Id
                ' Wert per LINQ aus DT_ControlValues suchen der zur aktuellen controlId passt
                Dim values As List(Of Object) = (From row In DT_ControlValues.AsEnumerable()
                            Where row.Item("CONTROL_ID") = ControlId
                            Select row.Item("VALUE")).ToList()
                If TypeOf control Is GroupBox Then
                    Dim groupbox As GroupBox = DirectCast(control, GroupBox)
                    LoadControlValues(RecordId, ParentRecordId, FormId, groupbox.Controls, Entity_ID, True)
                Else
                    LoadControlValue(RecordId, ParentRecordId, ControlId, control, values, Entity_ID)
                End If

                PerfomanceHelper.ResumeDraw(control)
            Next

            elapsed = sw.Elapsed.TotalSeconds
            sw.Stop()
            If LogErrorsOnly = False Then ClassLogger.Add(String.Format(" >> Loop LoadControlValue took {0} to load", Format(elapsed, "0.000000000") & " seconds"), False)
        Catch ex As Exception
            ClassLogger.Add("Unexpected Error in LoadControlValuesNeu: " & ex.Message, True)
            MsgBox("Error in LoadControlValuesNeu:" & vbNewLine & ex.Message, MsgBoxStyle.Critical)
        End Try

    End Sub
    Public Shared Function GetControlValuesREC_CONTROL(RecordId As Integer, CONTROL_ID As Integer)
        Try
            'Dim SQL As String = String.Format("SELECT * FROM VWPMO_VALUES WHERE VALUE <> '' AND RECORD_ID = {0}", RecordId)
            Dim SQL As String = String.Format("SELECT VALUE FROM VWPMO_VALUES WHERE RECORD_ID = {0} AND CONTROL_ID = {1}", RecordId, CONTROL_ID)
            Dim RESULT = ClassDatabase.Execute_Scalar(SQL, True)
            If IsNothing(RESULT) Then
                Return Nothing
            ElseIf RESULT = "" Then
                Return Nothing
            Else
                Return RESULT
            End If
        Catch ex As Exception
            ClassLogger.Add("Unexpected Error in GetControlValuesREC_CONTROL: " & ex.Message, True)
            MsgBox("Error in GetControlValuesREC_CONTROL:" & vbNewLine & ex.Message, MsgBoxStyle.Critical)
            Return Nothing
        End Try

    End Function
    Private Shared Sub LoadControlHints(controls As Control.ControlCollection)

        For Each c As Control In controls
            Dim id As Integer = DirectCast(c.Tag, ClassControlMetadata).Id

            Dim sql As String = String.Format("SELECT HINT FROM TBPMO_CONTROL_LANGUAGE WHERE CONTROL_SCREEN_ID = (SELECT GUID FROM TBPMO_CONTROL_SCREEN WHERE CONTROL_ID = {0} AND SCREEN_ID = 1) AND LANGUAGE_TYPE = '{1}' AND HINT IS NOT NULL", id, USER_LANGUAGE)
            Dim hint = ClassDatabase.Execute_Scalar(sql)

            If IsNothing(hint) Then
                Continue For
            End If

            ClassControlValueCache.SaveHint(id, hint.ToString)
        Next

    End Sub

    Public Shared Sub LoadControlValue(recordId As Integer, parentRecordId As Integer, controlId As Integer, control As Control, values As List(Of Object), entity_ID As Integer)
        Try
            ' Für die meisten Controls wird nur das erste Element der Liste benötigt
            Dim value As String = Nothing

            If values.Count > 0 Then
                value = values.Item(0)
            End If
            Select Case control.GetType()
                Case GetType(TextBox)
                    If CURRENT_CONTROL_ID = 272 Then
                        Console.WriteLine("272")
                    End If
                    Dim textbox As TextBox = DirectCast(control, TextBox)
                    ControlLoader.TextBox.LoadValue(textbox, recordId, parentRecordId, value, entity_ID)

                Case GetType(Label)
                    Dim label As Label = DirectCast(control, Label)
                    ControlLoader.Label.LoadValue(label, recordId, parentRecordId, value, entity_ID)

                Case GetType(CustomComboBox)

                    Dim combobox As CustomComboBox = DirectCast(control, CustomComboBox)
                    ControlLoader.Combobox.LoadValue(combobox, recordId, parentRecordId, value)

                Case GetType(CheckBox)
                    Dim checkbox As CheckBox = DirectCast(control, CheckBox)
                    ControlLoader.Checkbox.LoadValue(checkbox, value)

                Case GetType(RadioButton)
                    If LogErrorsOnly = False Then ClassLogger.Add(" >> Sub LoadControlValueNeu - GetType(RadioButton) ", False)
                    Dim radiobutton As RadioButton = DirectCast(control, RadioButton)
                    ControlLoader.RadioButton.LoadValue(radiobutton, value)

                Case GetType(DevExpress.XtraEditors.DateEdit)
                    Dim datepicker As DevExpress.XtraEditors.DateEdit = DirectCast(control, DevExpress.XtraEditors.DateEdit)
                    ControlLoader.DateTimePicker.LoadValue(datepicker, value)

                Case GetType(DevExpress.XtraEditors.ListBoxControl)
                    Dim listbox As DevExpress.XtraEditors.ListBoxControl = DirectCast(control, DevExpress.XtraEditors.ListBoxControl)
                    ControlLoader.ListBox.LoadValue(listbox, value)

                Case GetType(DevExpress.XtraEditors.CheckedListBoxControl)
                    Dim checkedlistbox As DevExpress.XtraEditors.CheckedListBoxControl = DirectCast(control, DevExpress.XtraEditors.CheckedListBoxControl)
                    ControlLoader.CheckedListBox.LoadValue(checkedlistbox, values)

                Case GetType(PictureBox)
                    Dim picturebox = DirectCast(control, PictureBox)
                    LoadImage(recordId, controlId, picturebox)

                Case GetType(DataGridView)
                    Dim gridview = DirectCast(control, DataGridView)
                    ControlLoader.DataGridView.LoadValue(gridview, values)

                Case GetType(DevExpress.XtraGrid.GridControl)
                    Dim gridcontrol As DevExpress.XtraGrid.GridControl = DirectCast(control, DevExpress.XtraGrid.GridControl)
                    ControlLoader.DataGridViewCheckable.LoadValue(gridcontrol, values)
                Case Else
                    If GetType(Control).ToString() <> "System.Windows.Forms.Control" Then
                        ClassLogger.Add(" >> Sub LoadControlValue - Control-Type nicht berücksichtigt: " & GetType(Control).ToString(), False)
                    End If

            End Select
        Catch ex As Exception
            ClassLogger.Add("Unexpected Error in LoadControlValue: " & ex.Message, True)
            MsgBox("Error in LoadControlValue:" & vbNewLine & ex.Message)
        End Try

    End Sub

    Public Shared Sub LoadControlValuesList(FormID As Integer, controls As Control.ControlCollection)
        Try
            Dim sw As New Stopwatch
            sw.Start()

            If controls.Count = 0 Then
                'MsgBox("LoadControlValuesList: Control.ControlCollection is unexpected empty!", MsgBoxStyle.Exclamation)
                ClassLogger.Add("LoadControlValuesList: Control.ControlCollection is unexpected empty!")
                Exit Sub
            End If
            Dim swsql As Stopwatch = Stopwatch.StartNew()

            ' Zuerst alle SQL Commands für FormID finden
            ' CONTROL_SQLCOMMAND_1 wird als SQL gealiast
            Dim SQL As String = String.Format("SELECT CONTROL_ID, CONTROL_CONNID_1,CONTROL_SQLCOMMAND_1 AS SQL FROM VWPMO_CONTROL_SCREEN WHERE FORM_ID = {0} AND CONTROL_SQLCOMMAND_1 NOT LIKE '%@%'", FormID)
            Dim dt As DataTable = ClassDatabase.Return_Datatable(SQL, True)
            Dim elapsed As Double
            elapsed = swsql.Elapsed.TotalSeconds
            swsql.Stop()
            If LogErrorsOnly = False Then ClassLogger.Add(String.Format(" >> LoadControlValuesList - Database took {0} to load", Format(elapsed, "0.000000000") & " seconds"), False)

            If dt.Rows.Count = 0 Then
                Exit Sub
            End If

            For Each Ctrl As Control In controls
                Dim controlTagId = DirectCast(Ctrl.Tag, ClassControlMetadata).Id

                PerfomanceHelper.SuspendDraw(Ctrl)

                'If controlTagId = 474 Then
                '    MsgBox("Thats it")
                'End If
                'Datatable nach row mit CONTROL_ID wie Ctrl suchen
                Dim row As DataRow = dt.Select(String.Format("CONTROL_ID={0}", controlTagId)).FirstOrDefault()
                If IsNothing(row) Then
                    ' Beim aussteigen muss wieder ResumeDraw aufgerufen werden
                    PerfomanceHelper.ResumeDraw(Ctrl)
                    Continue For
                End If
                Dim sqlcommand As String = row.Item("SQL")
                Dim ConnID = row.Item("CONTROL_CONNID_1")
                Select Case Ctrl.GetType()
                    Case GetType(CustomComboBox)
                        Dim combobox = DirectCast(Ctrl, CustomComboBox)
                        ControlLoader.Combobox.LoadList(combobox, FormID, ConnID, sqlcommand)

                    Case GetType(DevExpress.XtraEditors.ListBoxControl)
                        Dim listbox = DirectCast(Ctrl, DevExpress.XtraEditors.ListBoxControl)
                        ControlLoader.ListBox.LoadList(listbox, FormID, ConnID, sqlcommand)

                    Case GetType(DevExpress.XtraEditors.CheckedListBoxControl)
                        Dim chlistbox = DirectCast(Ctrl, DevExpress.XtraEditors.CheckedListBoxControl)
                        ControlLoader.CheckedListBox.LoadList(chlistbox, FormID, ConnID, sqlcommand)

                    Case GetType(DevExpress.XtraGrid.GridControl)
                        Dim grid = DirectCast(Ctrl, DevExpress.XtraGrid.GridControl)
                        ControlLoader.DataGridViewCheckable.LoadList(grid, FormID, ConnID, sqlcommand)
                End Select

                PerfomanceHelper.ResumeDraw(Ctrl)
            Next

            sw.Stop()
            elapsed = sw.Elapsed.TotalSeconds
            sw.Stop()
            sw.Reset()
            If LogErrorsOnly = False Then ClassLogger.Add(" >> LoadControlValuesList took " & Format(elapsed, "0.000000000") & " seconds", False)
        Catch ex As Exception
            ClassLogger.Add("Unexpected Error in LoadControlValuesList: " & ex.Message, True)
            MsgBox("Unexpected Error in LoadControlValuesList:" & vbNewLine & ex.Message, MsgBoxStyle.Critical)
        End Try


    End Sub

    Public Shared Sub LoadControlValuesListWithPlaceholders(FormId As Integer, RecordId As Integer, ParentRecordId As Integer, controls As Control.ControlCollection, entity_ID As Integer)
        Try
            If controls.Count = 0 Then
                'MsgBox("LoadControlValuesListWithPlaceholders: Control.ControlCollection is unexpected empty!", MsgBoxStyle.Exclamation)
                ClassLogger.Add("LoadControlValuesListWithPlaceholders: Control.ControlCollection is unexpected empty!")
                Exit Sub
            End If

            Dim SQL As String = String.Format("SELECT CONTROL_ID, CONTROL_CONNID_1, CONTROL_SQLCOMMAND_1 AS SQL FROM VWPMO_CONTROL_SCREEN WHERE FORM_ID = {0} AND CONTROL_SQLCOMMAND_1 <> '' AND CONTROL_SQLCOMMAND_1 LIKE '%@%'", FormId)
            Dim SW As Stopwatch = Stopwatch.StartNew()
            Dim commands As New List(Of String)
            Dim dt As DataTable = ClassDatabase.Return_Datatable(SQL, True)

            If dt.Rows.Count = 0 Then
                Exit Sub
            End If

            For Each Ctrl As Control In controls
                Dim controlTagId = DirectCast(Ctrl.Tag, ClassControlMetadata).Id
                Dim row As DataRow = dt.Select(String.Format("CONTROL_ID={0}", controlTagId)).FirstOrDefault()

                If IsNothing(row) Then
                    Continue For
                End If

                Dim connID = row.Item("CONTROL_CONNID_1")
                Dim sqlcommand As String = row.Item("SQL")

                If ParentRecordId = 0 And CURRENT_ACT_LEVEL > 1 Then
                    'eigentlich sollte eine Parent_RecordID da sein
                    Try
                        Dim _SQL = String.Format("SELECT RECORD1_ID FROM TBPMO_RECORD_CONNECT WHERE RECORD2_ID = {0}", RecordId)
                        Dim ParentRec = ClassDatabase.Execute_Scalar(_SQL)
                        If Not IsNothing(ParentRec) Then
                            If ParentRec > 0 Then
                                ParentRecordId = ParentRec
                            End If
                        End If
                    Catch ex As Exception
                        ClassLogger.Add("Unexpected Error in Getting Parent-Record cause PRecord was 0: " & ex.Message)
                    End Try
                End If

                sqlcommand = ReplaceSqlCommandPlaceholders(sqlcommand, RecordId, ParentRecordId, entity_ID)

                PerfomanceHelper.SuspendDraw(Ctrl)

                Select Case Ctrl.GetType()
                    Case GetType(CustomComboBox)
                        Dim combobox = DirectCast(Ctrl, CustomComboBox)
                        ControlLoader.Combobox.LoadList(combobox, FormId, connID, sqlcommand)

                    Case GetType(DevExpress.XtraEditors.ListBoxControl)
                        Dim listbox = DirectCast(Ctrl, DevExpress.XtraEditors.ListBoxControl)
                        ControlLoader.ListBox.LoadList(listbox, FormId, connID, sqlcommand)

                    Case GetType(DevExpress.XtraEditors.CheckedListBoxControl)
                        Dim chlistbox = DirectCast(Ctrl, DevExpress.XtraEditors.CheckedListBoxControl)
                        ControlLoader.CheckedListBox.LoadList(chlistbox, FormId, connID, sqlcommand)

                    Case GetType(DevExpress.XtraGrid.GridControl)
                        Dim gridControl = DirectCast(Ctrl, DevExpress.XtraGrid.GridControl)
                        ControlLoader.DataGridViewCheckable.LoadList(gridControl, FormId, connID, sqlcommand)

                End Select

                PerfomanceHelper.ResumeDraw(Ctrl)
            Next
            Dim elapsed As Double
            elapsed = SW.Elapsed.TotalSeconds
            SW.Stop()
            If LogErrorsOnly = False Then ClassLogger.Add(String.Format(" >> LoadControlValuesListWithPlaceholders took {0} to load", Format(elapsed, "0.000000000") & " seconds"), False)
        Catch ex As Exception
            ClassLogger.Add("Unexpected Error in LoadControlValuesListWithPlaceholders: " & ex.Message, True)
            MsgBox("Unexpected Error in LoadControlValuesListWithPlaceholders:" & vbNewLine & ex.Message, MsgBoxStyle.Critical)
        End Try
    End Sub


    ''' <summary>
    ''' Sucht alle Controls in der aktuellen Entität, die eine Abhängigkeit besitzen,
    ''' und (de)aktiviert sie basierend auf dem Wert er Abhängigkeit
    ''' </summary>
    ''' <remarks></remarks>
    Public Shared Sub Enable_Depending_Controls(FormId As Integer, RecordId As Integer, ParentRecordId As Integer, controls As Control.ControlCollection, entity_ID As Integer)
        Try
            If controls.Count = 0 Then
                'MsgBox("LoadControlValuesListWithPlaceholders: Control.ControlCollection is unexpected empty!", MsgBoxStyle.Exclamation)
                ClassLogger.Add("Enable_Depending_Controls: Control.ControlCollection is unexpected empty!")
                Exit Sub
            End If
            ' Alle Controls finden, die Abhängigkeiten haben
            Dim SQL As String = String.Format("select GUID,NAME,SQL_COMMAND_2 from TBPMO_CONTROL where FORM_ID = {0} AND SQL_COMMAND_2 IS NOT NULL " _
                                              & "AND LEN(SQL_COMMAND_2) > 10 AND SQL_COMMAND_2 LIKE '%@%@%'", FormId)
            Dim SW As Stopwatch = Stopwatch.StartNew()
            Dim commands As New List(Of String)
            Dim dt As DataTable = ClassDatabase.Return_Datatable(SQL)

            If dt.Rows.Count = 0 Then
                Exit Sub
            End If

            ' Durchlaufe alle Controls, die eine Abhängigheit haben
            For Each row As DataRow In dt.Rows
                Dim DependingControlId As Integer = row.Item("GUID")
                Dim DependingControlSQL As String = row.Item("SQL_COMMAND_2")
                Dim DependingControl As Control = controls.OfType(Of Control)().Where(Function(c As Control)
                                                                                          Return DirectCast(c.Tag, ClassControlMetadata).Id = DependingControlId
                                                                                      End Function).SingleOrDefault()

                Dim regex As New Regex("(@(\d+)@)")
                Dim match As Match = regex.Match(DependingControlSQL)

                If match.Success Then
                    ' Wir suchen aus dem SQL Befehl die ControlId heraus,
                    ' von dem das aktuelle Control abhängt
                    Dim otherControlId As Integer
                    Integer.TryParse(match.Groups(2).Value, otherControlId)
                    ' Jetzt suchen wir das Control, das zu dieser ControlId passt
                    Dim otherControl As Control = controls.OfType(Of Control)().Where(Function(c As Control)
                                                                                          Dim controlId As Integer = DirectCast(c.Tag, ClassControlMetadata).Id
                                                                                          Console.WriteLine(controlId)
                                                                                          Return controlId = otherControlId
                                                                                      End Function).SingleOrDefault()
                    Dim otherControlType As String = otherControl.GetType().Name

                    ' Jetzt holen wir uns den Wert von dem 'OtherControl'
                    ' und geben seinen Value zusammen mit dem dependingControl weiter
                    Dim value As Object = Nothing

                    ' Jetzt lesen wir den Wert aus, der im SQL Command ersetzt werden soll
                    Select Case otherControlType
                        Case "CheckBox"
                            value = DirectCast(otherControl, CheckBox).Checked
                        Case "TextBox"
                            value = DirectCast(otherControl, TextBox).Text
                        Case "CustomComboBox"
                            value = DirectCast(otherControl, CustomComboBox).Text
                        Case "DateEdit"
                            value = DirectCast(otherControl, DevExpress.XtraEditors.DateEdit).EditValue
                    End Select

                    ' Jetzt ersetzen wir den Platzhalter im SQL Command
                    DependingControlSQL = regex.Replace(DependingControlSQL, value)

                    Dim enableDT As DataTable = ClassDatabase.Return_Datatable(DependingControlSQL)

                    If enableDT.Rows.Count = 1 Then
                        Dim enabled As Boolean = CBool(enableDT.Rows(0).Item(0))
                        DependingControl.Enabled = enabled
                    Else
                        ClassLogger.Add(" >> Attention in Enable_Depending_Controls: RowCount for enabling control was '" & enableDT.Rows.Count.ToString & "' and not 1 as expected - Check SQL: '" & DependingControlSQL & "'")
                    End If
                End If
            Next

            Dim elapsed As Double
            elapsed = SW.Elapsed.TotalSeconds
            SW.Stop()
            If LogErrorsOnly = False Then ClassLogger.Add(String.Format(" >> Enable_Depending_Controls took {0} to load", Format(elapsed, "0.000000000") & " seconds"), False)
        Catch ex As Exception
            ClassLogger.Add("Unexpected Error in Enable_Depending_Controls: " & ex.Message, True)
            MsgBox("Unexpected Error in Enable_Depending_Controls:" & vbNewLine & ex.Message, MsgBoxStyle.Critical)
        End Try
    End Sub
    Public Shared Function ReplaceSqlCommandPlaceholders(sqlCommand As String, recordId As Integer, parentRecordId As Integer, entity_Id As Integer)
        Try
            sqlCommand = sqlCommand.Replace("@RECORD_ID", recordId)
            sqlCommand = sqlCommand.Replace("@RECORDID", recordId)
            sqlCommand = sqlCommand.Replace("@ENTITY_ID", entity_Id)
            sqlCommand = sqlCommand.Replace("@PARENTRECORD_ID", parentRecordId)
            sqlCommand = sqlCommand.Replace("@PARENTRECORDID", parentRecordId)
            Return sqlCommand
        Catch ex As Exception
            ClassLogger.Add("Unexpected Error in ReplaceSqlCommandPlaceholders: " & ex.Message, True)
            MsgBox("Unexpected Error in ReplaceSqlCommandPlaceholders:" & vbNewLine & ex.Message, MsgBoxStyle.Critical)
            Return sqlCommand
        End Try
      
    End Function

    Public Shared Sub UnloadControlValuesList(RecordID As Integer, FormID As Integer, controls As Control.ControlCollection)
        For Each C As Control In controls
            If TypeOf C Is CustomComboBox Then
                Dim Combobox = DirectCast(C, CustomComboBox)
                Dim currentValue As String = Combobox.Text
                Combobox.DataSource = Nothing
                Combobox.Text = currentValue
            End If
        Next
    End Sub

    Public Shared Sub LoadImage(RecordID As Integer, ControlID As Integer, control As Control)
        Dim picbox As PictureBox = DirectCast(control, PictureBox)
        Dim SQL As String = String.Format("SELECT IMG FROM TBPMO_CONTROL_IMAGE WHERE RECORD_ID = {0} AND CONTROL_ID = {1}", RecordID, ControlID)
        Dim bimage As Byte() = ClassDatabase.Execute_Scalar(SQL)

        If Not IsNothing(bimage) Then
            picbox.BackgroundImage = ByteArrayToBitmap(bimage)
            picbox.BackgroundImageLayout = ImageLayout.Zoom
        Else
            picbox.BackgroundImage = Nothing
        End If
    End Sub

#Region "ClearControlValue"
    Public Shared Sub ClearControlValues(controls As Control.ControlCollection)
        For Each control In controls
            If control.GetType().Name = "GroupBox" Then
                Dim groupbox As GroupBox = control
                ClearControlValues(groupbox.Controls)
            Else
                ClearControlValue(control)
            End If
        Next
    End Sub

    Public Shared Sub ClearControlValue(control As Control)
        Select Case control.GetType()
            Case GetType(TextBox)
                DirectCast(control, TextBox).Text = String.Empty

            Case GetType(CustomComboBox)
                Dim combo As CustomComboBox = DirectCast(control, CustomComboBox)
                combo.SelectedIndex = -1
                combo.Text = String.Empty

            Case GetType(CheckBox)
                DirectCast(control, CheckBox).Checked = False

            Case GetType(RadioButton)
                DirectCast(control, RadioButton).Checked = False

            Case GetType(DevExpress.XtraEditors.DateEdit)
                DirectCast(control, DevExpress.XtraEditors.DateEdit).DateTime = Now

            Case GetType(PictureBox)
                DirectCast(control, PictureBox).BackgroundImage = Nothing

            Case GetType(DevExpress.XtraEditors.CheckedListBoxControl)
                Dim chklbx As DevExpress.XtraEditors.CheckedListBoxControl = DirectCast(control, DevExpress.XtraEditors.CheckedListBoxControl)
                chklbx.UnCheckAll()

            Case GetType(DevExpress.XtraEditors.ListBoxControl)
                Dim lb As DevExpress.XtraEditors.ListBoxControl = DirectCast(control, DevExpress.XtraEditors.ListBoxControl)
                lb.SelectedIndex = -1


            Case GetType(DataGridView)
                Dim dgv As DataGridView = DirectCast(control, DataGridView)
                Dim ds = dgv.DataSource

                If (IsNothing(ds)) Then
                    dgv.Rows.Clear()
                    dgv.Refresh()
                Else
                    dgv.DataSource = Nothing
                    dgv.Refresh()
                End If

            Case GetType(DevExpress.XtraGrid.GridControl)
                Dim gc = DirectCast(control, DevExpress.XtraGrid.GridControl)
                Dim gridview As DevExpress.XtraGrid.Views.Grid.GridView = gc.MainView

                ' Setzt den Filter zurück
                gridview.ActiveFilterString = String.Empty

                If gridview.RowCount = 0 Then
                    Exit Select
                End If

                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)
                    gridview.UnselectRow(rowhandle)
                Next
                Try
                    gridview.Columns(0).OptionsColumn.AllowEdit = False
                Catch ex As Exception

                End Try

        End Select
    End Sub
#End Region

#Region "LoadDefaultValue"

    Public Shared Sub LoadDefaultValues(FormID As Integer, RecordID As Integer, controls As Control.ControlCollection, parentRecordID As Integer, EntityID As Integer)
        Try
            Dim sw As New Stopwatch()
            sw.Start()

            ' Alle Controls leeren
            ClearControlValues(controls)

            ' Alle Controls laden, die einen Default Value haben
            Dim SQL As String = String.Format("SELECT CONTROL_ID, CONTROL_DEF_VALUE, CONTROL_NAME FROM VWPMO_CONTROL_SCREEN WHERE FORM_ID = {0} AND CONTROL_DEF_VALUE <> '' " & _
                                              "UNION SELECT CONTROL_ID, CONTROL_SQLCOMMAND_1 AS CONTROL_DEF_VALUE, CONTROL_NAME FROM VWPMO_CONTROL_SCREEN where FORM_ID = {0} and CONTROL_SQLCOMMAND_1 <> '' AND CONTROL_SQLCOMMAND_1 NOT LIKE '%@%@%' AND CONTROL_SQLCOMMAND_1 LIKE '%@RECORD_ID%'", FormID)
            Dim DEFAULT_VALUE_DT As DataTable = ClassDatabase.Return_Datatable(SQL, True)

            For Each row As DataRow In DEFAULT_VALUE_DT.Rows

                Dim defaultValue = row.Item("CONTROL_DEF_VALUE")
                Dim controlId As Integer = row.Item("CONTROL_ID")
                Dim controlName As String = row.Item("CONTROL_NAME")


                Try
                    Dim control As Control = controls.Find(controlName, False)(0)
                    LoadDefaultValue(controlId, RecordID, Control, parentRecordID, EntityID, defaultValue)
                Catch ex As Exception
                    ClassLogger.Add("Unexpected Error in getting default value for control '" & controlName & " - " & ex.Message, True)
                End Try
            Next


            sw.Stop()
            Console.WriteLine("LoadDefaultValues took {0} milliseconds to load", sw.ElapsedMilliseconds)

            'Den Focus auf das erste Steuerelement setzen
            For Each c As Control In controls
                If Not TypeOf c Is Label Then
                    c.Focus()
                    Exit For
                End If
            Next
        Catch ex As Exception
            MsgBox("Error in LoadDefaultValues: " & vbNewLine & ex.Message, MsgBoxStyle.Critical)
        End Try
    End Sub


    'Public Shared Sub LoadDefaultValues_(FormID As Integer, RecordID As Integer, controls As Control.ControlCollection, ParentRecordId As Integer, entity_ID As Integer)
    '    '' Zuerst alle Controls leeren
    '    ClearControlValues(controls)

    '    Dim i = 0
    '    For Each control As Control In controls

    '        Dim CONTROL_ID = DirectCast(control.Tag, ClassControlMetadata).Id ' GetControlID_for_Name(control.Name, FormID)
    '        If Not (TypeOf control Is Label) Then
    '            i += 1
    '        End If

    '        If TypeOf control Is GroupBox Then
    '            LoadDefaultValues(FormID, RecordID, DirectCast(control, GroupBox).Controls, ParentRecordId, entity_ID)
    '        End If

    '        'LoadDefaultValue(CONTROL_ID, RecordID, control, ParentRecordId, entity_ID)

    '        'Den Focus auf das erste Steuerelement setzen
    '        If i = 1 Then
    '            control.Focus()
    '        End If

    '    Next
    'End Sub

    Public Shared Sub LoadDefaultValue(ControlID As Integer, RecordID As Integer, control As Control, ParentRecordId As Integer, entity_ID As Integer, defaultValue As Object)
        Try
            'Dim SQL = String.Format("SELECT CONTROL_DEF_VALUE FROM VWPMO_CONTROL_SCREEN WHERE CONTROL_ID = {0} and CONTROL_DEF_VALUE <> ''", ControlID)
            'Dim defaultValue = ClassDatabase.Execute_Scalar(SQL)

            'Dim SQL = "SELECT * FROM VWPMO_CONTROL_SCREEN WHERE CONTROL_ID = " & ControlID
            'Dim DT As DataTable = ClassDatabase.Return_Datatable(SQL)
            'Dim result = DT.Rows(0).Item("CONTROL_DEF_VALUE")

            Select Case control.GetType()
                Case GetType(TextBox)
                    If ControlID = 272 Then
                        Console.WriteLine("obacht")
                    End If
                    Dim textbox As TextBox = DirectCast(control, TextBox)
                    If IsDBNull(defaultValue) Then
                        textbox.Text = ""
                    Else
                        Dim vorgabe = defaultValue
                        'Wenn der Default Wert über einen Select kommt
                        If vorgabe.ToString.ToLower.StartsWith("select") Then
                            vorgabe = defaultValue.Replace("@FORM_ID", CURRENT_ENTITY_ID)
                            vorgabe = vorgabe.Replace("@RECORD_ID", CURRENT_RECORD_ID)
                            vorgabe = vorgabe.Replace("@RECORDID", CURRENT_RECORD_ID)
                            vorgabe = vorgabe.Replace("@PARENTRECORD_ID", CURRENT_PARENT_RECORD_ID)
                            defaultValue = ClassDatabase.Execute_Scalar(vorgabe.ToString, True)
                            If IsNothing(vorgabe) Then
                                textbox.Text = ""
                            End If
                        End If
                        textbox.Text = defaultValue
                    End If

                Case GetType(CheckBox)
                    Dim checkbox As CheckBox = DirectCast(control, CheckBox)
                    checkbox.Checked = StrToBool(defaultValue)

                Case GetType(RadioButton)
                    Dim radio As RadioButton = DirectCast(control, RadioButton)
                    radio.Checked = StrToBool(defaultValue)

                Case GetType(CustomComboBox)

                    Dim combobox As CustomComboBox = DirectCast(control, CustomComboBox)
                    If IsDBNull(defaultValue) Then
                        combobox.SelectedIndex = -1
                    Else
                        combobox.SelectedIndex = combobox.FindStringExact(defaultValue)
                    End If
                Case GetType(DevExpress.XtraEditors.DateEdit)
                    Dim datepicker As DevExpress.XtraEditors.DateEdit = DirectCast(control, DevExpress.XtraEditors.DateEdit)

                    If IsDBNull(defaultValue) Then
                        defaultValue = String.Empty
                    End If

                    Dim result As EnumDateTimePickerDefaultValueOptions = EnumDateTimePickerDefaultValueOptions.Empty
                    Dim success = [Enum].TryParse(Of EnumDateTimePickerDefaultValueOptions)(defaultValue, result)

                    If success Then
                        If result = EnumDateTimePickerDefaultValueOptions.Empty Then
                            ' DBNull.Value leert das DateEdit control.
                            defaultValue = DBNull.Value
                        ElseIf result = EnumDateTimePickerDefaultValueOptions.CurrentDate Then
                            defaultValue = Now
                        End If
                    Else
                        'Wenn der DefaultWert nicht gelesen werden konnte, DateEdit leeren
                        defaultValue = DBNull.Value
                    End If

                    ' Mit EditValue kann man auch den angezeigten Wert leeren
                    'datepicker.DateTime = autoValue
                    datepicker.EditValue = defaultValue
                Case GetType(Label)
                    Dim lbl As Label = DirectCast(control, Label)
                    Dim CONNID = ClassDatabase.Execute_Scalar(String.Format("SELECT CONNECTION_ID_1 FROM TBPMO_CONTROL WHERE GUID = {0}", ControlID))
                    'Dim SQL_AUTOVALUE As String = ClassDatabase.Execute_Scalar(String.Format("SELECT SQL_COMMAND_1 FROM TBPMO_CONTROL WHERE GUID = {0}", ControlID))
                    defaultValue = ClassControlValues.ReplaceSqlCommandPlaceholders(defaultValue, RecordID, ParentRecordId, entity_ID)


                    If defaultValue = "" Or IsDBNull(defaultValue) Then
                        Exit Sub
                    End If

                    If Not IsNothing(CONNID) Then
                        defaultValue = ClassDatabase.Execute_ScalarWithConnection(CONNID, defaultValue)
                    Else
                        defaultValue = ClassDatabase.Execute_Scalar(defaultValue, True)
                    End If
                    ' AutoValue = ClassDatabase.Execute_Scalar(SQL)

                    If Not IsNothing(defaultValue) And Not IsDBNull(defaultValue) Then
                        lbl.Text = defaultValue
                    End If

            End Select
        Catch ex As Exception
            MsgBox("Unexpected Error in LoadDefaultValue:" & vbNewLine & ex.Message, MsgBoxStyle.Critical)
        End Try
    End Sub
#End Region


    Public Shared Function Get_Control_Value_for_ID(Control_ID As Integer, Record_ID As Integer)
        Try
            Dim sql = "SELECT VALUE FROM TBPMO_CONTROL_VALUE WHERE CONTROL_ID = " & Control_ID & " AND RECORD_ID = " & Record_ID
            CURRENT_LAST_SQL = sql
            Return ClassDatabase.Execute_Scalar(sql)
        Catch ex As Exception
            ClassLogger.Add("Unexpected Error in GetControlValueForControlID: " & ex.Message, True)
            MsgBox("Error in GetControlValueForControlID:" & vbNewLine & ex.Message, MsgBoxStyle.Critical)
            Return Nothing
        End Try
    End Function

End Class
