Imports System.Threading.Tasks
Imports DevExpress.LookAndFeel
Imports DevExpress.XtraSplashScreen
Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.Windows
Imports DigitalData.Modules.Messaging
Imports DigitalData.Modules.ZooFlow
Imports DigitalData.Modules.ZooFlow.Params
Imports DigitalData.GUIs.ZooFlow.OnFlowFormStateChangedEvent.FlowFormState
Imports DigitalData.Modules.ClipboardWatcher

Partial Public Class frmAdmin
    Private WithEvents FlowForm As frmFlowForm

    Private Init As ClassInit
    Private Loading As Boolean = True
    Private Logger As Logger = My.LogConfig.GetLogger
    Private MatchingProfiles As List(Of ProfileData)
    Private MatchTreeView As New TreeView

    Public Sub New()
        InitializeComponent()
    End Sub

    Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        ' === Initialization ===
        Init = New ClassInit(My.LogConfig, Me)
        AddHandler Init.Completed, AddressOf Init_Completed
        Init.InitializeApplication()

        ' === Show Splash Screen ===
        SplashScreenManager.ShowForm(Me, GetType(frmSplash), False, False)

        ' === Layout and Skin ===
        UserLookAndFeel.Default.SetSkinStyle(My.UIConfig.SkinName)

        ' === Register As Event Listener ===
        EventBus.Instance.Register(Me)
    End Sub

    Private Sub Init_Completed(sender As Object, e As EventArgs)
        ' === Initialization Complete ===
        Loading = False
        SplashScreenManager.CloseForm(False)

        ' === Setup Timers ===
        AddHandler TimerRefreshData.Tick, AddressOf TimerRefreshData_Tick
        TimerRefreshData.Enabled = True

        ' === Setup Flow Form ===
        FlowForm = New frmFlowForm(My.Application.ModulesActive)
        FlowForm.Location = My.UIConfig.FlowForm.Location
        FlowForm.Show()

        ' === Load Data ===
        RefreshData()
    End Sub

    Private Sub frmAdmin_Shown(sender As Object, e As EventArgs) Handles Me.Shown
        Visible = False
    End Sub

    Private Sub frmMain_FormClosed(sender As Object, e As FormClosedEventArgs)
        EventBus.Instance.Unregister(Me)
    End Sub

    Public Sub OnEvent(e As OnFlowFormInteractionEvent)
        Select Case e.Interaction
            Case OnFlowFormInteractionEvent.FlowFormInteraction.Click
                Dim oClipboardContents As String = Clipboard.GetText()
                Dim oEnvironment As New Environment() With {
                    .User = My.Application.User,
                    .Modules = My.Application.Modules,
                    .Database = My.Database,
                    .Settings = My.Application.Settings
                }
                Dim oParams As New ClipboardWatcherParams() With {
                    .MatchingProfiles = MatchingProfiles,
                    .MatchTreeView = MatchTreeView,
                    .ClipboardContents = oClipboardContents
                }
                Dim oForm As New frmMatch(My.LogConfig, oEnvironment, oParams)
                oForm.Show()
        End Select
    End Sub

    Private Sub TimerRefreshData_Tick(sender As Object, e As EventArgs)
        RefreshData()
    End Sub

    Private Async Sub FlowForm_ClipboardChanged(sender As Object, e As IDataObject) Handles FlowForm.ClipboardChanged
        If My.Application.ClipboardWatcher.UserProfiles.Rows.Count = 0 Then
            Logger.Warn("Clipboard Changed but no profiles configured!")
            Exit Sub
        End If

        Dim oProfileFilter As ProfileFilter
        Dim oMatchingProfiles As List(Of ProfileData)
        Dim oWindow As New Window(My.LogConfig)
        Dim oWindowInfo = oWindow.GetWindowInfo()
        Dim oClipboardContents As String = Clipboard.GetText()
        Dim oUserState = My.Application.User

        Try
            oProfileFilter = New ProfileFilter(My.LogConfig,
                                               My.Application.ClipboardWatcher.UserProfiles,
                                               My.Application.ClipboardWatcher.ProfileProcesses,
                                               My.Application.ClipboardWatcher.ProfileWindows,
                                               My.Application.ClipboardWatcher.ProfileControls,
                                               MatchTreeView)

            oMatchingProfiles = oProfileFilter.Profiles
            oMatchingProfiles = oProfileFilter.FilterProfilesByClipboardRegex(oMatchingProfiles, oClipboardContents)
            oMatchingProfiles = oProfileFilter.FilterProfilesByProcess(oMatchingProfiles, oWindowInfo.ProcessName)
            oMatchingProfiles = oProfileFilter.FilterWindowsByWindowTitleRegex(oMatchingProfiles, oWindowInfo.WindowTitle)
            oMatchingProfiles = oProfileFilter.FilterProfilesByFocusedControl(oMatchingProfiles, oClipboardContents, Handle)
            oMatchingProfiles = Await Task.Run(Function()
                                                   Return oProfileFilter.FilterProfilesBySearchResults(
                                                        oMatchingProfiles,
                                                        My.Database,
                                                        oUserState,
                                                        oClipboardContents)
                                               End Function)
            oMatchingProfiles = oProfileFilter.ClearNotMatchedProfiles(oMatchingProfiles)
        Catch ex As Exception
            MsgBox("Fehler beim Laden der Profile. Möglicherweise liegt ein Konfigurationsfehler vor." & vbNewLine & vbNewLine & ex.Message, MsgBoxStyle.Critical, Text)
            Exit Sub
        End Try

        'If oMatchingProfiles.Count = 0 Then
        '    Logger.Warn("No matching Profiles found")
        '    Exit Sub
        'End If

        MatchingProfiles = oMatchingProfiles

        EventBus.Instance.PostEvent(New OnFlowFormStateChangedEvent(HasSearchResults))
    End Sub

