Imports DevExpress.XtraBars.Docking
Imports DevExpress.XtraBars.Docking2010
Imports DevExpress.XtraBars.Docking2010.Views
Imports DevExpress.XtraBars.Docking2010.Views.Tabbed
Imports DevExpress.XtraGrid
Imports DigitalData.GUIs.ClientSuite.Base
Imports DigitalData.Modules.Logging

Public Class PanelManager
    Private _logger As Logger
    Private _logConfig As LogConfig

    Private _documentManager As DocumentManager
    Private _dockManager As DockManager
    Private _view As TabbedView

    Private _documents As New List(Of Document)

    Public Sub New(LogConfig As LogConfig, DocumentManager As DocumentManager, DockManager As DockManager)
        Try
            Dim oView = DocumentManager.View

            _logConfig = LogConfig
            _logger = LogConfig.GetLogger()

            _documentManager = DocumentManager
            _dockManager = DockManager
            _view = oView

            AddHandler oView.DocumentAdded, AddressOf View_DocumentAdded
            AddHandler oView.DocumentClosed, AddressOf View_DocumentClosed
            AddHandler oView.DocumentClosing, AddressOf View_DocumentClosing
            AddHandler oView.DocumentActivated, AddressOf View_DocumentActivated
            AddHandler oView.DocumentDeactivated, AddressOf View_DocumentDeactivated
        Catch ex As Exception
            _logger.Error(ex)
            Throw ex
        End Try
    End Sub

    Private Sub View_DocumentDeactivated(sender As Object, e As DocumentEventArgs)
        Dim oDocument As BaseDocument = e.Document

        ' TODO: oDocument.Control can be nothing
        If oDocument Is Nothing Then
            Exit Sub
        End If

        ' Maybe hide panels for this form
        For Each oPanel As DockPanel In _dockManager.Panels
            Dim oTag As Integer = oPanel.Tag

            If oTag = oDocument.Control.GetHashCode Then
                oPanel.Hide()
            End If
        Next
    End Sub

    Private Sub View_DocumentActivated(sender As Object, e As DocumentEventArgs)
        Dim oDocument As BaseDocument = e.Document
        Dim oHashcode As Integer = oDocument.Control.GetHashCode

        If oDocument Is Nothing Then
            Exit Sub
        End If

        ' Show Panels for this form
        For Each oPanel As DockPanel In _dockManager.Panels
            Dim oTag As Integer = oPanel.Tag

            If oTag = oHashcode Then
                oPanel.Show()
            End If
        Next
    End Sub

    Private Sub View_DocumentClosing(sender As Object, e As DocumentCancelEventArgs)
        Dim oDocument As BaseDocument = e.Document
        Dim oHashcode As Integer = oDocument.Control.GetHashCode

        If oDocument Is Nothing Then
            Exit Sub
        End If

        ' close all related panels. 
        For Each oPanel As DockPanel In _dockManager.Panels
            Dim oTag As Integer = oPanel.Tag

            If oTag = oHashcode Then
                oPanel.Close()
            End If
        Next
    End Sub

    Private Sub View_DocumentClosed(sender As Object, e As DocumentEventArgs)
        ' remove event handlers
        _documents.Remove(e.Document)
    End Sub

    Private Sub View_DocumentAdded(sender As Object, e As DocumentEventArgs)
        ' Only Ribbon Forms can have panels!
        If TypeOf e.Document.Control IsNot BaseRibbonForm Then
            Exit Sub
        End If

        ' Don't open panels for the same form twice!
        If _documents.Contains(e.Document) Then
            Exit Sub
        End If

        _documents.Add(e.Document)

        Dim oForm As BaseRibbonForm = e.Document.Control
        Dim oFormHash As Integer = oForm.GetHashCode
        Dim oInitialPanelInfo As List(Of PanelInfo) = oForm.GetInitialPanels()

        ' TODO: determine how much panels at most can be added
        ' check if initial panels should be loaded
        For Each oPanelInfo As PanelInfo In oInitialPanelInfo
            ' create the control
            Dim oControl As BasePanel = GetPanelControl(oPanelInfo, oFormHash)

            If oControl Is Nothing Then
                Dim oPanelType = oPanelInfo.PanelControl.GetType.ToString
                _logger.Warn("Unknown panel type {0}", oPanelType)
                Continue For
            End If

            ' create panel
            Dim oPanel = _dockManager.AddPanel(oPanelInfo.Position)

            ' configure panel
            oPanel.Options.ShowCloseButton = oPanelInfo.CanBeClosed
            oPanel.Options.ShowAutoHideButton = oPanelInfo.CanBePinned
            oPanel.Options.ShowMaximizeButton = oPanelInfo.CanBeMaximized
            oPanel.Options.AllowFloating = oPanelInfo.CanBeUndocked

            ' relation is defined through HashCode of form saved in Tag property of panel
            '
            ' Form                  Panel
            ' GetHashCode --------> Tag
            '
            oPanel.Tag = oFormHash
            oPanel.Text = oPanelInfo.Title
            oPanel.Controls.Add(oControl)
        Next

        ' TODO: establish communication channel to load panels on-demand
    End Sub

    Private Function GetPanelControl(PanelInfo As PanelInfo, FormHash As Integer) As BasePanel
        If TypeOf PanelInfo.PanelControl Is DocumentPanel Then
            Dim oPanelControl As DocumentPanel = DirectCast(PanelInfo.PanelControl, DocumentPanel)
            oPanelControl.Datasource = PanelInfo.Datasource
            oPanelControl.Dock = DockStyle.Fill

            Return oPanelControl
        Else
            Return Nothing
        End If
    End Function
End Class
