Imports System.IO
Imports System.Text.Encoding
Imports taskFLOW.Controls
Imports DevExpress.XtraBars
Imports DevExpress.XtraEditors
Imports DevExpress.XtraLayout
Imports DevExpress.XtraLayout.Customization
Imports DevExpress.XtraLayout.Dragging
Imports DevExpress.XtraLayout.HitInfo
Imports DevExpress.XtraToolbox

Public Class frmDesignerLayout
    Private SelectedLayoutId As Integer = 0
    Private FormsDatatable As DataTable
    Private _ControlLoader As ControlLoader

#Region "Drag Helper"
    Private _DragItem As BaseLayoutItem
    Private _Window As DragFrameWindow
    Private _DragController As LayoutItemDragController = Nothing
    Private _LayoutSerializer As LayoutControlSerializer = Nothing

    Protected ReadOnly Property DragFrameWindow As DragFrameWindow
        Get
            If _Window Is Nothing Then
                _Window = New DragFrameWindow(LayoutControlMain)
            End If
            Return _Window
        End Get
    End Property

    Private Sub ShowDragHelper()
        DragFrameWindow.Visible = True
    End Sub

    Private Sub HideDragHelper()
        DragFrameWindow.Reset()
        DragFrameWindow.Visible = False
    End Sub

    Private Sub UpdateDragHelper(p As Point)
        p = LayoutControlMain.PointToClient(p)
        _DragController = New LayoutItemDragController(_DragItem, LayoutControlMain.Root, New Point(p.X, p.Y))
        DragFrameWindow.DragController = _DragController
    End Sub
#End Region
#Region "Drag Drop Actions"
    Private Sub ToolboxControlMain_DragItemDrop(sender As Object, e As ToolboxDragItemDropEventArgs) Handles ToolboxControlMain.DragItemDrop
        Dim oPosition As Point = LayoutControlMain.PointToClient(MousePosition)
        Dim oHitInfo As BaseLayoutItemHitInfo = LayoutControlMain.CalcHitInfo(oPosition)
        Dim oLayoutControl As LayoutControlItem = DirectCast(_DragItem, LayoutControlItem)
        Dim oControlName As String = oLayoutControl.Tag & Guid.NewGuid().ToString().GetHashCode().ToString("x")
        Dim oControl As BaseEdit = _ControlLoader.CreateLayoutControl(oLayoutControl.Tag, oControlName, 0)

        If oLayoutControl IsNot Nothing Then
            HideDragHelper()
            oLayoutControl.Control = oControl
            oLayoutControl.Text = oControlName
            oLayoutControl.Name = "Container-" & oControlName


            If (_DragController IsNot Nothing AndAlso _DragItem IsNot Nothing) Then
                If (_DragItem.Owner Is Nothing OrElse _DragItem.Parent Is Nothing) Then
                    _DragController.DragWildItem()
                Else
                    _DragController.Drag()
                End If
                Focus()
            End If
            HideDragHelper()
            _DragItem = Nothing
        End If
    End Sub

    Private Sub ToolboxControlMain_DragItemStart(sender As Object, e As ToolboxDragItemStartEventArgs) Handles ToolboxControlMain.DragItemStart
        _DragItem = CreateLayoutControlItem(e.Item.Tag)
    End Sub

    Private Sub ToolboxControlMain_DragItemMove(sender As Object, e As DevExpress.XtraToolbox.ToolboxDragItemMoveEventArgs) Handles ToolboxControlMain.DragItemMove
        If (CType(LayoutControlMain, ILayoutControl)).EnableCustomizationMode OrElse Me.DesignMode Then Return
        Dim oFormPosition As Point = PointToClient(e.Location)
        Dim oLayoutPosition As Point = LayoutControlMain.PointToClient(e.Location)

        If LayoutControlMain.Bounds.Contains(oFormPosition) Then

            If Not DragFrameWindow.Visible Then
                DragFrameWindow.Visible = True
                Return
            End If

            UpdateDragHelper(e.Location)
        Else
            DragFrameWindow.Visible = False
        End If
    End Sub

    Private Function CreateLayoutControlItem(Id As String) As LayoutControlItem
        Return New LayoutControlItem() With {.Tag = Id}
    End Function
