Imports DD_Record_Organiser.ClassDatabase
Imports DD_Record_Organiser.ClassControlBuilder



Public Class ClassControlCommandsUI
    Private _CtrlBuilder As ClassControlBuilder
    Private _AddAppointmentHandler As System.EventHandler
    Private _AddFormDataHandler As System.EventHandler
    Private _ContextMenuStrip As ContextMenuStrip

    Public IsInsert As Boolean = False

    ''' <summary>
    ''' Erstellt eine neue Instanz der ClassControlCommandsUI Klasse
    ''' </summary>
    ''' <param name="ControlBuilder">Eine ControlBuilder Instanz</param>
    ''' <param name="AddAppointmentDelegate">Ein Delegate, der auf eine AddAppointment-Methode verweist, mit AddressOf verwenden</param>
    ''' <param name="AddFormDataDelegate">Ein Delegate, der auf eine AddFormData-Methode verweist, mit AddressOf verwenden</param>
    ''' <remarks></remarks>
    Sub New(ControlBuilder As ClassControlBuilder, ContextMenuStrip As ContextMenuStrip, AddAppointmentDelegate As System.EventHandler, AddFormDataDelegate As System.EventHandler)
        _CtrlBuilder = ControlBuilder
        _ContextMenuStrip = ContextMenuStrip
        _AddAppointmentHandler = AddAppointmentDelegate
        _AddFormDataHandler = AddFormDataDelegate
    End Sub

    Sub LoadControls(FormId As Integer)
        _CtrlBuilder.ClearControls()

        Dim SQL As String = String.Format("SELECT T.*, dbo.FNPMO_GET_CONTROL_CAPTION ('{2}', {3},T.CONTROL_ID) AS 'CAPTION' FROM VWPMO_CONTROL_SCREEN T WHERE SCREEN_ID = {0} AND FORM_ID = {1}", CURRENT_SCREEN_ID, FormId, USER_LANGUAGE, CURRENT_SCREEN_ID)

        ' "SELECT * FROM VWPMO_CONTROL_SCREEN WHERE FORM_ID = " & FormId & " and SCREEN_ID = 1"
        Dim DT As DataTable = ClassDatabase.Return_Datatable(SQL)

        _CtrlBuilder.MasterPanel.SuspendLayout()

        For Each dr As DataRow In DT.Rows

            Dim parent As GroupBox = Nothing
            If (dr.Item("CONTROL_PARENT_ID") <> 0) Then
                Dim parentname As String = Get_Name_for_ControlID(dr.Item("CONTROL_PARENT_ID"), FormId)
                parent = _CtrlBuilder.GetControlByName(parentname)
            End If

            Select Case dr.Item("CTRLTYPE_ID")
                Case 1 ' Label
                    _CtrlBuilder.AddLabel(dr.Item("CONTROL_ID"),
                                        dr.Item("CONTROL_NAME"),
                                         dr.Item("CAPTION"),
                                         dr.Item("CTRLSCR_X_LOC"),
                                         dr.Item("CTRLSCR_Y_LOC"),
                                         dr.Item("CTRLSCR_FONT_FAMILY"),
                                         dr.Item("CTRLSCR_FONT_COLOR"),
                                         dr.Item("CTRLSCR_FONT_SIZE"),
                                         dr.Item("CTRLSCR_FONT_STYLE"),
                                         dr.Item("CONTROL_SQLCOMMAND_1"),
                                         False,
                                         parent)
                Case 2 ' TextBox
                    _CtrlBuilder.AddTextBox(dr.Item("CONTROL_ID"),
                                            dr.Item("CONTROL_NAME"),
                                           dr.Item("CTRLSCR_X_LOC"),
                                           dr.Item("CTRLSCR_Y_LOC"),
                                           dr.Item("CTRLSCR_FONT_FAMILY"),
                                           dr.Item("CTRLSCR_FONT_COLOR"),
                                           dr.Item("CTRLSCR_FONT_SIZE"),
                                           dr.Item("CTRLSCR_FONT_STYLE"),
                                           dr.Item("CTRLSCR_TAB_INDEX"),
                                           dr.Item("CTRLSCR_TAB_STOP"),
                                           dr.Item("CTRLSCR_WIDTH"),
                                           dr.Item("CTRLSCR_HEIGHT"),
                                           dr.Item("CONTROL_MULTILINE"),
                                           dr.Item("CONTROL_READ_ONLY"),
                                           dr.Item("CONTROL_REQUIRED"),
                                           dr.Item("CONTROL_FORMAT_TYPE"),
                                           False,
                                           parent)
                Case 3 ' ComboBox
                    _CtrlBuilder.AddComboBox(dr.Item("CONTROL_ID"),
                                            dr.Item("CONTROL_NAME"),
                                            dr.Item("CTRLSCR_X_LOC"),
                                            dr.Item("CTRLSCR_Y_LOC"),
                                            dr.Item("CTRLSCR_FONT_FAMILY"),
                                            dr.Item("CTRLSCR_FONT_COLOR"),
                                            dr.Item("CTRLSCR_FONT_SIZE"),
                                            dr.Item("CTRLSCR_FONT_STYLE"),
                                            dr.Item("CTRLSCR_TAB_INDEX"),
                                            dr.Item("CTRLSCR_TAB_STOP"),
                                            dr.Item("CTRLSCR_WIDTH"),
                                            dr.Item("CTRLSCR_HEIGHT"),
                                            dr.Item("CONTROL_FORMAT_TYPE"),
                                            False,
                                            dr.Item("CONTROL_READ_ONLY"),
                                            dr.Item("CONTROL_REQUIRED"),
                                            dr.Item("CONTROL_STATIC_LIST"),
                                            dr.Item("CONTROL_SQLCOMMAND_1"),
                                            parent)
                Case 4 ' DateTimePicker
                    _CtrlBuilder.AddDateTimePicker(dr.Item("CONTROL_ID"),
                                                    dr.Item("CONTROL_NAME"),
                                                  dr.Item("CTRLSCR_X_LOC"),
                                                  dr.Item("CTRLSCR_Y_LOC"),
                                                  dr.Item("CTRLSCR_FONT_FAMILY"),
                                                  dr.Item("CTRLSCR_FONT_SIZE"),
                                                  dr.Item("CTRLSCR_FONT_STYLE"),
                                                  dr.Item("CTRLSCR_TAB_INDEX"),
                                                  dr.Item("CTRLSCR_TAB_STOP"),
                                                  dr.Item("CTRLSCR_WIDTH"),
                                                  dr.Item("CTRLSCR_HEIGHT"),
                                                  dr.Item("CONTROL_READ_ONLY"),
                                                  dr.Item("CONTROL_REQUIRED"),
                                                  False,
                                                  parent)
                Case 5 ' GroupBox
                    _CtrlBuilder.AddGroupBox(dr.Item("CONTROL_ID"),
                                            dr.Item("CONTROL_NAME"),
                                            dr.Item("CTRLSCR_CAPTION"),
                                            dr.Item("CTRLSCR_X_LOC"),
                                            dr.Item("CTRLSCR_Y_LOC"),
                                            dr.Item("CTRLSCR_WIDTH"),
                                            dr.Item("CTRLSCR_HEIGHT"),
                                            dr.Item("CTRLSCR_BACK_COLOR"),
                                            dr.Item("CTRLSCR_FONT_COLOR"),
                                            dr.Item("CTRLSCR_FONT_FAMILY"),
                                            dr.Item("CTRLSCR_FONT_SIZE"),
                                            dr.Item("CTRLSCR_FONT_STYLE"),
                                            False,
                                            parent)
                Case 6 ' PictureBox
                    _CtrlBuilder.AddPictureBox(dr.Item("CONTROL_ID"),
                                                dr.Item("CONTROL_NAME"),
                                              dr.Item("CTRLSCR_X_LOC"),
                                              dr.Item("CTRLSCR_Y_LOC"),
                                              dr.Item("CTRLSCR_WIDTH"),
                                              dr.Item("CTRLSCR_HEIGHT"),
                                              False,
                                              dr.Item("CONTROL_READ_ONLY"),
                                              dr.Item("CONTROL_REQUIRED"),
                                              parent)
                Case 7 ' DataGridView
                    _CtrlBuilder.AddDataGridView(dr.Item("CONTROL_ID"),
                                                dr.Item("CONTROL_NAME"),
                                                dr.Item("CTRLSCR_X_LOC"),
                                                dr.Item("CTRLSCR_Y_LOC"),
                                                dr.Item("CTRLSCR_WIDTH"),
                                                dr.Item("CTRLSCR_HEIGHT"),
                                                False,
                                                dr.Item("CONTROL_READ_ONLY"),
                                                dr.Item("CONTROL_REQUIRED"),
                                                dr.Item("CONTROL_COL_NAME"),
                                                parent)
                Case 10 ' Checkbox
                    Dim Checked As Boolean = False
                    'If IsDBNull(dr.Item("CONTROL_DEF_VALUE")) Then
                    '    Checked = False
                    'Else
                    '    Checked = StrToBool(dr.Item("CONTROL_DEF_VALUE"))
                    'End If
                    _CtrlBuilder.AddCheckBox(dr.Item("CONTROL_ID"),
                                            dr.Item("CONTROL_NAME"),
                                            dr.Item("CTRLSCR_CAPTION"),
                                            Checked,
                                            dr.Item("CTRLSCR_X_LOC"),
                                            dr.Item("CTRLSCR_Y_LOC"),
                                            dr.Item("CTRLSCR_FONT_FAMILY"),
                                            dr.Item("CTRLSCR_FONT_COLOR"),
                                            dr.Item("CTRLSCR_FONT_SIZE"),
                                            dr.Item("CTRLSCR_FONT_STYLE"),
                                            dr.Item("CTRLSCR_TAB_INDEX"),
                                            dr.Item("CTRLSCR_TAB_STOP"),
                                            dr.Item("CTRLSCR_WIDTH"),
                                            dr.Item("CTRLSCR_HEIGHT"),
                                            False,
                                            dr.Item("CONTROL_READ_ONLY"),
                                            dr.Item("CONTROL_REQUIRED"),
                                            parent)
                Case 8 ' Function AddAppointment
                    _CtrlBuilder.FunctionAddAppointment(dr.Item("CONTROL_ID"),
                                                        dr.Item("CONTROL_NAME"),
                                                       dr.Item("CTRLSCR_CAPTION"),
                                                       dr.Item("CTRLSCR_X_LOC"),
                                                       dr.Item("CTRLSCR_Y_LOC"),
                                                       dr.Item("CTRLSCR_WIDTH"),
                                                       dr.Item("CTRLSCR_HEIGHT"),
                                                       False,
                                                       parent)
                    AddHandler _CtrlBuilder.CurrentControl.Click, _AddAppointmentHandler
                Case 9 ' Function AddFormData
                    _CtrlBuilder.FunctionAddFormData(dr.Item("CONTROL_ID"),
                                                    dr.Item("CONTROL_NAME"),
                                                    dr.Item("CTRLSCR_CAPTION"),
                                                    dr.Item("CTRLSCR_X_LOC"),
                                                    dr.Item("CTRLSCR_Y_LOC"),
                                                    dr.Item("CTRLSCR_WIDTH"),
                                                    dr.Item("CTRLSCR_HEIGHT"),
                                                    False,
                                                    parent)
                    AddHandler _CtrlBuilder.CurrentControl.Click, _AddFormDataHandler
                Case 11 ' RadioButton
                    Dim Checked As Boolean = False
                    'If IsDBNull(dr.Item("CONTROL_DEF_VALUE")) Then
                    '    Checked = False
                    'Else
                    '    Checked = StrToBool(dr.Item("CONTROL_DEF_VALUE"))
                    'End If
                    _CtrlBuilder.AddRadioButton(dr.Item("CONTROL_ID"),
                                                dr.Item("CONTROL_NAME"),
                                                dr.Item("CTRLSCR_CAPTION"),
                                                Checked,
                                                dr.Item("CTRLSCR_X_LOC"),
                                                dr.Item("CTRLSCR_Y_LOC"),
                                                dr.Item("CTRLSCR_FONT_FAMILY"),
                                                dr.Item("CTRLSCR_FONT_COLOR"),
                                                dr.Item("CTRLSCR_FONT_SIZE"),
                                                dr.Item("CTRLSCR_FONT_STYLE"),
                                                dr.Item("CTRLSCR_TAB_INDEX"),
                                                dr.Item("CTRLSCR_TAB_STOP"),
                                                dr.Item("CTRLSCR_WIDTH"),
                                                dr.Item("CTRLSCR_HEIGHT"),
                                                False,
                                                dr.Item("CONTROL_READ_ONLY"),
                                                dr.Item("CONTROL_REQUIRED"),
                                                parent)
                Case 12 'CheckedListBox
                    CtrlBuilder.AddCheckedListBox(dr.Item("CONTROL_ID"),
                                            dr.Item("CONTROL_NAME"),
                                            dr.Item("CTRLSCR_X_LOC"),
                                            dr.Item("CTRLSCR_Y_LOC"),
                                            dr.Item("CTRLSCR_FONT_FAMILY"),
                                            dr.Item("CTRLSCR_FONT_COLOR"),
                                            dr.Item("CTRLSCR_FONT_SIZE"),
                                            dr.Item("CTRLSCR_FONT_STYLE"),
                                            dr.Item("CTRLSCR_TAB_INDEX"),
                                            dr.Item("CTRLSCR_TAB_STOP"),
                                            dr.Item("CTRLSCR_WIDTH"),
                                            dr.Item("CTRLSCR_HEIGHT"),
                                            False,
                                            dr.Item("CONTROL_READ_ONLY"),
                                            dr.Item("CONTROL_REQUIRED"),
                                            dr.Item("CONTROL_STATIC_LIST"),
                                            dr.Item("CONTROL_SQLCOMMAND_1"),
                                            parent)
                Case 13 'CheckedListBox
                    CtrlBuilder.AddListBox(dr.Item("CONTROL_ID"),
                                            dr.Item("CONTROL_NAME"),
                                            dr.Item("CTRLSCR_X_LOC"),
                                            dr.Item("CTRLSCR_Y_LOC"),
                                            dr.Item("CTRLSCR_FONT_FAMILY"),
                                            dr.Item("CTRLSCR_FONT_COLOR"),
                                            dr.Item("CTRLSCR_FONT_SIZE"),
                                            dr.Item("CTRLSCR_FONT_STYLE"),
                                            dr.Item("CTRLSCR_TAB_INDEX"),
                                            dr.Item("CTRLSCR_TAB_STOP"),
                                            dr.Item("CTRLSCR_WIDTH"),
                                            dr.Item("CTRLSCR_HEIGHT"),
                                            False,
                                            dr.Item("CONTROL_READ_ONLY"),
                                            dr.Item("CONTROL_REQUIRED"),
                                            dr.Item("CONTROL_STATIC_LIST"),
                                            dr.Item("CONTROL_SQLCOMMAND_1"),
                                            parent)
            End Select

            _CtrlBuilder.MasterPanel.ResumeLayout()

            ' ContextMenuStrip zuweisen
            ' MasterDataID im ContextMenuStrip Speichern
            If dr.Item("CTRLSCR_MASTER_DATA_ID") <> 0 Then
                _CtrlBuilder.CurrentControl.ContextMenuStrip = _ContextMenuStrip
                ' Tag wird für ControlId verwendet, master data id bei rechtsklick herausfinden
                '_CtrlBuilder.CurrentControl.Tag = dr.Item("CTRLSCR_MASTER_DATA_ID")
            End If
        Next
    End Sub

    Function DeleteRecord(RecordID As Integer)
        Dim sql As String = "DELETE FROM TBPMO_RECORD_CONNECT WHERE RECORD1_ID = " & RecordID & " OR RECORD2_ID = " & RecordID
        If ClassDatabase.Execute_non_Query(sql) = True Then
            sql = "DELETE FROM TBPMO_WORKFLOW_TASK WHERE RECORD_ID = " & RecordID
            If ClassDatabase.Execute_non_Query(sql) = True Then
                sql = "DELETE FROM TBPMO_CONTROL_VALUE WHERE RECORD_ID = " & RecordID
                If ClassDatabase.Execute_non_Query(sql) = True Then ' Delete der Controls erfolgreich ausgeführt, jetzt der Record
                    sql = "DELETE FROM TBPMO_RECORD WHERE GUID = " & RecordID
                    If ClassDatabase.Execute_non_Query(sql) = True Then
                        Return True
                    End If
                End If
            End If
        End If

        Return False
    End Function


    Function SaveRecord(RecordID As Integer, FormID As Integer, Optional foreignRecordID As Integer = 0) As String
        Try
            Dim ADDED_WHO As String = Environment.UserName
            Dim RECORD_ID As Integer

            If IsInsert Then
                If LogErrorsOnly = False Then ClassLogger.Add(">> (SaveRecord) Insert", False)

                ' Den Record erstellen
                If CreateRecord(FormID) = False Then
                    IsInsert = False
                    Return "ERROR - INSERT RECORD NOT SUCCESSFUL"
                End If

                ' Die eben erstellte RecordID holen
                RECORD_ID = GetLastRecord()
                CURRENT_RECORD_ID = RECORD_ID
                ' Wenn gegeben, foreignrecordID mit Record verknüpfen
                If foreignRecordID > 0 Then
                    If LogErrorsOnly = False Then ClassLogger.Add(">> foreignRecordID:  " & foreignRecordID & "; Record-ID: " & RECORD_ID, False)
                    ConnectRecord(foreignRecordID, RECORD_ID)
                End If

                ' Für angegebene Control Typen den Wert speichern
                InsertAllControls(FormID, RECORD_ID, _CtrlBuilder.AllControls)

                ' Status zurücksetzen
                IsInsert = False

                NEW_RECORD_ID = RECORD_ID

                Return "Neuer Datensatz eingefügt - " & Now
            ElseIf IsInsert = False Then
                If LogErrorsOnly = False Then ClassLogger.Add(">> (SaveRecord) Update RecordID: " & RECORD_ID, False)
                UpdateAllControls(FormID, RecordID, _CtrlBuilder.AllControls)

                Return "Datensatz aktualisiert - " & Now
            End If
        Catch ex As Exception
            MsgBox("Unexpected Error in SaveRecord: " & ex.Message, MsgBoxStyle.Critical)
        End Try
      
    End Function

    Private Sub InsertAllControls(FormID As Integer, RecordID As Integer, controls As Control.ControlCollection)
        For Each ctrl As Control In controls
            Dim CONTROL_ID As Integer = DirectCast(ctrl.Tag, ClassControlMetadata).Id 'GetControlID_for_Name(ctrl.Name, FormID)
            Dim CONTROL_VALUE As String = Nothing

            If TypeOf ctrl Is PictureBox Then
                'Dim id As Integer = GetControlID_for_Name(ctrl.Name, FormID)
                UpsertImage(CONTROL_ID, RecordID, ctrl.BackgroundImage)
                Continue For
            End If

            ' Control existiert
            If CONTROL_ID <> -1 Then
                CONTROL_VALUE = GetControlValue(ctrl)
            End If
            'If TypeName(ctrl).ToString = "DateEdit" Then
            '    CONTROL_VALUE = CDate(CONTROL_VALUE)
            'End If
            'If CONTROL_ID = 489 Then
            '    Console.WriteLine(TypeName(ctrl))
            'End If
            ' Kein Bekanntes Control oder Groupbox
            If IsNothing(CONTROL_VALUE) Then
                If TypeOf ctrl Is GroupBox Then
                    InsertAllControls(FormID, RecordID, DirectCast(ctrl, GroupBox).Controls)
                End If
            Else
                InsertControlValue(CONTROL_ID, RecordID, CONTROL_VALUE)
            End If
        Next
    End Sub

    Private Sub UpsertImage(ControlID As Integer, RecordID As Integer, image As Bitmap)
        Dim existsSQL As String = "SELECT GUID FROM TBPMO_CONTROL_IMAGE WHERE CONTROL_ID = " & ControlID & " AND RECORD_ID = " & RecordID
        Dim exists = ClassDatabase.Execute_Scalar(existsSQL)

        If IsNothing(exists) Then
            InsertImage(ControlID, RecordID, image)
        Else
            UpdateImage(ControlID, RecordID, image)
        End If
    End Sub

    Private Sub InsertImage(ControlID As Integer, RecordID As Integer, image As Bitmap)
        Try
            Dim bimage() As Byte
            Dim SQL As String = "INSERT INTO TBPMO_CONTROL_IMAGE (CONTROL_ID, RECORD_ID, IMG, ADDED_WHO) VALUES (@CONTROL_ID, @RECORD_ID, @IMG, @ADDED_WHO)"
            Dim conn As New SqlClient.SqlConnection(MyConnectionString)
            Dim cmd As New SqlClient.SqlCommand(SQL, conn)

            If IsNothing(image) Then
                DeleteImage(ControlID, RecordID)
                Exit Sub
            End If

            bimage = BitmapToByteArray(image)

            cmd.Parameters.Add("@CONTROL_ID", SqlDbType.Int).Value = ControlID
            cmd.Parameters.Add("@RECORD_ID", SqlDbType.Int).Value = RecordID
            cmd.Parameters.Add("@RECORDID", SqlDbType.Int).Value = RecordID
            cmd.Parameters.Add("@IMG", SqlDbType.VarBinary).Value = bimage
            cmd.Parameters.Add("@ADDED_WHO", SqlDbType.VarChar).Value = Environment.UserName

            conn.Open()
            cmd.ExecuteNonQuery()
            conn.Close()

            LinkImage(ControlID, RecordID)
        Catch ex As Exception
            MsgBox("Error in InsertImage: ", ex.Message, vbCritical)
        End Try
    End Sub

    Private Sub LinkImage(ControlID As Integer, RecordID As Integer)
        Try
            Dim SQL = String.Format("SELECT GUID FROM TBPMO_CONTROL_IMAGE WHERE CONTROL_ID = {0} AND RECORD_ID = {1}", ControlID, RecordID)
            Dim ImageID As Integer = ClassDatabase.Execute_Scalar(SQL)

            SQL = String.Format("SELECT GUID FROM TBPMO_CONTROL_VALUE WHERE CONTROL_ID = {0} AND RECORD_ID = {1}", ControlID, RecordID)
            Dim valueExists = ClassDatabase.Execute_Scalar(SQL)

            Dim VALUE = "%%" & ImageID.ToString & "%%"

            If valueExists Then
                SQL = String.Format("UPDATE TBPMO_CONTROL_VALUE SET VALUE = '{0}' WHERE CONTROL_ID = {1} AND RECORD_ID = {2}", VALUE, ControlID, RecordID)
            Else
                SQL = String.Format("INSERT INTO TBPMO_CONTROL_VALUE (RECORD_ID, CONTROL_ID, VALUE, ADDED_WHO) VALUES ({0}, {1}, '{2}', '{3}')", RecordID, ControlID, VALUE, Environment.UserName)
            End If

            ClassDatabase.Execute_non_Query(SQL)
        Catch ex As Exception
            MsgBox("Error in LinkImage: " & vbNewLine & ex.Message)
        End Try
    End Sub

    Private Sub UpdateImage(ControlID As Integer, RecordID As Integer, image As Bitmap)
        Try
            Dim bimage() As Byte
            Dim SQL As String = "UPDATE TBPMO_CONTROL_IMAGE SET IMG = @IMG, CHANGED_WHO = @CHANGED_WHO WHERE CONTROL_ID = @CONTROL_ID AND RECORD_ID = @RECORD_ID"
            Dim conn As New SqlClient.SqlConnection(MyConnectionString)
            Dim cmd As New SqlClient.SqlCommand(SQL, conn)

            If IsNothing(image) Then
                DeleteImage(ControlID, RecordID)
                Exit Sub
            End If

            bimage = BitmapToByteArray(image)

            cmd.Parameters.Add("@CONTROL_ID", SqlDbType.Int).Value = ControlID
            cmd.Parameters.Add("@RECORD_ID", SqlDbType.Int).Value = RecordID
            cmd.Parameters.Add("@RECORDID", SqlDbType.Int).Value = RecordID
            cmd.Parameters.Add("@IMG", SqlDbType.VarBinary).Value = bimage
            cmd.Parameters.Add("@CHANGED_WHO", SqlDbType.VarChar).Value = Environment.UserName

            conn.Open()
            cmd.ExecuteNonQuery()
            conn.Close()

            LinkImage(ControlID, RecordID)
        Catch ex As Exception
            MsgBox("Error in UpdateImage: ", ex.Message, vbCritical)
        End Try
    End Sub


    Private Sub DeleteImage(ControlID As Integer, RecordID As Integer)
        Try
            ' Delete Image
            Dim SQL = String.Format("DELETE FROM TBPMO_CONTROL_IMAGE WHERE CONTROL_ID = {0} AND RECORD_ID = {1}", ControlID, RecordID)
            Dim result = ClassDatabase.Execute_non_Query(SQL)

            ' Delete Value
            SQL = String.Format("DELETE FROM TBPMO_CONTROL_VALUE WHERE CONTROL_ID = {0} AND RECORD_ID = {1}", ControlID, RecordID)
            result = ClassDatabase.Execute_non_Query(SQL)
        Catch ex As Exception
            MsgBox("Fehler beim löschen des Bildes:" & vbNewLine & ex.Message, MsgBoxStyle.Critical)
        End Try
    End Sub

    Private Sub UpdateAllControls(FormID As Integer, RecordID As Integer, controls As Control.ControlCollection)
        Try
            For Each ctrl As Control In controls
                Dim CONTROL_ID As Integer = DirectCast(ctrl.Tag, ClassControlMetadata).Id 'GetControlID_for_RecordID(ctrl.Name, RecordID)
                If LogErrorsOnly = False Then ClassLogger.Add(">> CONTROL_ID: " & CONTROL_ID, False)
                Dim CONTROL_VALUE As String = GetControlValue(ctrl)

                If TypeOf ctrl Is PictureBox Then
                    Dim id As Integer = DirectCast(ctrl.Tag, ClassControlMetadata).Id 'GetControlID_for_Name(ctrl.Name, FormID)
                    UpsertImage(id, RecordID, ctrl.BackgroundImage)
                    Continue For
                End If

                If TypeOf ctrl Is GroupBox Then
                    Dim ctrls As Control.ControlCollection = DirectCast(ctrl, GroupBox).Controls
                    UpdateAllControls(FormID, RecordID, ctrls)
                    Continue For
                End If

                If TypeOf ctrl Is DevExpress.XtraEditors.CheckedListBoxControl Then
                    Dim id As Integer = DirectCast(ctrl.Tag, ClassControlMetadata).Id
                    UpdateMultipleValues(id, RecordID, CONTROL_VALUE)
                    Continue For
                End If

                If TypeOf ctrl Is Windows.Forms.DataGridView Then
                    Dim id As Integer = DirectCast(ctrl.Tag, ClassControlMetadata).Id
                    UpdateMultipleValues(id, RecordID, CONTROL_VALUE)
                    Continue For
                End If

                Dim ValueExists = ClassDatabase.Execute_Scalar(String.Format("SELECT RECORD_ID FROM VWPMO_VALUES WHERE RECORD_ID = {0} AND CONTROL_ID = {1}", RecordID, CONTROL_ID))

                If ValueExists Then ' Control Updaten
                    UpdateControlValue(CONTROL_ID, RecordID, CONTROL_VALUE)
                Else ' Neues Control
                    If LogErrorsOnly = False Then ClassLogger.Add(">> InsertControlValue: " & CONTROL_ID & "|" & RecordID & "|" & CONTROL_VALUE, False)
                    InsertControlValue(CONTROL_ID, RecordID, CONTROL_VALUE)
                End If
            Next
        Catch ex As Exception
            MsgBox("Unexpected Error in UpdateAllControls: " & vbNewLine & ex.Message, MsgBoxStyle.Critical)
        End Try
    
    End Sub

    Public Sub UpdateMultipleValues(ControlId As Integer, RecordId As Integer, value As String)
        Try
            Dim values As New List(Of String)(value.Split(";"))
            Dim dt As DataTable = ClassDatabase.Return_Datatable(String.Format("SELECT VALUE FROM TBPMO_CONTROL_VALUE WHERE CONTROL_ID = {0} AND RECORD_ID = {1}", ControlId, RecordId))
            ' Konvertiere datatable zu liste
            Dim oldValues = dt.AsEnumerable().Select(Of String)(Function(r)
                                                                    Return r.Item("VALUE")
                                                                End Function).ToList()

            Dim AddValues = values.Except(oldValues)
            Dim RemoveValues = oldValues.Except(values)

            For Each v As String In AddValues
                ClassDatabase.Execute_non_Query(String.Format("INSERT INTO TBPMO_CONTROL_VALUE (CONTROL_ID, RECORD_ID, VALUE) VALUES({0}, {1}, '{2}')", ControlId, RecordId, v))
            Next

            For Each v As String In RemoveValues
                ClassDatabase.Execute_non_Query(String.Format("DELETE FROM TBPMO_CONTROL_VALUE WHERE CONTROL_ID = {0} AND RECORD_ID = {1} AND VALUE = '{2}'", ControlId, RecordId, v))
            Next

        Catch ex As Exception
            MsgBox("Error in UpdateMultipleValues:" & vbNewLine & ex.Message)
        End Try
    End Sub

    Function GetControlValue(ctrl As Control) As String

        Dim type = ctrl.GetType().Name
        Dim CONTROL_ID As Integer = DirectCast(ctrl.Tag, ClassControlMetadata).Id ' GetControlID_for_RecordID(ctrl.Name, CURRENT_RECORD_ID)
        If LogErrorsOnly = False Then ClassLogger.Add(">> GetControlValue CONTROL_ID: " & CONTROL_ID, False)
        Dim CONTROL_VALUE As String = Nothing
        If LogErrorsOnly = False Then ClassLogger.Add(">> type = " & type.ToString, False)
        Select Case type
            Case "TextBox"
                Return DirectCast(ctrl, TextBox).Text
            Case "ComboBox"
                If LogErrorsOnly = False Then ClassLogger.Add(">> Return Value: " & DirectCast(ctrl, ComboBox).Text, False)
                Return DirectCast(ctrl, ComboBox).Text
            Case "CheckBox"
                Return DirectCast(ctrl, CheckBox).Checked.ToString()
            Case "RadioButton"
                Return DirectCast(ctrl, RadioButton).Checked.ToString()
            Case "DateEdit"
                Dim Value = DirectCast(ctrl, DevExpress.XtraEditors.DateEdit).EditValue

                If IsDBNull(Value) Then
                    Return ""
                Else
                    Return DirectCast(ctrl, DevExpress.XtraEditors.DateEdit).DateTime.ToString("yyyy-MM-dd")
                End If
            Case "PictureBox"
                'Return "PictureBox" 'Es ist egal was für ein String hier zurückgegeben wird, hauptsache nicht Nothing
            Case "CheckedListBoxControl"
                Dim chklbx As DevExpress.XtraEditors.CheckedListBoxControl
                chklbx = DirectCast(ctrl, DevExpress.XtraEditors.CheckedListBoxControl)

                'TODO: Wenn keine Datasource vorhanden, angecheckte einträge als string speichern
                If IsNothing(chklbx.DataSource) Then
                    Dim result As New List(Of String)
                    Dim result_string As String

                    For Each item As DevExpress.XtraEditors.Controls.CheckedListBoxItem In chklbx.CheckedItems
                        result.Add(item.Value.ToString.Trim)
                    Next

                    result_string = String.Join(";", result)

                    ' Hier wird ein String zurückgegeben, der als VALUE gespeichert werden soll
                    ' Überspringt den Rest der funktion
                    Return result_string
                End If

                'Alle Recorddatensätze durchlaufen und überprüfen ob nicht angehakt
                'Wenn nicht angehakt dann Record löschen
                Dim index As Integer = 0
                For i As Integer = 0 To chklbx.ItemCount - 1
                    Dim item = chklbx.GetItem(i)
                    Dim row As DataRowView = CType(item, DataRowView)
                    If chklbx.GetItemCheckState(i) = 0 Then
                        If CInt(row(0)) > 0 Then
                            'Überprüfen ob es den Record gibt
                            Dim SQL = "SELECT COUNT(*) FROM TBPMO_RECORD_CONNECT WHERE RECORD1_ID = " & CURRENT_RECORD_ID & " AND RECORD2_ID = " & CInt(row(0))
                            If ClassDatabase.Execute_Scalar(SQL) = 1 Then
                                SQL = "DELETE FROM TBPMO_RECORD_CONNECT WHERE RECORD1_ID = " & CURRENT_RECORD_ID & " AND RECORD2_ID = " & CInt(row(0))
                                If ClassDatabase.Execute_non_Query(SQL) = True Then
                                    If LogErrorsOnly = False Then ClassLogger.Add(">> TBPMO_RECORD_CONNECT-Entry after 'deselect CheckedListBox' deleted", False)
                                End If
                            End If
                        End If
                    End If
                Next

                'Für jeden gecheckten Eintrag den Record der Stammentität mit dem selektierten linken
                Dim checked_result As New List(Of String)
                Dim checked_result_string As String

                For Each item As Object In DirectCast(ctrl, DevExpress.XtraEditors.CheckedListBoxControl).CheckedItems
                    Dim row As DataRowView = CType(item, DataRowView)
                    Try
                        If CInt(row(0)) > 0 Then
                            Dim rid = CInt(row(0))
                            Dim checked_value = row(1)
                            checked_result.Add(checked_value)
                            checked_result_string = String.Join(";", checked_result)
                            Dim SQL = "SELECT COUNT(*) FROM TBPMO_RECORD_CONNECT WHERE RECORD1_ID = " & CURRENT_RECORD_ID & " AND RECORD2_ID = " & CInt(row(0))
                            If ClassDatabase.Execute_Scalar(SQL) = 0 Then
                                If CURRENT_RECORD_ID = 0 Then
                                    MsgBox("Attention: no current record Selected!", MsgBoxStyle.Exclamation)
                                Else
                                    If ConnectRecord(CURRENT_RECORD_ID, CInt(row(0)), "CheckedListBox;" & ctrl.Name) = True Then
                                        If LogErrorsOnly = False Then ClassLogger.Add(">> Checked ListBox record  '" & rid.ToString & "' was linked successfully.", False)
                                    End If
                                End If

                            End If
                        End If
                    Catch ex As Exception
                        ClassLogger.Add("Error in CheckedListBoxGetControlValue: " & ex.Message, True)
                    End Try

                Next
                ' Hier wird ein String zurückgegeben, der als VALUE gespeichert werden soll
                ' Überspringt den Rest der funktion
                If Not IsNothing(checked_result_string) Then
                    Dim sql = String.Format("select count(*) from TBPMO_CONTROL_VALUE where CONTROL_ID = {0} and RECORD_ID = {1}", CONTROL_ID, CURRENT_RECORD_ID)
                    If ClassDatabase.Execute_Scalar(sql) = 0 Then
                        InsertControlValue(CONTROL_ID, CURRENT_RECORD_ID, "")
                    End If
                    Return checked_result_string
                Else
                    'In jedem Fall Nothing zurückgeben
                    Return Nothing
                End If


            Case "ListBoxControl"
                Dim listbox As DevExpress.XtraEditors.ListBoxControl = DirectCast(ctrl, DevExpress.XtraEditors.ListBoxControl)
                Return listbox.SelectedValue

            Case "DataGridView"
                Dim list As New List(Of String)
                Dim dgv As DataGridView = DirectCast(ctrl, DataGridView)

                For Each row As DataGridViewRow In dgv.Rows
                    Dim cell As DataGridViewCell = row.Cells(0)
                    If Not IsNothing(cell.Value) Then
                        list.Add(cell.Value)
                    End If
                Next

                Return String.Join(";", list)

            Case Else
                Return Nothing
        End Select
    End Function

    Public Shared Function InsertControlValue(ControlID As Integer, RecordID As Integer, Value As String)
        Try
            Dim AddedWho = Environment.UserName
            Dim FORMAT_TYPE As String = ClassDatabase.Execute_Scalar("SELECT FORMAT_TYPE FROM TBPMO_CONTROL WHERE GUID = " & ControlID)

            Select Case FORMAT_TYPE
                Case "Currency"
                    If Not Value = String.Empty Then
                        Value = Decimal.Parse(Value, Globalization.NumberStyles.Currency).ToString
                    End If

                Case "Decimal"
                    If Not Value = String.Empty Then
                        Value = Decimal.Parse(Value, Globalization.NumberStyles.Integer)
                    End If

            End Select

            Using conn As New SqlClient.SqlConnection(MyConnectionString)
                Dim cmd As New SqlClient.SqlCommand("INSERT INTO TBPMO_CONTROL_VALUE (CONTROL_ID, RECORD_ID, VALUE, ADDED_WHO) VALUES (@CONTROL_ID, @RECORD_ID, @VALUE, @ADDED_WHO)", conn)
                cmd.Parameters.Add("@VALUE", SqlDbType.NVarChar).Value = Value
                cmd.Parameters.Add("@ADDED_WHO", SqlDbType.VarChar).Value = AddedWho
                cmd.Parameters.Add("@CONTROL_ID", SqlDbType.Int).Value = ControlID
                cmd.Parameters.Add("@RECORD_ID", SqlDbType.Int).Value = RecordID

                conn.Open()
                cmd.ExecuteNonQuery()
                Return True
            End Using

            'Dim SQL = "INSERT INTO TBPMO_CONTROL_VALUE (CONTROL_ID, RECORD_ID, VALUE, ADDED_WHO) VALUES (" & ControlID & ", " & RecordID & ", '" & Value & "', '" & AddedWho & "')"
            'Return ClassDatabase.Execute_non_Query(SQL, True)
        Catch ex As Exception
            ClassLogger.Add("Unerwarteter Fehler in InsertControlValue: " & ex.Message, True)
            Return False
        End Try
    End Function

    Public Shared Function UpdateControlValue(ControlID As Integer, RecordID As Integer, Value As String)
        Try
            Dim CHANGED_WHO = Environment.UserName
            Dim FORMAT_TYPE As String = ClassDatabase.Execute_Scalar("SELECT FORMAT_TYPE FROM TBPMO_CONTROL WHERE GUID = " & ControlID)

            If Not Value = String.Empty Then
                Select Case FORMAT_TYPE
                    Case "Currency"
                        Value = Decimal.Parse(Value, Globalization.NumberStyles.Currency).ToString
                    Case "Decimal"
                        Value = Decimal.Parse(Value, Globalization.NumberStyles.Integer)
                End Select
            End If

            Using conn As New SqlClient.SqlConnection(MyConnectionString)
                Dim cmd As New SqlClient.SqlCommand("UPDATE TBPMO_CONTROL_VALUE SET VALUE = @VALUE, CHANGED_WHO = @CHANGED_WHO WHERE CONTROL_ID = @CONTROL_ID AND RECORD_ID = @RECORD_ID", conn)
                cmd.Parameters.Add("@VALUE", SqlDbType.NVarChar).Value = Value
                cmd.Parameters.Add("@CHANGED_WHO", SqlDbType.VarChar).Value = CHANGED_WHO
                cmd.Parameters.Add("@CONTROL_ID", SqlDbType.Int).Value = ControlID
                cmd.Parameters.Add("@RECORD_ID", SqlDbType.Int).Value = RecordID

                conn.Open()
                cmd.ExecuteNonQuery()
                Return True
            End Using

        Catch ex As Exception
            ClassLogger.Add("Unerwarteter Fehler in UpdateControlValue: " & ex.Message, True)
            Return False
        End Try
    End Function

    Public Shared Function CreateRecord(FormID)
        Dim ADDED_WHO As String = Environment.UserName
        Dim SQL = "INSERT INTO TBPMO_RECORD(ADDED_WHO, FORM_ID,RECORD_ENTITY_ID) VALUES ('" & ADDED_WHO & "', " & FormID & ",4711)"
        Return ClassDatabase.Execute_non_Query(SQL, True)
    End Function

    Public Shared Function GetLastRecord()
        Dim ADDED_WHO As String = Environment.UserName
        Dim SQL = "SELECT (MAX(GUID)) FROM TBPMO_RECORD where ADDED_WHO = '" & ADDED_WHO & "'"
        Return ClassDatabase.Execute_Scalar(SQL, True)
    End Function

    Public Shared Function ConnectRecord(PARENT_RECORD As Integer, LINK_RECORD As Integer, Optional Comment As String = "")
        Dim ADDED_WHO As String = Environment.UserName
        Dim SQL = "INSERT INTO TBPMO_RECORD_CONNECT(RECORD1_ID,RECORD2_ID,COMMENT,ADDED_WHO) VALUES (" & PARENT_RECORD & "," & LINK_RECORD & ",'" & Comment & "','" & ADDED_WHO & "')"
        If LogErrorsOnly = False Then ClassLogger.Add(">> ConnectRecord SQL:  " & SQL, False)
        Return ClassDatabase.Execute_non_Query(SQL, True)
    End Function
End Class
