Imports System.Drawing
Imports System.IO
Imports System.Windows.Forms
Imports DevExpress.Utils
Imports DevExpress.XtraGrid
Imports DevExpress.XtraGrid.Columns
Imports DevExpress.XtraGrid.Views.Grid
Imports DevExpress.XtraPrinting
Imports DigitalData.Modules.Config
Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.ZooFlow
Imports DigitalData.Modules.Language
Imports DevExpress.XtraGrid.Views.Base
Imports DevExpress.XtraGrid.Views.BandedGrid
Imports System.ComponentModel

Public Class frmDocumentResultList
    Implements IResultForm

    Private _LogConfig As LogConfig
    Private _Logger As Logger
    Private _Config As ConfigManager(Of DocumentResultConfig)
    Private _Environment As Environment
    Private _Params As DocumentResultParams
    Private _ResultLists As List(Of DocumentResult)

    Private _ActiveGrid As GridControl = Nothing
    Private _ActiveGridBand As GridBand = Nothing
    Private _ActiveRowHandle As Integer = Constants.NO_ROW_HANDLE

    Private Const COLUMN_ICON = "ICON"
    Private Const COLUMN_FILEPATH = "FULL_FILENAME"
    Private Const COLUMN_FILENAME = "Filename"
    Private Const COLUMN_DOCID = "DocID"

    Private _IsLoading As Boolean = True

    Public Property ShouldReturnToPreviousForm As Boolean = False Implements IResultForm.ShouldReturnToPreviousForm

    Public Sub New(LogConfig As LogConfig, Environment As Environment, Params As DocumentResultParams)
        ' Dieser Aufruf ist für den Designer erforderlich.
        InitializeComponent()

        ' Fügen Sie Initialisierungen nach dem InitializeComponent()-Aufruf hinzu.
        Dim oConfigPath As String = Path.Combine(Application.UserAppDataPath, "ResultList", Params.WindowGuid)

        _LogConfig = LogConfig
        _Logger = LogConfig.GetLogger()
        _Config = New ConfigManager(Of DocumentResultConfig)(LogConfig, oConfigPath, oConfigPath)
        _Environment = Environment
        _Params = Params
        _ResultLists = Params.Results
    End Sub

    Private Sub frmDocumentResultList_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Try
            ' Load config
            SplitContainerControl1.SplitterPosition = _Config.Config.SplitContainer1Distance
            SwitchMainContainerHorizontal.Checked = _Config.Config.SplitContainer1Horizontal
            SplitContainerControl2.SplitterPosition = _Config.Config.SplitContainer2Distance
            SwitchDetailContainerHorizontal.Checked = _Config.Config.SplitContainer2Horizontal

            If Utils.IsVisibleOnAnyScreen(_Config.Config.WindowLocation) Then
                If Utils.LocationIsVisible(_Config.Config.WindowLocation) Then
                    Location = _Config.Config.WindowLocation
                End If
                If Utils.SizeIsVisible(_Config.Config.WindowSize) Then
                    Size = _Config.Config.WindowSize
                End If
            End If

            ' Initialize Viewer with GDPicture.NET License
            DocumentViewer1.Init(_LogConfig, _Environment.Settings.GdPictureKey)

            AddHandler GridView1.FocusedRowChanged, AddressOf GridView_FocusedRowChanged
            AddHandler GridView2.FocusedRowChanged, AddressOf GridView_FocusedRowChanged
            AddHandler GridView3.FocusedRowChanged, AddressOf GridView_FocusedRowChanged

            Dim oTotalResults = 0

            For Each oList In _ResultLists
                oTotalResults += oList.Datatable.Rows.Count
            Next

            labelResultCount.Caption = String.Format(labelResultCount.Caption, oTotalResults)

            ' Load Grids
            For index = 0 To _ResultLists.Count - 1
                Select Case index
                    Case 0
                        Dim oResult As DocumentResult = _ResultLists.Item(0)
                        CreateDocumentGrid(GridView1, oResult.Datatable)
                        UpdateGridHeader(index, oResult.Datatable.Rows.Count)
                    Case 1
                        Dim oResult As DocumentResult = _ResultLists.Item(1)
                        CreateDocumentGrid(GridView2, oResult.Datatable)
                        UpdateGridHeader(index, oResult.Datatable.Rows.Count)

                    Case 2
                        Dim oResult As DocumentResult = _ResultLists.Item(2)
                        CreateDocumentGrid(GridView3, oResult.Datatable)
                        UpdateGridHeader(index, oResult.Datatable.Rows.Count)

                    Case Else
                        MessageBox.Show("You have more than three searches configured. This Window will only show the first three result lists!", Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                        Exit For
                End Select
            Next

            ' Hide Grids depending on Result count
            Select Case _ResultLists.Count
                Case 0
                    SplitContainerControl1.SetPanelCollapsed(True)
                    SplitContainerControl2.SetPanelCollapsed(True)

                    SwitchMainContainerHorizontal.Enabled = False
                    SwitchDetailContainerHorizontal.Enabled = False

                    MessageBox.Show("No Searches found.", Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
                Case 1
                    SplitContainerControl1.SetPanelCollapsed(True)
                    SplitContainerControl2.SetPanelCollapsed(True)

                    SwitchMainContainerHorizontal.Enabled = False
                    SwitchDetailContainerHorizontal.Enabled = False
                Case 2
                    SplitContainerControl2.SetPanelCollapsed(True)

                    SwitchDetailContainerHorizontal.Enabled = False
            End Select
        Catch ex As Exception
            _Logger.Error(ex)
            MessageBox.Show("Error while loading results:" & vbNewLine & vbNewLine & ex.Message, Text)
        Finally
            _IsLoading = False
        End Try
    End Sub

    Private Sub UpdateGridHeader(Index As Integer, Count As Integer)
        Select Case Index
            Case 0
                Dim oResult = _ResultLists.Item(0)
                GridBand1.Caption = $"{oResult.Title} ({Count})"

            Case 1
                Dim oResult = _ResultLists.Item(1)
                GridBand2.Caption = $"{oResult.Title} ({Count})"

            Case 2
                Dim oResult = _ResultLists.Item(2)
                GridBand3.Caption = $"{oResult.Title} ({Count})"
        End Select
    End Sub

    Private Sub GridView_FocusedRowChanged(sender As GridView, e As FocusedRowChangedEventArgs)
        _ActiveRowHandle = e.FocusedRowHandle

        If e.FocusedRowHandle >= 0 Then
            Dim oRow = sender.GetDataRow(e.FocusedRowHandle)
            Dim oFullPath = oRow.Item(COLUMN_FILEPATH)
            DocumentViewer1.LoadFile(oFullPath)
        End If
    End Sub

    Private Sub CreateDocumentGrid(GridView As GridView, Datatable As DataTable)
        Dim oMyDocDatatable As New DataTable
        Try
            'Die Icon Colum erstellen und konfigurieren
            oMyDocDatatable.Columns.Add(New DataColumn() With {
                .DataType = GetType(Image),
                .ColumnName = COLUMN_ICON,
                .Caption = ""
            })
            oMyDocDatatable.Columns.Add(New DataColumn() With {
                .DataType = GetType(String),
                .ColumnName = COLUMN_FILEPATH,
                .Caption = "Fullpath"
            })
            oMyDocDatatable.Columns.Add(New DataColumn() With {
                .DataType = GetType(Int32),
                .ColumnName = "DocID",
                .Caption = "DocID"
            })
            oMyDocDatatable.Columns.Add(New DataColumn() With {
                .DataType = GetType(String),
                .ColumnName = "Filename",
                .Caption = "Filename"
            })

            Dim oRestColArray As New List(Of String)
            For Each oCol As DataColumn In Datatable.Columns
                Dim onewColumn As New DataColumn()
                If oCol.ColumnName <> "DocID" And oCol.ColumnName <> COLUMN_FILEPATH And oCol.ColumnName <> "Filename" Then
                    onewColumn.DataType = GetType(String)
                    onewColumn.ColumnName = oCol.ColumnName
                    onewColumn.Caption = oCol.Caption
                    oMyDocDatatable.Columns.Add(onewColumn)
                    oRestColArray.Add(onewColumn.ColumnName)
                End If

            Next
            For Each oRow As DataRow In Datatable.Rows
                Dim oFullpath = oRow.Item(COLUMN_FILEPATH)
                Dim oDocID = oRow.Item("DocID")
                'Dim Folderpath = Path.GetDirectoryName(fullpath)
                Dim oFilename = IO.Path.GetFileName(oFullpath)
                Dim oFileextension = IO.Path.GetExtension(oFullpath)
                Dim oNewRow As DataRow
                oNewRow = oMyDocDatatable.NewRow()
                'Icon zuweisen
                Select Case oFileextension.ToUpper
                    Case ".csv".ToUpper
                        oNewRow.Item(0) = My.Resources.xls
                    Case ".txt".ToUpper
                        oNewRow.Item(0) = My.Resources.txt
                    Case ".pdf".ToUpper
                        oNewRow.Item(0) = My.Resources.pdf
                    Case ".doc".ToUpper
                        oNewRow.Item(0) = My.Resources.doc
                    Case ".docx".ToUpper
                        oNewRow.Item(0) = My.Resources.doc
                    Case ".xls".ToUpper
                        oNewRow.Item(0) = My.Resources.xls
                    Case ".xlsx".ToUpper
                        oNewRow.Item(0) = My.Resources.xls
                    Case ".xlsm".ToUpper
                        oNewRow.Item(0) = My.Resources.xls
                    Case ".ppt".ToUpper
                        oNewRow.Item(0) = My.Resources.ppt
                    Case ".pptx".ToUpper
                        oNewRow.Item(0) = My.Resources.ppt
                    Case ".dwg".ToUpper
                        oNewRow.Item(0) = My.Resources.dwg
                    Case ".dxf".ToUpper
                        oNewRow.Item(0) = My.Resources.dxf
                    Case ".msg".ToUpper
                        oNewRow.Item(0) = My.Resources._page
                    Case ".msg".ToUpper
                        oNewRow.Item(0) = My.Resources._page
                    Case ".tif".ToUpper
                        oNewRow.Item(0) = My.Resources.tiff
                    Case ".tiff".ToUpper
                        oNewRow.Item(0) = My.Resources.tiff
                    Case ".jpg".ToUpper
                        oNewRow.Item(0) = My.Resources.jpg
                    Case Else
                        oNewRow.Item(0) = My.Resources._blank
                End Select
                'Den Filepath mitgeben
                oNewRow.Item(1) = oFullpath
                oNewRow.Item(2) = oDocID
                oNewRow.Item(3) = oFilename

                Dim oIndex = 4 'Fängt bei 4 an, um die definierten Spalten zu überspringen
                For Each oColumnName As String In oRestColArray
                    Dim oRowValue
                    oRowValue = oRow.Item(oColumnName)
                    oNewRow.Item(oIndex) = oRowValue.ToString
                    oIndex += 1
                Next
                oMyDocDatatable.Rows.Add(oNewRow)
            Next

            Dim oGridControl As GridControl = GridView.GridControl
            oGridControl.DataSource = oMyDocDatatable
            oGridControl.ForceInitialize()
            Try
                GridView.Columns.Item("DocID").Visible = False
            Catch ex As Exception
            End Try
            Try
                GridView.Columns.Item(COLUMN_FILEPATH).Visible = False
            Catch ex As Exception
            End Try

            Dim oCreated, oChanged As String
            If _Environment.User.Language <> "de-DE" Then
                oChanged = "Changed"
                oCreated = "Created"
            Else
                oChanged = "Geändert"
                oCreated = "Erstellt"
            End If

            Dim oCreatedColumn = GridView.Columns(oCreated)
            If Not IsNothing(oCreatedColumn) Then
                oCreatedColumn.DisplayFormat.FormatType = FormatType.DateTime
                oCreatedColumn.DisplayFormat.FormatString = _Environment.User.DateFormat & " HH:MM:ss"
            End If

            Dim oChangedColumn = GridView.Columns(oChanged)
            If Not IsNothing(oChangedColumn) Then
                oChangedColumn.DisplayFormat.FormatType = FormatType.DateTime
                oChangedColumn.DisplayFormat.FormatString = _Environment.User.DateFormat & " HH:MM:ss"
            End If

            ' Alle Spalten aus ReadOnly setzen, danach werden alle passenden auf nicht ReadOnly gesetzt
            For Each oColumn As GridColumn In GridView.Columns
                oColumn.OptionsColumn.AllowEdit = False
            Next

            GridView.Columns.Item(COLUMN_ICON).MaxWidth = 24
            GridView.Columns.Item(COLUMN_ICON).MinWidth = 24
            GridView.OptionsView.BestFitMaxRowCount = -1
            GridView.BestFitColumns(True)
        Catch ex As Exception
            _Logger.Error(ex)
        End Try
    End Sub

    Private Sub SwitchMainContainerHorizontal_CheckedChanged(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles SwitchMainContainerHorizontal.CheckedChanged
        SplitContainerControl1.Horizontal = SwitchMainContainerHorizontal.Checked

        If _Config IsNot Nothing And _IsLoading = False Then
            _Config.Config.SplitContainer1Horizontal = SwitchMainContainerHorizontal.Checked
            _Config.Save()
        End If
    End Sub

    Private Sub SwitchDetailContainerHorizontal2_CheckedChanged(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles SwitchDetailContainerHorizontal.CheckedChanged
        SplitContainerControl2.Horizontal = SwitchDetailContainerHorizontal.Checked

        If _Config IsNot Nothing And _IsLoading = False Then
            _Config.Config.SplitContainer2Horizontal = SwitchDetailContainerHorizontal.Checked
            _Config.Save()
        End If
    End Sub

    Private Sub BarButtonItemExportGrid1_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItemExportGrid1.ItemClick
        Dim oActiveGrid = GetActiveGridControl()

        If oActiveGrid IsNot Nothing Then
            Dim oGridBand = _ActiveGridBand

            XtraSaveFileDialog.FileName = Utils.ConvertTextToSlug(oGridBand.Caption) & ".xlsx"
            XtraSaveFileDialog.DefaultExt = ".xlsx"

            If XtraSaveFileDialog.ShowDialog() = Windows.Forms.DialogResult.OK Then
                Dim oOptions As New XlsxExportOptions() With {
                    .ExportMode = XlsxExportMode.SingleFile
                }
                oActiveGrid.ExportToXlsx(XtraSaveFileDialog.FileName, oOptions)
            End If

        Else
            MessageBox.Show("Bitte wählen Sie eine Tabelle aus, die Sie exportieren möchten", Text, MessageBoxButtons.OK)
        End If
    End Sub

    Private Sub SplitContainerControl1_SplitterPositionChanged(sender As Object, e As EventArgs) Handles SplitContainerControl1.SplitterPositionChanged
        If _IsLoading = False Then
            _Config.Config.SplitContainer1Distance = SplitContainerControl1.SplitterPosition
            _Config.Save()
        End If
    End Sub

    Private Sub SplitContainerControl2_SplitterPositionChanged(sender As Object, e As EventArgs) Handles SplitContainerControl2.SplitterPositionChanged
        If _IsLoading = False Then
            _Config.Config.SplitContainer2Distance = SplitContainerControl2.SplitterPosition
            _Config.Save()
        End If
    End Sub

    Private Function GetActiveRow() As DataRow
        Dim oActiveGrid = GetActiveGridControl()
        Dim oActiveRowhandle = GetActiveRowHandle()

        If oActiveGrid IsNot Nothing And oActiveRowhandle <> Constants.NO_ROW_HANDLE Then
            Dim oView = DirectCast(oActiveGrid.DefaultView, GridView)
            Dim oRow = oView.GetDataRow(oActiveRowhandle)
            Return oRow
        Else
            Return Nothing
        End If
    End Function

    Private Function GetActiveGridControl() As GridControl
        If _ActiveGrid Is Nothing Then
            Return Nothing
        End If

        Return _ActiveGrid
    End Function

    Private Function GetActiveRowHandle() As Integer
        If _ActiveRowHandle = Constants.NO_ROW_HANDLE Then
            Return Constants.NO_ROW_HANDLE
        End If

        Return _ActiveRowHandle
    End Function

    Private Sub GridControl_Enter(sender As GridControl, e As EventArgs) Handles GridControl1.Enter, GridControl2.Enter, GridControl3.Enter
        _ActiveGrid = sender
        SetActiveGridBand()
    End Sub

    Private Sub GridView1_FocusedRowChanged(sender As GridView, e As FocusedRowChangedEventArgs) Handles GridView1.FocusedRowChanged, GridView2.FocusedRowChanged, GridView3.FocusedRowChanged
        Dim oGrid As GridControl = sender.GridControl
        _ActiveGrid = oGrid
    End Sub

    Private Sub SetActiveGridBand()
        If _ActiveGrid.Equals(GridControl1) Then
            _ActiveGridBand = GridBand1
        ElseIf _ActiveGrid.Equals(GridControl2) Then
            _ActiveGridBand = GridBand2
        ElseIf _ActiveGrid.Equals(GridControl3) Then
            _ActiveGridBand = GridBand3
        Else
            _ActiveGridBand = Nothing
        End If
    End Sub

    Private Sub OpenFolderPath()
        Try
            Dim oRow = GetActiveRow()

            If oRow IsNot Nothing Then
                Dim oFilename = oRow.Item(COLUMN_FILEPATH)
                Dim oDirectory = IO.Path.GetDirectoryName(oFilename)
                Process.Start(oDirectory)
            End If
        Catch ex As Exception
            _Logger.Error(ex)
        End Try
    End Sub

    Private Sub OpenFile()
        Try
            Dim oRow = GetActiveRow()

            If oRow IsNot Nothing Then
                Dim oFilename = oRow.Item(COLUMN_FILEPATH)
                Process.Start(oFilename)
            End If
        Catch ex As Exception
            _Logger.Error(ex)
        End Try
    End Sub

    Private Sub CopyFileName()
        Try
            Dim oRow = GetActiveRow()

            If oRow IsNot Nothing Then
                Dim oFilename = oRow.Item(COLUMN_FILEPATH)
                Clipboard.SetText(oFilename)
            End If
        Catch ex As Exception
            _Logger.Error(ex)
        End Try
    End Sub

    Private Sub BarButtonItem1_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItem1.ItemClick
        OpenFile()
    End Sub

    Private Sub BarButtonItem2_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItem2.ItemClick
        OpenFolderPath()
    End Sub

    Private Sub BarButtonItem3_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItem3.ItemClick
        CopyFileName()
    End Sub

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

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

    Private Sub PfadInZwischenablageKopierenToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles PfadInZwischenablageKopierenToolStripMenuItem.Click
        CopyFileName()
    End Sub

    Private Sub GridView1_ColumnFilterChanged(sender As GridView, e As EventArgs) Handles GridView1.ColumnFilterChanged
        Dim oRowCount = sender.RowCount
        UpdateGridHeader(0, oRowCount)
    End Sub

    Private Sub GridView2_ColumnFilterChanged(sender As GridView, e As EventArgs) Handles GridView2.ColumnFilterChanged
        Dim oRowCount = sender.RowCount
        UpdateGridHeader(1, oRowCount)
    End Sub

    Private Sub GridView3_ColumnFilterChanged(sender As GridView, e As EventArgs) Handles GridView3.ColumnFilterChanged
        Dim oRowCount = sender.RowCount
        UpdateGridHeader(2, oRowCount)
    End Sub

    Private Sub BarButtonItem4_ItemClick(sender As Object, e As DevExpress.XtraBars.ItemClickEventArgs) Handles BarButtonItem4.ItemClick
        ShouldReturnToPreviousForm = True
        Close()
    End Sub

    Private Sub frmDocumentResultList_Closing(sender As Object, e As CancelEventArgs) Handles Me.Closing
        Try
            _Config.Config.WindowLocation = Location
            _Config.Config.WindowSize = Size
            _Config.Save()
        Catch ex As Exception
            _Logger.Error(ex)
        End Try
    End Sub

    Private Sub GridControl_DoubleClick(sender As Object, e As EventArgs) Handles GridControl1.DoubleClick, GridControl2.DoubleClick, GridControl3.DoubleClick
        OpenFile()
    End Sub


End Class