Imports System.Reflection
Imports IntraSell_DLL
Imports IntraSell_Net_Base

Public Class ClassPlugIns

    Private pluginsDict As New Dictionary(Of String, DataSet)

    Private pluginsForms As New Dictionary(Of String, Form)

    ''' <summary>
    ''' 
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub LadePlugins(ByRef dashboardForm As Dashboard, ByRef mainForm As Main)
        WriteLog("LadePlugins START")

        Dim r As Short = 0
        For Each pluginDefinition In ListFilesInFolder(GetAppPath(), False, "plugin")
            Try
                LadePlugInForFile(pluginDefinition, dashboardForm, mainForm, r)
                r += 1
            Catch ex As Exception
                WriteLog("LadePlugins Error " + ex.Message)
            End Try
        Next
        WriteLog("Plugins geladen: " & r)
        WriteLog("LadePlugins END")
    End Sub

    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="pluginDefinition">XML Filename des Plugin</param>
    ''' <param name="dashboardForm"></param>
    ''' <param name="mainForm"></param>
    ''' <param name="rowIndex"></param>
    Private Sub LadePlugInForFile(pluginDefinition As String, ByRef dashboardForm As Dashboard, ByRef mainForm As Main, rowIndex As Integer)
        Try
            WriteLog("LadePlugin Definition " + pluginDefinition)
            Dim pluginDefDataset As New DataSet
            pluginDefDataset.ReadXml(pluginDefinition)
            Dim plugin = pluginDefDataset.Tables("plugin")
            Dim menu As String = plugin.Rows(0).Item("menu")
            Dim dashboard As String = plugin.Rows(0).Item("dashboard")
            Dim enabledPlugin = plugin.Rows(0).Item("enabled")

            Dim nameForVars As String = dashboard
            If String.IsNullOrEmpty(nameForVars) Or nameForVars = "-" Or Len(nameForVars) < 3 Then
                nameForVars = menu
            End If

            Dim enabled As Boolean = CType(enabledPlugin, Boolean) And VarValue_Default(nameForVars + "_enabled", "true")
            Dim autostart As Boolean = VarValue_Default(nameForVars + "_autostart", "false")

            If enabled Then
                'add as dashboard button
                If Len(dashboard) > 1 AndAlso autostart Then
                    Dim actionButton As New Button With {
                        .Height = 25,
                        .Width = 50,
                        .Font = New Font("Microsoft Sans Serif", 10),
                        .Text = dashboard,
                        .Tag = pluginDefinition,
                        .Dock = DockStyle.Fill,
                        .Margin = New System.Windows.Forms.Padding(1, 1, 1, 1),
                        .Padding = New System.Windows.Forms.Padding(0, 0, 0, 0)
                    }
                    ModuleStyle.StyleButton(actionButton)

                    AddHandler actionButton.Click, AddressOf OnButtonAction
                    dashboardForm.AddPlugin(actionButton, row:=rowIndex, col:=3)
                End If

                'add as Menu 
                If Len(menu) > 1 Then
                    Dim pluginMenuItem = New System.Windows.Forms.ToolStripMenuItem With {
                        .ForeColor = Color.Green,
                        .Text = menu,
                        .Tag = pluginDefinition
                    }
                    AddHandler pluginMenuItem.Click, AddressOf OnAction
                    mainForm.AddPlugin(pluginMenuItem)
                End If
            Else
                WriteLog("LadePlugin nicht enabled " + pluginDefinition)
            End If

            pluginsDict.Add(pluginDefinition, pluginDefDataset)

            If enabled AndAlso autostart Then
                OnTag(pluginDefinition, hide:=True)
            End If
        Catch ex As Exception
            HandleAppError(ex, Silent:=True)
        End Try
    End Sub

    Private Sub OnButtonAction(sender As Object, e As EventArgs)
        Try
            Dim tag = CType(sender, Button).Tag
            OnTag(tag, hide:=False)
        Catch ex As Exception
            HandleAppError(ex)
        End Try
    End Sub

    Private Sub OnAction(sender As Object, e As EventArgs)
        Try
            Dim tag = CType(sender, ToolStripMenuItem).Tag
            OnTag(tag, hide:=False)
        Catch ex As Exception
            HandleAppError(ex)
        End Try
    End Sub

    Friend Sub OnTag(tag As Object, hide As Boolean)
        Dim pluginDefDataset As New DataSet
        pluginsDict.TryGetValue(tag, pluginDefDataset)

        Dim pluginDefinition As String = tag
        Dim assembly = pluginDefinition.ToLower.Replace(".plugin", ".exe")
        If pluginDefDataset IsNot Nothing Then
            Dim plugin = pluginDefDataset.Tables("plugin")
            Dim form As String = plugin.Rows(0).Item("form")
            OnActionPluginStarten(pluginDefinition, assembly, form, hide)
        End If
    End Sub

    Private Sub OnActionPluginStarten(pluginDefinition As String, exe As String, form As String, hide As Boolean)
        Try
            WriteLog("OnActionPluginStarten Plugin " & exe)
            If IO.File.Exists(exe) Then
                If pluginsForms.ContainsKey(pluginDefinition) Then
                    Dim objFormOld = New Form
                    If pluginsForms.TryGetValue(pluginDefinition, objFormOld) AndAlso Not objFormOld.IsDisposed Then
                        ReopenPlugin(objFormOld)
                        Exit Sub
                    End If
                End If

                ShowPluginForm(pluginDefinition, exe, form, hide)

            Else
                'Plugin ist nicht vorhanden 
                WriteLog("Plugin ist nicht vorhanden  " & exe)
            End If
        Catch tla As TypeLoadException
            HandleAppError(tla, "Cannot load " & pluginDefinition, True)
        Catch ex As Exception
            HandleAppError(ex, "Installieren Sie das Plugin erneut! Plugin: " & pluginDefinition, True)
        End Try
    End Sub

    Sub ReopenPlugin(ByRef objFormOld As Form)
        If objFormOld.Width < 200 Then
            objFormOld.Width = 600
        End If
        If objFormOld.Height < 100 Then
            objFormOld.Height = 600
        End If
        objFormOld.WindowState = FormWindowState.Normal
        objFormOld.Show()
        objFormOld.Focus()
    End Sub

    Sub ShowPluginForm(pluginDefinition As String, exe As String, form As String, hide As Boolean)
        Try
            Dim objForm = OpenPluginForm(pluginDefinition, exe, form, hide)
            If hide Then
                objForm.Hide()
            Else
                'objForm.Show()
            End If

            pluginsForms.Remove(pluginDefinition)
            pluginsForms.Add(pluginDefinition, objForm)
            AddHandler objForm.FormClosing, AddressOf PluginFormClosed
        Catch ex As Exception
            HandleAppError(ex, Silent:=True)
        End Try
    End Sub

    Public Shared Function OpenPluginForm(pluginDefinition As String, exe As String, form As String, hide As Boolean) As Form
        IntraSell_DLL.ModuleLog.WriteLog($"OpenPluginForm {exe}, {form}")
        'INIT
        System.Environment.SetEnvironmentVariable("LADE_PLUGIN_EXE", exe)
        Dim path As String = IO.Path.GetFileName(exe) '"TConnectSync.exe"
        Dim ass As Assembly = Assembly.LoadFrom(path)
        Dim FormInstanceType = ass.GetType(form) '("TConnectSync.FormStart")
        Dim objForm = CType(Activator.CreateInstance(FormInstanceType), Form)
        If Not objForm.IsMdiContainer Then
            objForm.MdiParent = Main
        End If

        If hide Then
            objForm.Visible = False
            objForm.WindowState = FormWindowState.Minimized
        End If
        objForm.Show()
        Return objForm
    End Function


    Private Sub Test()
        Try
            Dim path As String = "TConnectSync.exe"
            Dim ass As Assembly = Assembly.LoadFrom(path)
            Dim FormInstanceType = ass.GetType("TConnectSync.FormStart")
            Dim objForm = CType(Activator.CreateInstance(FormInstanceType), Form)
            objForm.MdiParent = Main
            objForm.Show()
            objForm.Focus()
        Catch ex As Exception
            HandleAppError(ex)
        End Try
    End Sub

    Private Sub PluginFormClosed(sender As Object, e As FormClosingEventArgs)
        Try
            'pluginsForms.Remove(CType(sender, Form))
        Catch ex As Exception
            HandleAppError(ex, Silent:=True)
        End Try
    End Sub

    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="pluginName">E.g. TConnectSync.Plugin</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Function GetPluginFormByName(pluginName As String) As Form
        Dim f As Form = Nothing
        Dim nameInDictionary = Nothing
        For Each k In pluginsForms.Keys
            If k.Contains(pluginName) Then
                nameInDictionary = k
            End If
        Next
        pluginsForms.TryGetValue(nameInDictionary, f)
        Return f
    End Function

End Class