#End Region

    Private Sub frmDesignerLayout_Load(sender As Object, e As EventArgs) Handles Me.Load
        Try
            _ControlLoader = New ControlLoader(LOGCONFIG, LayoutControlGroupMain)
            _LayoutSerializer = New LayoutControlSerializer(LOGCONFIG)

            Dim oSQL = "Select * from TBIDB_LAYOUT_CONFIG"
            FormsDatatable = DatabaseFallback.GetDatatableIDB(oSQL)
            If Not IsNothing(FormsDatatable) Then
                For Each oRow As DataRow In FormsDatatable.Rows
                    Dim oItem As New BarButtonItem(RibbonControl1.Manager, oRow.Item("TITLE"))
                    oItem.Tag = oRow.Item("GUID")
                    AddHandler oItem.ItemClick, AddressOf Item_Click

                    BarListItem1.ItemLinks.Add(oItem)
                Next
            End If
        Catch ex As Exception
            MsgBox("Unexpected Error in FormLoad:" & ex.Message, MsgBoxStyle.Critical)
        End Try
    End Sub

    Private Sub Item_Click(sender As Object, e As ItemClickEventArgs)
        Try
            SelectedLayoutId = e.Item.Tag
            Dim oRow As DataRow = FormsDatatable.Select($"GUID = {SelectedLayoutId}").First()
            'Dim oXml = oRow.Item("XML_CONTENT")

            Dim oLayout As Byte() = System.Convert.FromBase64String(oRow.Item("XML_LAYOUT"))
            Dim oControls As Byte() = System.Convert.FromBase64String(oRow.Item("XML_CONTENT"))

            Using oLayoutStream As New MemoryStream(oLayout, False)
                Using oControlStream As New MemoryStream(oControls, False)
                    _LayoutSerializer.RestoreLayoutExFromStream(LayoutControlMain, oLayoutStream, oControlStream)
                End Using
            End Using
        Catch ex As Exception
            MsgBox("Unexpected Error in FormSave:" & ex.Message, MsgBoxStyle.Critical)
        End Try
    End Sub

    Private Sub BarButtonItem2_ItemClick(sender As Object, e As ItemClickEventArgs) Handles BarButtonItem2.ItemClick
        Using oLayoutStream As New MemoryStream()
            Using oControlStream As New MemoryStream()
                _LayoutSerializer.SaveLayoutExToStream(LayoutControlMain, oLayoutStream, oControlStream)

                Dim oLayout = System.Convert.ToBase64String(oLayoutStream.ToArray())
                Dim oControls = System.Convert.ToBase64String(oControlStream.ToArray())

                Dim oSql As String = $"UPDATE TBIDB_LAYOUT_CONFIG SET XML_CONTENT = '{oControls}', XML_LAYOUT = '{oLayout}', CHANGED_WHO = '{Environment.UserName}' WHERE GUID = {SelectedLayoutId}"

                DatabaseFallback.ExecuteNonQueryIDB(oSql)
            End Using
        End Using
    End Sub

    Private Sub BarButtonItem1_ItemClick(sender As Object, e As ItemClickEventArgs) Handles BarButtonItem1.ItemClick
        LayoutControlMain.ShowCustomizationForm()
    End Sub

    Private Sub LayoutControlMain_ItemSelectionChanged(sender As Object, e As EventArgs) Handles LayoutControlMain.ItemSelectionChanged
        ' only layout control items have properties
        If TypeOf sender IsNot LayoutControlItem Then
            Exit Sub
        End If

        Dim oLayoutItem As LayoutControlItem = DirectCast(sender, LayoutControlItem)
        Dim oSelectedControl As BaseEdit = oLayoutItem.Control
        Dim oMetadata As New Metadata

        ' Don't load properties for layout items like splitters, separators, etc.
        If oLayoutItem.Control Is Nothing Then
            Exit Sub
        End If

        Select Case oSelectedControl.GetType
            Case GetType(MemoEdit)
                PropertyGridMain.SelectedObject = New Properties.MemoeditProperties() With {
                    .Id = 0,
                    .Name = oSelectedControl.Name
                }
            Case GetType(TextEdit)
                PropertyGridMain.SelectedObject = New Properties.TextboxProperties() With {
                    .Id = 0,
                    .Name = oSelectedControl.Name
                }
            Case GetType(DateEdit)
                PropertyGridMain.SelectedObject = New Properties.DatepickerProperties() With {
                    .Id = 0,
                    .Name = oSelectedControl.Name
                }
            Case GetType(CheckEdit)
                PropertyGridMain.SelectedObject = New Properties.CheckboxProperties() With {
                    .Id = 0,
                    .Name = oSelectedControl.Name
                }
        End Select
    End Sub
End Class