#Region "Notify Icon Menu"
    Private Sub BeendenToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles BeendenToolStripMenuItem.Click
        Application.Exit()
    End Sub

    Private Sub NotifyIconMain_DoubleClick(sender As Object, e As EventArgs) Handles NotifyIconMain.DoubleClick
        ToggleVisibility()
    End Sub

    Private Sub AnzeigenVersteckenToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles AnzeigenVersteckenToolStripMenuItem.Click
        ToggleVisibility()
    End Sub




#End Region

    Private Sub ToggleVisibility()
        If Visible Then
            Hide()
        Else
            Show()
            BringToFront()
        End If
    End Sub

    Private Sub ButtonSettings_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles ButtonSettings.ItemClick
        frmSettings.ShowDialog()
    End Sub

    Private Sub frmMain_StyleChanged(sender As Object, e As EventArgs) Handles Me.StyleChanged
        If Loading = False Then
            My.UIConfig.SkinName = LookAndFeel.ActiveSkinName
            My.UIConfigManager.Save()
        End If
    End Sub

    Public Sub RefreshData()
        Try
            Dim oUserId As Integer = My.Application.User.UserId
            Dim oSql As String = My.Queries.ClipboardWatcher.VWCW_USER_PROFILE(oUserId)
            My.Application.ClipboardWatcher.UserProfiles = My.Database.GetDatatable(oSql)

            If My.Application.ClipboardWatcher.UserProfiles.Rows.Count = 0 Then
                MsgBox("No profiles configured for this user so far!", MsgBoxStyle.Exclamation)
            Else
                oSql = My.Queries.ClipboardWatcher.TBCW_PROFILE_PROCESS(oUserId)
                My.Application.ClipboardWatcher.ProfileProcesses = My.Database.GetDatatable(oSql)

                oSql = My.Queries.ClipboardWatcher.VWCW_PROFILE_REL_WINDOW(oUserId)
                My.Application.ClipboardWatcher.ProfileWindows = My.Database.GetDatatable(oSql)

                oSql = My.Queries.ClipboardWatcher.VWCW_PROFILE_REL_CONTROL(oUserId)
                My.Application.ClipboardWatcher.ProfileControls = My.Database.GetDatatable(oSql)
            End If
        Catch ex As Exception
            Logger.Error(ex)
        End Try
    End Sub


End Class
