Imports System.Threading
Imports System.IO
Imports System.Globalization
Imports DD_Clipboard_Watcher.ClassConstants
Imports DD_Clipboard_Watcher.ClassWindowAPI
Imports DigitalData.Modules.ZooFlow
Imports DigitalData.GUIs.ClipboardWatcher

Public Class frmStart
    Private WithEvents Hotkey As New ClassHotkey(Me)
    'Private WithEvents _Watcher As ClipboardWatcher = ClipboardWatcher.Singleton
    Private WithEvents _Watcher2 As ClassClipboardWatcher = ClassClipboardWatcher.Singleton
    Private _MatchForm As frmMatch = Nothing

    Public Sub New()
        ' Dieser Aufruf ist für den Designer erforderlich.
        InitializeComponent()

        ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu.
        Dim splash As New frmSplash()
        splash.ShowDialog()
        If ERROR_INIT <> "INVALID USER" Then
            Dim cultureInfo As New CultureInfo(USER_LANGUAGE)
            Thread.CurrentThread.CurrentCulture = cultureInfo
            Thread.CurrentThread.CurrentUICulture = cultureInfo
            CultureInfo.DefaultThreadCurrentCulture = cultureInfo
            CultureInfo.DefaultThreadCurrentUICulture = cultureInfo
        End If
    End Sub

    Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles Me.Load
        ClassWindowLocation.LoadFormLocationSize(Me)
        If ERROR_INIT = "FAILED DBCONNECTION" Or ERROR_INIT = "DATABASE" Then
            frmConfig_Basic.ShowDialog()
        End If

        If Database.DBInitialized = True Then
            If ERROR_INIT <> "" Then
                If ERROR_INIT = "NO CLIENT" Then
                    MsgBox("You are not related to a client!" & vbNewLine & "Please contact the system administrator!", MsgBoxStyle.Exclamation)
                Else
                    MsgBox("Sorry Something went wrong in user configuration!" & vbNewLine & "Reason: " & ERROR_INIT & vbNewLine & "Please contact the system administrator!", MsgBoxStyle.Exclamation)
                End If
                Exit Sub
            End If
            NotifyIconMain.Visible = True
            ClassInit.Refresh_Profile_Links()
            ClassInit.Refresh_Connections()
            Hotkey.AddHotKey(Keys.T, ClassHotkey.ModfierKey.MOD_CONTROL, HOTKEY_TOGGLE_WATCHER)
            Dim oKeyCode As Keys
            Dim oConverter As New KeysConverter
            Dim oObject As Object = oConverter.ConvertFromString(HotkeySearchKey.ToUpper)
            oKeyCode = CType(oObject, Keys)

            If HotkeyFunctionKey = HOTKEY_CTRL Then
                Hotkey.AddHotKey(oKeyCode, ClassHotkey.ModfierKey.MOD_CONTROL, ClassConstants.HOTKEY_TRIGGER_WATCHER)
            ElseIf HotkeyFunctionKey = HOTKEY_SHIFT Then
                Hotkey.AddHotKey(oKeyCode, ClassHotkey.ModfierKey.MOD_SHIFT, ClassConstants.HOTKEY_TRIGGER_WATCHER)
            End If

        End If

        RefreshUI()
    End Sub

    Private Sub frmMain_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
        Logger.Info(">> Logout time: " & Now.ToString, False)
        If ERROR_INIT = "INVALID USER" Or ERROR_INIT = "NO CLIENT" Then
            Exit Sub
        End If
        Try
            Dim sql = "DELETE FROM TBDD_USER_MODULE_LOG_IN WHERE USER_ID = " & USER_ID & " AND UPPER(MODULE) = UPPER('Clipboard-Watcher')"
            Database.ExecuteNonQuery(sql)
            ClassWindowLocation.SaveFormLocationSize(Me, "")
            My.Settings.Save()
        Catch ex As Exception

        End Try
        Try
            Hotkey.RemoveHotKey(HOTKEY_TOGGLE_WATCHER)
            Hotkey.RemoveHotKey(HOTKEY_TRIGGER_WATCHER)
        Catch ex As Exception
            Logger.Error(ex)
            Logger.Warn("Hotkeys could not be removed")
        End Try

        'TempDateien löschen
        For Each oFile In TEMP_FILES
            Try
                File.Delete(oFile)
            Catch ex As Exception
                Logger.Warn("Temp file {0} could not be deleted", oFile)
                Logger.Error(ex)
            End Try
        Next
    End Sub

    Private Sub frmClipboardWatch_Disposed(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Disposed
        _Watcher2.Dispose()
    End Sub

    Private Sub WatcherChanged_New(ByVal sender As Object, ByVal e As String) Handles _Watcher2.Changed
        If MONITORING_ACTIVE = False Then
            Logger.Info("Clipboard Watcher is inactive!")
            'NotifyIconMain.ShowBalloonTip(20000, "Clipboard Watcher", "Clipboard-watcher is inactive.", ToolTipIcon.Info)
            Exit Sub
        End If

        If DT_USER_PROFILES Is Nothing OrElse DT_USER_PROFILES.Rows.Count = 0 Then
            Logger.Warn("DT_USER_PROFILES is empty!")
            Exit Sub
        End If

        If DTPROFILE_REL_PROCESS Is Nothing OrElse DTPROFILE_REL_PROCESS.Rows.Count = 0 Then
            Logger.Warn("DTPROFILE_REL_PROCESS is empty!")
            Exit Sub
        End If

        If DTPROFILE_REL_WINDOW Is Nothing Then
            Logger.Warn("DTPROFILE_REL_WINDOW is empty!")
            Exit Sub
        End If

        If DTPROFILE_REL_CONTROL Is Nothing Then
            Logger.Warn("DTPROFILE_REL_CONTROL is empty!")
            Exit Sub
        End If

        Dim oWindowInfo = GetWindowInfo()
        Dim ClipboardContents As String = Clipboard.GetText().Trim()
        Dim oProfileFilter As ProfileFilter

        Try
            CurrMatchTreeView.Nodes.Clear()
            CurrMatchTreeView.ImageList = ImageList1
            CurrMatchTreeView.SelectedImageIndex = 0

            oProfileFilter = New ProfileFilter(
                LogConfig,
                DT_USER_PROFILES,
                DTPROFILE_REL_PROCESS,
                DTPROFILE_REL_WINDOW,
                DTPROFILE_REL_CONTROL,
                CurrMatchTreeView
            )
        Catch ex As Exception
            Logger.Error(ex)
            MsgBox("Fehler beim Laden der Profile. Möglicherweise liegt ein Konfigurationsfehler vor. Mehr Informationen im Log.", MsgBoxStyle.Critical, Text)
            Exit Sub
        End Try

        Try
            Dim oProfiles = oProfileFilter.Profiles.AsEnumerable()
            Dim oEnvironment = GetEnvironment()

            oProfiles = oProfileFilter.FilterProfilesByClipboardRegex(oProfiles, ClipboardContents)
            oProfiles = oProfileFilter.LogRemainingProfiles(oProfiles, "FilterProfilesByClipboardRegex")
            oProfiles = oProfileFilter.FilterProfilesByProcess(oProfiles, oWindowInfo.ProcessName)
            oProfiles = oProfileFilter.LogRemainingProfiles(oProfiles, "FilterProfilesByProcess")
            oProfiles = oProfileFilter.FilterWindowsByWindowTitleRegex(oProfiles, oWindowInfo.WindowTitle)
            oProfiles = oProfileFilter.LogRemainingProfiles(oProfiles, "FilterWindowsByWindowTitleRegex")
            oProfiles = oProfileFilter.FilterProfilesByFocusedControl(oProfiles, ClipboardContents, Handle)
            oProfiles = oProfileFilter.LogRemainingProfiles(oProfiles, "FilterProfilesByFocusedControl")
            oProfiles = oProfileFilter.FilterProfilesBySearchResults(oProfiles, oEnvironment.Database, oEnvironment.User, ClipboardContents)
            oProfiles = oProfileFilter.LogRemainingProfiles(oProfiles, "FilterProfilesBySearchResults")
            oProfiles = oProfileFilter.ClearNotMatchedProfiles(oProfiles)
            oProfiles = oProfileFilter.ClearDuplicateProfiles(oProfiles)
            oProfiles = oProfileFilter.LogRemainingProfiles(oProfiles, "CleanUp")
            oProfiles = oProfiles.ToList()

            CURRENT_MATCHING_PROFILES = oProfiles
            CURRENT_CLIPBOARD_CONTENTS = ClipboardContents
        Catch ex As Exception
            MsgBox("Fehler beim Auswerten der Profile. Mehr Informationen im Log.", MsgBoxStyle.Critical, Text)
            Logger.Error(ex)
        End Try
    End Sub

    Private Sub ReceiveHotKey(ByVal HotKeyID As String) Handles Hotkey.HotKeyPressed
        If HotKeyID = HOTKEY_TRIGGER_WATCHER Then
            If CURRENT_CLIPBOARD_CONTENTS IsNot Nothing Then
                If CURRENT_MATCHING_PROFILES.Count > 0 And MONITORING_ACTIVE = True Then
                    CHECK_PROFILE_MATCH()
                End If
            End If
        ElseIf HotKeyID = HOTKEY_TOGGLE_WATCHER Then
            Change_Monitoring_State()
        End If
    End Sub
    Sub CHECK_PROFILE_MATCH()
        Logger.Debug("...now CHECK_PROFILE_MATCH...")
        Dim oProfiles = CURRENT_MATCHING_PROFILES
        'Dim oInvalidDocumentSQL = False
        'Dim oInvalidDataSQL = False

        'Dim oPatterns As New ClassPatterns(LogConfig)
        Dim oEnv = GetEnvironment()

        'For Each oProfile In oProfiles
        '    Dim oResultDocs As Integer = 0
        '    Dim oResultData As Integer = 0

        '    Dim oDataSearches As DataTable = Database.GetDatatable($"SELECT COUNT_COMMAND FROM TBCW_PROF_DATA_SEARCH WHERE ACTIVE = 1 AND PROFILE_ID = {oProfile.Guid}")
        '    Dim oDocSearches As DataTable = Database.GetDatatable($"SELECT COUNT_COMMAND FROM TBCW_PROF_DOC_SEARCH WHERE ACTIVE = 1 AND PROFILE_ID = {oProfile.Guid}")

        '    For Each oRow As DataRow In oDataSearches.Rows
        '        Dim oCountCommand = String.Empty
        '        Try
        '            oCountCommand = oRow.Item("COUNT_COMMAND")

        '            If oCountCommand = String.Empty Then
        '                Continue For
        '            End If

        '            oCountCommand = oPatterns.ReplaceUserValues(oCountCommand, oEnv.User)
        '            oCountCommand = oPatterns.ReplaceInternalValues(oCountCommand)

        '            oResultData += Database.GetScalarValue(oCountCommand)
        '        Catch ex As Exception
        '            Logger.Warn("Invalid SQL Query for Counting Data in Profile {0}: {1}", oProfile.Guid, oCountCommand)
        '            oInvalidDataSQL = True
        '        End Try
        '    Next

        '    For Each oRow As DataRow In oDocSearches.Rows
        '        Dim oCountCommand = String.Empty
        '        Try
        '            oCountCommand = oRow.Item("COUNT_COMMAND")

        '            If oCountCommand = String.Empty Then
        '                Continue For
        '            End If

        '            oCountCommand = oPatterns.ReplaceUserValues(oCountCommand, oEnv.User)
        '            oCountCommand = oPatterns.ReplaceInternalValues(oCountCommand)
        '            Logger.Debug($"Now again checking countDocs: sql so far: {oCountCommand}")
        '            oResultDocs += Database.GetScalarValue(oCountCommand)
        '            Logger.Debug($"Now oResultDocs is: {oResultDocs}")
        '        Catch ex As Exception
        '            Logger.Warn("Invalid SQL Query for Counting Data in Profile {0}: {1}", oProfile.Guid, oCountCommand)
        '            oInvalidDocumentSQL = True
        '        End Try
        '    Next

        '    oProfile.CountData = oResultData
        '    If oProfile.CountDocs > 0 Then
        '        Logger.Debug($"For hell no replacing JJ as CountDocs already has a result > 0!!!")
        '    Else
        '        oProfile.CountDocs = oResultDocs
        '    End If

        'Next

        'If oInvalidDocumentSQL Or oInvalidDataSQL Then
        '    MsgBox("Ein oder mehrere Abfragen konnten nicht ausgeführt werden. Bitte überprüfen Sie das Log.", MsgBoxStyle.Exclamation, "Warnung")
        '    Exit Sub
        'End If

        Dim oParams = New ClipboardWatcherParams() With {
            .ClipboardContents = CURRENT_CLIPBOARD_CONTENTS,
            .MatchingProfiles = oProfiles,
            .MatchTreeView = CurrMatchTreeView
        }

        Dim oForm As New frmMatch(LogConfig, oEnv, oParams)
        _MatchForm = oForm
        oForm.Show()
    End Sub

    Private Function GetEnvironment() As Environment
        Dim oUser As New State.UserState() With {
            .DateFormat = USER_DATE_FORMAT,
            .Email = USER_EMAIL,
            .GivenName = USER_PRENAME,
            .Language = USER_LANGUAGE,
            .MachineName = System.Environment.MachineName,
            .ShortName = USER_SHORTNAME,
            .Surname = USER_SURNAME,
            .UserId = USER_ID,
            .UserName = USER_USERNAME
        }

        Dim oSettings As New State.SettingsState() With {
            .GdPictureKey = GDPICTURE_LICENSE
        }

        Dim oEnvironment As New Environment() With {
            .Database = Database,
            .Modules = Nothing,
            .User = oUser,
            .Settings = oSettings
        }

        Return oEnvironment
    End Function

    Sub Change_Monitoring_State()
        If MONITORING_ACTIVE = True Then
            NotifyIconMain.ShowBalloonTip(30000, "Clipboard Watcher", "Clipboard-Watcher wurde deaktiviert!", ToolTipIcon.Info)
            MONITORING_ACTIVE = False
        Else
            MONITORING_ACTIVE = True
            NotifyIconMain.ShowBalloonTip(30000, "Clipboard Watcher", "Clipboard-Watcher wurde wieder aktiviert!", ToolTipIcon.Info)
        End If
    End Sub
    Private Sub frmMain_Shown(sender As Object, e As EventArgs) Handles Me.Shown
        If ERROR_INIT <> "INVALID USER" And LICENSE_COUNT > 0 Then
            If DT_USER_PROFILES.Rows.Count >= 1 Then
                Hide()
            End If
        Else
            If USER_IS_ADMIN = True And ERROR_INIT = "NO LICENSE" Then
                MsgBox("As an admin You have access! Please inform Digital Data to add a valid license!", MsgBoxStyle.Exclamation, "No valid License")
            Else
                If Not USER_IS_ADMIN Then
                    MsgBox("Application will close now!", MsgBoxStyle.Critical, "No valid License")
                    Close()
                End If

            End If
        End If
        If USER_IS_ADMIN = True Then
            btnAdminConfig.Visible = True
        Else
            btnAdminConfig.Visible = False
        End If
        TimerRefresh.Start()
    End Sub

    Private Sub NotifyIcon1_DoubleClick(sender As Object, e As EventArgs) Handles NotifyIconMain.DoubleClick
        OpenClose()
    End Sub
    Sub OpenClose()
        If Visible = False Then
            BringToFront()
            Visible = True
            TimerClose.Start()
        Else
            Hide()
            NotifyIconMain.Visible = True
        End If
    End Sub

    Private Sub tsmiChangeState_Click(sender As Object, e As EventArgs) Handles tsmiChangeState.Click
        If tsmiChangeState.Tag = "stop" Then
            tsmiChangeState.Tag = "start"
            tsmiChangeState.Image = My.Resources.control_start_blue
            tsmiChangeState.Text = "Clipboard Watcher starten"
            MONITORING_ACTIVE = False
            NotifyIconMain.ShowBalloonTip(30000, "Clipboard Watcher", "Clipboard-Watcher wurde deaktiviert!", ToolTipIcon.Info)
        Else
            tsmiChangeState.Image = My.Resources.StatusAnnotations_Stop_16xLG
            tsmiChangeState.Tag = "stop"
            tsmiChangeState.Text = "Clipboard Watcher stoppen"
            MONITORING_ACTIVE = True
            NotifyIconMain.ShowBalloonTip(30000, "Clipboard Watcher", "Clipboard-Watcher wurde wieder aktiviert!", ToolTipIcon.Info)
        End If
    End Sub

    Private Sub TimerClose_Tick(sender As Object, e As EventArgs) Handles TimerClose.Tick
        Hide()
    End Sub

    Private Sub frmMain_VisibleChanged(sender As Object, e As EventArgs) Handles Me.VisibleChanged
        If TimerClose.Enabled = True Then
            TimerClose.Stop()
        End If
    End Sub

    Private Sub MinimierenToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles MinimierenToolStripMenuItem.Click
        Hide()
    End Sub

    Private Sub ClientÖffnenToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ClientÖffnenToolStripMenuItem.Click
        OpenClose()
    End Sub

    Private Sub btnUserConfig_Click(sender As Object, e As EventArgs) Handles btnUserConfig.Click
        frmConfig_Basic.ShowDialog()
    End Sub

    Private Sub btnAdminConfig_Click(sender As Object, e As EventArgs) Handles btnAdminConfig.Click
        TimerClose.Stop()
        MONITORING_ACTIVE = False
        frmAdministration.ShowDialog()
        TimerClose.Start()
        MONITORING_ACTIVE = True
    End Sub

    Private Sub ClientBeendenToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ClientBeendenToolStripMenuItem.Click
        Shut_Down
    End Sub
    Sub Shut_Down()
        If MsgBox("Wollen Sie das Programm beenden?", MsgBoxStyle.Question Or MsgBoxStyle.YesNo, Text) = MsgBoxResult.Yes Then
            Close()
        End If
    End Sub
    Private Sub TimerRefresh_Tick(sender As Object, e As EventArgs) Handles TimerRefresh.Tick
        RefreshUI()
    End Sub

    Private Sub RefreshUI()
        Dim oResultText = ClassInit.Refresh_Profile_Links()
        lblrefresh.Text = ""
        ClassInit.CheckModuleData()
        labelStatus.Text = oResultText
        labelRefresh.Text = $"Aktualisiert: {Now.ToShortTimeString}"
        lblrefresh.Text = $"Eingeloggte Benutzer: {USERCOUNT_LOGGED_IN}"
        labelVersion.Text = String.Format(labelVersion.Text, My.Application.Info.Version.ToString)
        labelUser.Text = String.Format(labelUser.Text, USER_USERNAME)
        labelHotkey.Text = String.Format(labelHotkey.Text, $"{HotkeyFunctionKey.ToUpper}+{HotkeySearchKey.ToUpper}")
    End Sub

    Private Sub BisherigenAblaufAnzeigenToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles BisherigenAblaufAnzeigenToolStripMenuItem.Click
        If CurrMatchTreeView.Nodes.Count > 0 Then
            Dim oForm As New frmTreeView(CurrMatchTreeView.Nodes)
            oForm.Show()
        End If
    End Sub
End Class
