Imports WINDREAMLib
Imports WINDREAMLib.WMCOMEvent
Imports WINDREAMLib.WMEntity
Imports WINDREAMLib.WMObjectEditMode
Imports WINDREAMLib.WMSearchOperator
Imports WINDREAMLib.WMSearchRelation
Imports WMOBRWSLib

Public Class ClassWindream_allgemein

#Region "+++++ Konstanten +++++"
    Const DEBUG = AUS
    Const AUS = 0
    Const WINDREAM = 1
    Const VARIABLEN = 2
#End Region

#Region "+++++ Variablen +++++"
    Public oConnect ' der Typ darf nicht festgelegt werden (warum auch immer... geht sonst nicht)
    Public oSession 'As WINDREAMLib.WMSession ' der Typ darf nicht festgelegt werden (warum auch immer... geht sonst nicht)
    Public oBrowser As New WMOBRWSLib.ServerBrowser
    Public oDokumentTypen As WINDREAMLib.WMObjects
#End Region


#Region "+++++ Allgemeine Methoden und Funktionen +++++"

    ''' <summary>
    ''' Konstruktor für die windream-Klasse
    ''' </summary>
    ''' <remarks></remarks>
    Sub New()

    End Sub


    ''' <summary>
    ''' Initialisiert die statische Klasse (Login, Session starten, usw.)
    ''' </summary>
    ''' <returns>Liefert True wenn das Anmelden erfolgreich war, sonst False</returns>
    ''' <remarks></remarks>
    Public Function Create_Session() As Boolean
        Try
            Try
                ' Session-Objekt instanziieren und mit dem im Client ausgewählten Server belegen
                Me.oSession = CreateObject("Windream.WMSession", Me.GetCurrentServer)
                LOGGER.Debug("windream-Server: '" & Me.GetCurrentServer & "'")
                ' Connection-Objekt instanziieren
                Me.oConnect = CreateObject("Windream.WMConnect")
                'MsgBox("windrem init 'ed")
            Catch ex As Exception
                LOGGER.Error(ex)
                LOGGER.Debug($"Error while creating WMConnect Object: {vbCrLf}{ex.Message}")
                Return False
            End Try


            ' wenn windream nicht angemeldet ist
            If Not Me.IsLoggedIn Then

                ' Art der Anmeldung an windream festlegen
                '   0x0L (also 0)                   = Standard windream Benutzer
                '   WM_MODULE_ID_DOCTYPEEDITOR_LIC  = ermöglicht Zugriff auf die windream Management Funktionen (Z.B. zur Verwaltung der windream Dokumententypen, Auswahllisten, etc.)
                '   WM_MODULE_ID_INDEXSERVICE       = ermöglicht der Session die Indexierungs-Events vom windream DMS-Service zu empfangen
                Me.oConnect.ModuleID = 0

                ' setzt die minimal erwartete windream-Version 
                Me.oConnect.MinReqVersion = "3"

                ' -- Impersonifizierung nur möglich mit registry-eintrag --
                ' oConnect.UserName "\schulung\windream"
                ' oConnect.Password "windream"

                ' Verbindung mit Session-Objekt (und dem ausgewählten Server) aufbauen
                Me.oConnect.LoginSession(Me.oSession)
                If Me.oSession.aLoggedin = False Then
                    MsgBox("Es konnte keine Verbindung mit dem windream-Server hergestellt werden", MsgBoxStyle.Exclamation, "Verbindung konnte nicht hergestellt werden")
                    Return False
                End If

                If ModuleMySettings.DEBUG = False Then
                    LOGGER.Info(" >> windream-Version: '" & oSession.GetSystemInfo("WindreamVersion") & "'")
                End If

                ' AUSGABE VON SYSTEMINFORMATIONEN
                ' Gibt die Versionsart (Lizenztyp) also Small-Business-Edition (SBE), Small-Business-Extension (SBX) 
                ' oder Business-Edition (BE) aus
                'MsgBox("WindreamVersion: " & oSession.GetSystemInfo("WindreamVersion") & vbNewLine & "LicenceKey: " & oSession.GetSystemInfo("LicenceKey") & vbNewLine & _
                '       vbNewLine & "LicenceName: " & oSession.GetSystemInfo("LicenceName"))

                'Dim WMCtrl As AISCONTROLDATACOMLib.AISControlData
                'WMCtrl = New AISCONTROLDATACOMLib.AISControlData

                '' liefert die Versionsnummer des Clients

                'MsgBox(WMCtrl.WMWorkstationBuildNo)
                'MsgBox(WMCtrl.W
                '' liefert den Servernamen des angemeldeten windreams
                'MsgBox(WMCtrl.WMServerName)

                Try
                    Me.oSession.SwitchEvents(WMCOMEventWMSessionNeedIndex, False)
                    ' der Parameter WMEntityDocument definiert, dass nur Dokumenttypen und keine 
                    ' Ordnertypen ausgelesen werden
                    Me.oDokumentTypen = Me.oSession.GetWMObjectTypes(WINDREAMLib.WMEntity.WMEntityDocument)
                Catch ex As Exception
                    LOGGER.Error(ex)
                    Return False
                End Try

            End If

            LOGGER.Debug($"windream login successful")
            Return True

        Catch ex As Exception
            LOGGER.Error(ex)
            MsgBox(ex.Message, MsgBoxStyle.Critical, "Error Login on windream")

            Return False
        End Try

    End Function
    Public Function Start_WMCC_andCo()
        Try
            ' 04.10.18: Überprüft, ob der Benutzer Mitglied der SERVER_USER Gruppe ist
            Dim sql = "SELECT T.GUID FROM TBDD_GROUPS_USER T WITH (NOLOCK) INNER JOIN TBDD_GROUPS T1 WITH (NOLOCK) on T1.GUID = T.GROUP_ID WHERE T1.NAME = 'SERVER_USER' AND T.USER_ID = " & USER_ID
            Dim userExistsInServerUserGroup = DatabaseFallback.GetScalarValueECM(sql) ', CONNECTION_STRING_ECM, "StartWMCC-userExistsInServerUserGroup")

            If WMSESSION_STARTSTOP_STARTUP = True Then
                'And userExistsInServerUserGroup Is Nothing
                LOGGER.Info(">> WINDREAM-Start on ApplicationStart is active!")

                Dim owindreamControlCenter = CreateObject("Wmcc.ControlCenter")
                Dim owindreamIndexService = CreateObject("WMIndexServer.WMIdxSvControl")
                owindreamControlCenter.StartVFSService(1)
                System.Threading.Thread.Sleep(1000)
                owindreamIndexService.Start()
                System.Threading.Thread.Sleep(1500)
            End If
            Create_Session()
        Catch ex As Exception
            LOGGER.Error(ex)
            LOGGER.Info("Error while starting up WMCC and IndexService: " & ex.Message, True)
        End Try
    End Function
    Public Function Stop_WMCC_andCo()
        Try
            ' 04.10.18: Überprüft, ob der Benutzer Mitglied der SERVER_USER Gruppe ist
            Dim sql = "SELECT T.GUID FROM TBDD_GROUPS_USER T INNER JOIN TBDD_GROUPS T1 on T1.GUID = T.GROUP_ID WHERE T1.NAME = 'SERVER_USER' AND T.USER_ID = " & USER_ID
            Dim userExistsInServerUserGroup = DatabaseFallback.GetScalarValueECM(sql) ', CONNECTION_STRING_ECM, "StopWMCC-userExistsInServerUserGroup")

            If WMSESSION_STARTSTOP_STARTUP = True Then 'And userExistsInServerUserGroup Is Nothing
                Dim owindreamControlCenter = CreateObject("Wmcc.ControlCenter")
                Dim owindreamIndexService = CreateObject("WMIndexServer.WMIdxSvControl")
                owindreamControlCenter.StartVFSService(0)
                owindreamIndexService.Shutdown()
                owindreamControlCenter.ExitCC(0)
            End If
        Catch ex As Exception
LOGGER.Error(ex)
            LOGGER.Info("Error while Stopping WMCC and IndexService: " & ex.Message, True)
        End Try
    End Function
#End Region



#Region "+++++ Funktionen die für den Objekttyp relevate Informationen zurückliefern +++++"

    ''' <summary>
    ''' Liefert alle Objekttypen des aktuellen Servers als windream-Objekte.
    ''' </summary>
    ''' <returns>Alle Objekttypen als WMObjects-Objekt</returns>
    ''' <remarks></remarks>
    Public Function GetObjecttypesAsObjects() As WMObjects
        Try

            Return Me.oDokumentTypen

        Catch ex As Exception
LOGGER.Error(ex)
            MsgBox("Fehlernachricht:" & vbNewLine & ex.Message, MsgBoxStyle.Critical, "Fehler beim Auslesen der Objekttypen")
            Return Nothing
        End Try
    End Function

    ''' <summary>
    ''' Liefert alle Objekttypen des aktuellen Servers als Array aus Strings.
    ''' </summary>
    ''' <returns>Array mit allen Objekttypen als Strings</returns>
    ''' <remarks></remarks>
    Public Function GetObjecttypesAsStrings() As String()

        Try
            Dim objektTypenStr(Me.oDokumentTypen.Count) As String

            For i As Integer = 0 To Me.oDokumentTypen.Count
                objektTypenStr(i) = Me.oDokumentTypen.Item(i).aName
            Next

            Return objektTypenStr

        Catch ex As Exception
LOGGER.Error(ex)
            MsgBox("Fehlernachricht:" & vbNewLine & ex.Message, MsgBoxStyle.Critical, "Fehler beim Auslesen der Objekttypen als String")
            Return Nothing
        End Try

    End Function
    Public Function GetTypeOfIndex(ByVal indexname As String) As Integer
        Try
            If IsNothing(Me.oSession) Then
                LOGGER.Warn("⚠️ GetTypeOfIndex: WMSession is nothing")
                Return Nothing
            End If
            Dim oAttribute = Me.oSession.GetWMObjectByName(WINDREAMLib.WMEntity.WMEntityAttribute, indexname)
            Dim vType = oAttribute.getVariableValue("dwAttrType")
            Return vType
        Catch ex As Exception
            Dim omsg = $"Unexpected error in GetTypeOfIndex [{indexname}]: {ex.Message}"
            LOGGER.Warn(omsg)
            Return Nothing
        End Try

    End Function

    Public Function NormalizePath(pPath As String)
        Dim oNormalizedPath As String
        If pPath.StartsWith(WMSUFFIX) Then
            oNormalizedPath = pPath.Replace(WMSUFFIX, "")
        ElseIf pPath.StartsWith("\\") Then
            oNormalizedPath = pPath.Substring(1)
        ElseIf pPath.StartsWith("\") Then
            Return pPath
        ElseIf pPath.StartsWith(WMDRIVE_LETTER) Then
            oNormalizedPath = pPath.Replace(WMDRIVE_LETTER & ":", "")
        ElseIf pPath.StartsWith("\") = False Then
            oNormalizedPath = "\" & pPath
        Else
            oNormalizedPath = pPath
        End If

        Return oNormalizedPath
    End Function

    Public Function CheckFileExists(Path As String)
        Dim oNormalizedPath = NormalizePath(Path)

        Try
            Dim oObjectId = 0
            Dim oObjectDbId = 0
            Dim WMObject As WINDREAMLib.WMObject '= CreateObject("WINDREAMLib.WMObject")  'New WINDREAMLib.WMObject
            If IsNothing(oSession) Then
                If Create_Session() = False Then
                    Return False
                End If
            End If
            WMObject = oSession.GetWMObjectByPath(WINDREAMLib.WMEntity.WMEntityDocument, oNormalizedPath)
            Return True
        Catch ex As Exception
LOGGER.Error(ex)
            Return False
        End Try
    End Function
    ''' <summary>
    ''' Liefert alle Indexe eines Objekttypen.
    ''' </summary>
    ''' <param name="name">Name des Objekttyps</param>
    ''' <returns>Array mit allen Objekttyp zugeordneten Indexen als String</returns>
    ''' <remarks></remarks>
    Public Function GetIndicesByObjecttype(ByVal Objecttype_name As String) As String()
        Try
            If IsNothing(Me.oSession) Then
                LOGGER.Warn("⚠️ GetIndicesByObjecttype: WMSession is nothing")
                Return Nothing
            End If
            Dim oObjectType As WMObject
            Dim oIndexAttributes As WMObjectRelation
            Dim oIndexAttribute As WMObject
            Dim oIndex As WMObject
            Dim oRelProperties As WMObjectRelationClass

            ' den Objekttyp laden
            oObjectType = Me.oSession.GetWMObjectByName(WMEntityObjectType, Objecttype_name)

            ' Beziehung zu Indizes des Objekttyp auslesen
            oIndexAttributes = oObjectType.GetWMObjectRelationByName("TypeAttributes")

            ' Array für Indizes vorbereiten
            Dim aIndexNames(oIndexAttributes.Count - 1) As String

            ' alle Indizes durchlaufen
            For j As Integer = 0 To oIndexAttributes.Count - 1

                ' aktuellen Index auslesen
                oIndexAttribute = oIndexAttributes.Item(j)

                ' Eigenschaften des Index auslesen
                oRelProperties = oIndexAttribute.GetWMObjectRelationByName("Attribute")

                ' Index aus den Eigenschaften auslesen
                oIndex = oRelProperties.Item(0)

                ' Indexname speichern
                aIndexNames(j) = oIndex.aName
            Next
            ' Indexarray sortiert zurückgeben
            Array.Sort(aIndexNames)
            ' Indexarray zurückgeben
            Return aIndexNames

        Catch ex As Exception
            LOGGER.Error(ex)
            MsgBox(ex.Message, MsgBoxStyle.Critical, "Fehler beim Auslesen der windream-Indexe")
            Return Nothing
        End Try
    End Function
    ''' <summary>
    ''' Liefert einen Objekttyp als WMObject an Hand dessen Name.
    ''' </summary>
    ''' <param name="objekttypName">Name des Objekttyps</param>
    ''' <returns>Objekttyp als WMObject</returns>
    ''' <remarks></remarks>
    'Public Function GetObjecttypeByName(ByVal objekttypName As String) As WMObject
    '    Try
    '        If IsNothing(Me.oSession) Then
    '            LOGGER.Warn("⚠️ GetObjecttypeByName: WMSession is nothing")
    '            Return Nothing
    '        End If
    '        ' alle Objekttypen auslesen
    '        Dim oObjectTypes As WMObjects = Me.oSession.GetWMObjectTypes(WINDREAMLib.WMEntity.WMEntityDocument)

    '        ' alle Objekttypen durchlaufen und nach dem mit dem angegebenen Namen suchen
    '        For Each oObjectType As WMObject In oObjectTypes
    '            If oObjectType.aName = objekttypName Then
    '                Return oObjectType
    '            End If
    '        Next

    '        Return Nothing

    '    Catch ex As Exception
    '        LOGGER.Error(ex)
    '        MsgBox("Es konnte ein Objekttyp nicht erstellt werden." & vbNewLine & vbNewLine & "Fehlernachricht:" & vbNewLine & ex.Message, MsgBoxStyle.Exclamation, "Objekttyp konnte nicht erstellt werden")
    '        Return Nothing
    '    End Try
    'End Function

    ''' <summary>
    ''' Überprüft ob der angegebene Index im Objekttyp existiert
    ''' </summary>
    ''' <param name="objekttyp">Name des zu durchsuchenden Objekttyps</param>
    ''' <param name="indexname">Name des zu suchenden Indexes</param>
    ''' <returns>Liefert True wenn der Index im Objekttyp existiert, sonst False</returns>
    ''' <remarks></remarks>
    Public Function ExistIndexInObjekttyp(ByVal objekttyp As String, ByVal indexname As String) As Boolean
        Try
            Dim indexnamen() As String = Me.GetIndicesByObjecttype(objekttyp)

            If indexnamen Is Nothing Then Return False
            MVSource_AllIndicies = MyIndicies

            For Each index As String In indexnamen
                If index = indexname Then Return True
            Next

        Catch ex As Exception
            LOGGER.Error(ex)
            MsgBox("Beim Prüfen ob ein Index für einen Objekttypen existiert, ist ein Fehler aufgetreten." & vbNewLine & vbNewLine & "Fehlernachricht:" & vbNewLine & ex.Message, MsgBoxStyle.Critical, "Fehler beim Prüfen auf Existenz eines Index in einem Objekttyp")
        End Try

        Return False

    End Function

#End Region



#Region "+++++ Allgemeine Funktionen die Informationen zurückliefern +++++"

    ''' <summary>
    ''' Liefert True wenn die windream-Session angemeldet ist und False für den Fall, dass die Session nicht eingeloggt ist.
    ''' </summary>
    ''' <returns>Anmeldestatus als Boolean</returns>
    ''' <remarks></remarks>
    Public Function IsLoggedIn() As Boolean
        Try
            Return Me.oSession.aLoggedin
        Catch ex As Exception
LOGGER.Error(ex)
            MsgBox("Es konnte nicht erfolgreich geprüft werden, ob das Programm am windream-Server angemeldted ist." & vbNewLine & vbNewLine & "Fehlernachricht:" & vbNewLine & ex.Message, MsgBoxStyle.Critical, "Fehler bei Loggedin-Prüfung")
        End Try

        Return False
    End Function

    ''' <summary>
    ''' Liefert den Servernamen an dem windream aktuell angemeldet ist.
    ''' </summary>
    ''' <returns>Servername als String</returns>
    ''' <remarks></remarks>
    Public Function GetCurrentServer() As String
        Try
            Return Me.oBrowser.GetCurrentServer 'ClassWindream.oBrowser.GetCurrentServer
        Catch ex As Exception
LOGGER.Error(ex)
            MsgBox("Der aktuell gewählte windream-Server konnte nicht ausgelesen werden." & vbNewLine & vbNewLine & "Fehlernachricht:" & vbNewLine & ex.Message, MsgBoxStyle.Critical, "Fehler beim Auslesen des windream-Servers")
        End Try

        Return ""
    End Function

    'Public Function GetSharedCurrentServer() As String
    '    Try
    '        Return ClassWindream.oBrowser.GetCurrentServer
    '    Catch ex As Exception
    '        MsgBox("Der aktuell gewählte windream-Server konnte nicht ausgelesen werden." & vbNewLine & vbNewLine & "Fehlernachricht:" & vbNewLine & ex.Message, MsgBoxStyle.Critical, "Fehler beim Auslesen des windream-Servers")
    '    End Try

    '    Return ""
    'End Function


    ''' <summary>
    ''' Liefert das Windream-Laufwerk des windream-Servers, in Form '[Laufwerksbuchstabe]:'. (z.B. 'W:')
    ''' </summary>
    ''' <returns>Laufwerksbuchstabe mit Doppelpunkt als String</returns>
    ''' <remarks></remarks>
    'Public Function GetWindreamDriveLetter() As String

    '    Try
    '        Dim oControl As AISCONTROLDATACOMLib.AISControlData
    '        Dim sDrive As String = ""

    '        oControl = New AISCONTROLDATACOMLib.AISControlData

    '        sDrive = oControl.GetStringValue(&H10040003)

    '        Return sDrive & ":"

    '    Catch ex As Exception
    '        MsgBox("Fehlernachricht: " & ex.Message, MsgBoxStyle.Critical, "Fehler beim Auslesen des windream-Laufwerks")
    '    End Try

    '    Return ""
    'End Function

    ''' <summary>
    ''' Liefert den Typen eines Indexes als Integer.
    ''' </summary>
    ''' <param name="indexname">Name des zu überprüfenden Indexfeldes</param>
    ''' <returns>Liefert eine Zahl, die einen Typen beschreibt</returns>
    ''' <remarks></remarks>

    Public Function GetValuesfromAuswahlliste(ByVal _auswahlliste As String) As Object
        Try
            'Dim oAttribute = Me.oSession.GetWMObjectByName(WINDREAMLib.WMEntity.WMEntityAttribute, indexname)
            'Dim vType = oAttribute.getVariableValue("vItems")
            'Return vType
            Dim oChoiceList = oSession.GetWMObjectByName(WMEntityChoiceList, _auswahlliste)
            If Err.Number = 0 And TypeName(oChoiceList) <> "Nothing" Then
                Dim Values = oChoiceList
                Values = oChoiceList.GetVariableValue("vItems")
                Dim anz As Integer = 0
                'If LogErrorsOnly = False Then MsgBox("Try getting values for resullist: " & _auswahlliste)
                For Each CLItem In Values
                    If oChoiceList.aName IsNot Nothing Then
                        anz += 1
                    End If
                Next
                Dim strListe(anz - 1)
                Dim zahl As Integer = 0
                For Each CLItem In Values
                    'If LogErrorsOnly = False Then MsgBox("Item:  " & CLItem)
                    If oChoiceList.aName IsNot Nothing Then
                        strListe(zahl) = CLItem
                        zahl += 1
                    End If
                Next
                Return strListe
            Else
                MsgBox("Auswahlliste: " & _auswahlliste & " nicht gefunden!", MsgBoxStyle.Critical, "Fehler:")
                Return Nothing
            End If

        Catch ex As Exception
LOGGER.Error(ex)
            MsgBox(ex.Message, MsgBoxStyle.Critical, "Fehler in GetValuesfromAuswahlliste:")
            Return Nothing
        End Try
    End Function
#End Region
End Class
