' *
' * The project site is at: http://sourceforge.jp/projects/fishbornas/
' *
' * First author tiritomato 2012.
' *
' * Distributed under the FishbornArchiveShelf License (See
' *  file "Licenses/License.txt" contained in a project, or the following link.
' *  http://sourceforge.jp/projects/fishbornas/scm/svn/blobs/head/trunk/Licenses/License.txt)
' *
' * 2012.06.07 Initial Revision (tiritomato)
' *

Public Class FileListPanel
    Implements IAppBase

    Private Class FileListItem
        Inherits Logic.Collections.KeyBase(Of String)
        Public Row As DataGridViewRow
        Public ScanResult As AppBase.ArchiveItemScanArgs.PayloadData
        Public Sub New()
            MyBase.New()
            Row = Nothing
            ScanResult = Nothing
        End Sub
        Public Sub New(ByVal v As String, Optional ByVal setRow As DataGridViewRow = Nothing)
            MyBase.New(v)
            Row = setRow
            ScanResult = Nothing
        End Sub
    End Class

    Private idxColPlan As Integer
    Private idxColPresetName As Integer
    Private idxColDeleteTarget As Integer
    Private idxColName As Integer
    Private idxColFolder As Integer
    Private idxColPath As Integer
    Private idxColByteSize As Integer
    Private idxColDCreated As Integer
    Private idxColDLastAccess As Integer
    Private idxColDLWrited As Integer
    Private idxColLast As Integer

    Private dicFileList As New FileListItem.Collection(Of FileListItem)
    Private dicFileListFromDir As New Collections.Generic.Dictionary(Of String, Collections.Generic.List(Of FileListItem))

    Private ColumnLayoutChanged As New Logic.UniqueEvents(Of Windows.Forms.DataGridViewColumnEventArgs)
    Private CellValueChanged As New Logic.UniqueEvents(Of Windows.Forms.DataGridViewCellEventArgs)

    '///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Private m_AppBase As AppBase = Nothing
    Public Property AppBase As AppBase Implements IAppBase.AppBase
        Get
            Return m_AppBase
        End Get
        Set(ByVal value As AppBase)

            ColumnLayoutChanged.Clear()
            CellValueChanged.Clear()

            lstFile.ContextMenuStrip = Nothing
            If m_AppBase IsNot Nothing Then m_AppBase.Echoing.ArchiveItemScan.Remove(AddressOf ArchiveItemScan)

            m_AppBase = value

            If m_AppBase Is Nothing Then Return

            m_AppBase.Config.FileListColumnInf.Apply(lstFile)

            ColumnLayoutChanged.Add(AddressOf lstFile_ColumnLayoutChangedImpl)
            CellValueChanged.Add(AddressOf lstFile_CellValueChangedImpl)

            lstFile.ContextMenuStrip = New Logic.DataGridViewUtility.ColumnVisibleControlMenu({"colPlan"}, AppBase.Config.FileListColumnInf, ctxFileList)
            m_AppBase.Echoing.ArchiveItemScan.Add(AddressOf ArchiveItemScan)

        End Set
    End Property

    Private Sub FileListPanel_Disposed(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Disposed
        ctxFileListPlanCancelDeleteTarget.DropDownItems.Clear()
        AppBase = Nothing
    End Sub

    '///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    Private Sub ReportDialogFileList_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        idxColPlan = lstFile.Columns("colPlan").Index
        idxColPresetName = lstFile.Columns("colPresetName").Index
        idxColDeleteTarget = lstFile.Columns("colDeleteTarget").Index
        idxColName = lstFile.Columns("colName").Index
        idxColFolder = lstFile.Columns("colFolder").Index
        idxColPath = lstFile.Columns("colPath").Index
        idxColByteSize = lstFile.Columns("colByteSize").Index
        idxColDCreated = lstFile.Columns("colDateCreated").Index
        idxColDLastAccess = lstFile.Columns("colDateAccess").Index
        idxColDLWrited = lstFile.Columns("colDateLastWrited").Index
        idxColLast = lstFile.Columns("colLast").Index

        ctxFileListFileHiddenOn.Tag = True
        ctxFileListFileHiddenOff.Tag = False
        ctxFileListFolderHiddenOn.Tag = True
        ctxFileListFolderHiddenOff.Tag = False

        ctxFileListPlanScan.Image = AppBase.ShellIcon.GetSingletonInstance(AppBase.ShellIcon.HANDLE.START_SCAN)
        ctxFileListPlanCancel.Image = AppBase.ShellIcon.GetSingletonInstance(AppBase.ShellIcon.HANDLE.CANCEL)
        ctxFileListPlanExecute.Image = AppBase.ShellIcon.GetSingletonInstance(AppBase.ShellIcon.HANDLE.START_EXEC)
        ctxFileListPlanCancelUserCmd.Image = AppBase.ShellIcon.GetSingletonInstance(AppBase.ShellIcon.HANDLE.CANCEL_BATCMD)
        ctxFileListPlanCancelIsDelete.Image = AppBase.ShellIcon.GetSingletonInstance(AppBase.ShellIcon.HANDLE.CANCEL_ISDELETE)
        ctxFileListPlanCancelDeleteTarget.Image = AppBase.ShellIcon.GetSingletonInstance(AppBase.ShellIcon.HANDLE.CANCEL_HASDELETE)

    End Sub

    '///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Private Function FileList_AddRow(ByRef strPath As String) As FileListItem

        If String.IsNullOrWhiteSpace(strPath) Then Return Nothing

        Dim strExt As String = IO.Path.GetExtension(strPath)

        Dim objRet As FileListItem
        If dicFileList.Contains(strPath) Then
            objRet = dicFileList(strPath)
        Else
            Try
                Dim strDir As String = IO.Path.GetDirectoryName(strPath)
                objRet = New FileListItem(strPath, lstFile.Rows(lstFile.Rows.Add()))
                dicFileList.Add(objRet)
                If dicFileListFromDir.ContainsKey(strDir) = False OrElse dicFileListFromDir(strDir) Is Nothing Then
                    dicFileListFromDir.Item(strDir) = New Collections.Generic.List(Of FileListItem)
                End If
                dicFileListFromDir(strDir).Add(objRet)
                Dim Path As New Logic.FileSystem.Path(strPath)
                objRet.Row.Cells(idxColName).Value = Path.Name.ToString
                objRet.Row.Cells(idxColFolder).Value = Path.Parent.Name.ToString
                objRet.Row.Cells(idxColPath).Value = strPath
                objRet.Row.Cells(idxColByteSize).ValueType = GetType(Integer)
                objRet.Row.Cells(idxColDCreated).ValueType = GetType(Date)
                objRet.Row.Cells(idxColDLastAccess).ValueType = GetType(Date)
                objRet.Row.Cells(idxColDLWrited).ValueType = GetType(Date)
                PresentScanResultToRow(objRet)
            Catch ex As Exception
#If DEBUG Then
                Throw
#End If
                objRet = Nothing
            End Try
        End If

        Return objRet

    End Function

    Private Sub FileList_RemoveRow()
        If lstFile.SelectedRows IsNot Nothing AndAlso 0 < lstFile.SelectedRows.Count Then
            For Each Row As DataGridViewRow In lstFile.SelectedRows
                FileList_RemoveRow(Row)
            Next
        End If
    End Sub

    Private Sub FileList_RemoveRow(ByRef Row As DataGridViewRow)
        Dim strPath As String = Row.Cells(idxColPath).Value
        If Not String.IsNullOrWhiteSpace(strPath) Then
            Dim strDir As String = IO.Path.GetDirectoryName(strPath)
            dicFileList.Remove(strPath)
            If dicFileListFromDir.ContainsKey(strDir) Then
                Dim itemFileListDeleteTarget As New FileListItem
                For Each itemFileList As FileListItem In dicFileListFromDir(strDir)
                    If itemFileList.Row.Equals(Row) Then
                        itemFileListDeleteTarget = itemFileList
                        Exit For
                    End If
                Next
                If Not (itemFileListDeleteTarget.Row Is Nothing) Then dicFileListFromDir(strDir).Remove(itemFileListDeleteTarget)
                If dicFileListFromDir(strDir).Count <= 0 Then dicFileListFromDir.Remove(strDir)
            End If
        End If
        AppBase.Echoing.ArchiveItemRemoved.Echo(strPath)
        Row.DataGridView.Rows.Remove(Row)
    End Sub

    Private Sub PresentScanResultToRow(ByVal item As FileListItem)

        Dim d As New EventHandler(Of System.Windows.Forms.DataGridViewCellEventArgs)(AddressOf lstFile_CellValueChangedImpl)
        CellValueChanged.Remove(d)
        Try
            If item Is Nothing OrElse item.Row Is Nothing Then Return

            If (Not item.ScanResult Is Nothing) AndAlso (item.ScanResult.IsDelete Or item.ScanResult.HasDelete Or item.ScanResult.IsUserCmd) Then
                item.Row.Cells(idxColPlan).ReadOnly = False
                item.Row.Cells(idxColPlan).Value = item.ScanResult.IsUserChecked
            Else
                item.Row.Cells(idxColPlan).ReadOnly = True
                item.Row.Cells(idxColPlan).Value = Nothing
            End If

            Dim pad As Windows.Forms.Padding = item.Row.Cells(idxColPlan).Style.Padding
            pad.Left = IIf((Not item.ScanResult Is Nothing) AndAlso item.ScanResult.HasDelete, 40, 20)
            item.Row.Cells(idxColPlan).Style.Padding = pad

            If Not item.ScanResult Is Nothing Then

                If item.ScanResult.IsUserCmd AndAlso Not item.ScanResult.PresetName Is Nothing Then
                    item.Row.Cells(idxColPresetName).Value = item.ScanResult.PresetName
                Else
                    item.Row.Cells(idxColPresetName).Value = Nothing
                End If

                If Not item.ScanResult.DeleteFiles Is Nothing AndAlso 0 < item.ScanResult.DeleteFiles.Count Then
                    Dim buf() As String = item.ScanResult.DeleteFiles.ToArray
                    If 1 < item.ScanResult.DeleteFiles.Count Then
                        For idx As Integer = 0 To item.ScanResult.DeleteFiles.Count - 1
                            buf(idx) = IO.Path.GetFileName(buf(idx))
                        Next
                    End If
                    item.Row.Cells(idxColDeleteTarget).Value = String.Join(" , ", item.ScanResult.DeleteFiles)
                Else
                    item.Row.Cells(idxColDeleteTarget).Value = Nothing
                End If

                Dim clrCellFore As Drawing.Color
                If item.ScanResult.FileExists = False Then
                    clrCellFore = System.Drawing.SystemColors.GrayText
                    item.Row.Cells(idxColByteSize).Value = Nothing
                    item.Row.Cells(idxColDCreated).Value = Nothing
                    item.Row.Cells(idxColDLastAccess).Value = Nothing
                    item.Row.Cells(idxColDLWrited).Value = Nothing
                Else
                    clrCellFore = System.Drawing.SystemColors.WindowText
                    item.Row.Cells(idxColByteSize).Value = item.ScanResult.FileSize
                    item.Row.Cells(idxColDCreated).Value = item.ScanResult.CreationTime
                    item.Row.Cells(idxColDLastAccess).Value = item.ScanResult.LastAccessTime
                    item.Row.Cells(idxColDLWrited).Value = item.ScanResult.LastWriteTime
                End If

                If item.Row.Cells(idxColName).Style.ForeColor <> clrCellFore Then item.Row.Cells(idxColName).Style.ForeColor = clrCellFore
                If item.Row.Cells(idxColPath).Style.ForeColor <> clrCellFore Then item.Row.Cells(idxColPath).Style.ForeColor = clrCellFore

            End If

        Catch ex As Exception
            Throw

        Finally
            CellValueChanged.Add(d)
        End Try

        item.Row.DataGridView.Invalidate()

    End Sub

    '//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Private Sub ctxFileList_Opening(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles ctxFileList.Opening

        ctxFileListPlanScan.Enabled = AppBase.MainTask.IsWorkOut
        ctxFileListIsDropFolderRecursiveLoad.Checked = AppBase.Config.ExportableGroup.IsDropFolderRecursiveLoad

        Dim strCheckingName As String = ""

        Dim ctUserCmd As Integer = 0
        Dim PresetName As String = Nothing
        Dim isExecutableItem As Boolean = False
        Dim isCancelDelete As Boolean = False
        Dim ctCancelDeleteTarget As Integer = 0
        Dim DeleteTargets As FileListItem = Nothing
        For Each Row As DataGridViewRow In lstFile.SelectedRows
            Dim key As String = Nothing
            Dim item As FileListItem = Nothing
            If TypeOf Row.Cells(idxColPath).Value Is String Then key = Row.Cells(idxColPath).Value
            If Not key Is Nothing Then item = dicFileList(key)
            If Not item Is Nothing AndAlso Not item.ScanResult Is Nothing Then
                If item.ScanResult.IsUserCmd Then
                    ctUserCmd += 1
                    If ctUserCmd = 1 Then PresetName = item.ScanResult.PresetName
                End If
                isCancelDelete = isCancelDelete Or item.ScanResult.IsDelete
                If item.ScanResult.HasDelete Then
                    ctCancelDeleteTarget += 1
                    If DeleteTargets Is Nothing Then DeleteTargets = item
                End If
            End If
        Next

        ctxFileListPlanExecute.Enabled = 0 < ctUserCmd
        ctxFileListPlanCancel.Enabled = (0 < ctUserCmd) Or isCancelDelete Or (0 < ctCancelDeleteTarget)
        ctxFileListPlanCancelUserCmd.Enabled = (0 < ctUserCmd)
        ctxFileListPlanCancelIsDelete.Enabled = isCancelDelete

        ctxFileListPlanCancelDeleteTarget.DropDownItems.Clear()

        If 1 = ctCancelDeleteTarget Then
            ctxFileListPlanCancelDeleteTarget.Enabled = True
            ctxFileListPlanCancelDeleteTarget.Tag = Nothing
            ctxFileListPlanCancelDeleteTarget.Text = "削除対象をキャンセル"
            If 1 < DeleteTargets.ScanResult.DeleteFiles.Count Then
                Dim menuAdd As Windows.Forms.ToolStripMenuItem = ctxFileListPlanCancelDeleteTarget.DropDownItems.Add("すべての削除対象をキャンセルする")
                If Not menuAdd Is Nothing Then AddHandler menuAdd.Click, AddressOf ctxFileListPlanCancelDeleteTarget_Click
            End If
            If 0 < DeleteTargets.ScanResult.DeleteFiles.Count Then
                If 0 < ctxFileListPlanCancelDeleteTarget.DropDownItems.Count Then
                    ctxFileListPlanCancelDeleteTarget.DropDownItems.Add(New ToolStripSeparator())
                End If
                For Each path As Logic.FileSystem.Path In DeleteTargets.ScanResult.DeleteFiles
                    Dim menuAdd As Windows.Forms.ToolStripMenuItem = ctxFileListPlanCancelDeleteTarget.DropDownItems.Add(path.ToString)
                    If Not menuAdd Is Nothing Then
                        menuAdd.Tag = DeleteTargets
                        AddHandler menuAdd.Click, AddressOf ctxFileListPlanCancelDeleteTarget_Click
                    End If
                Next
            End If

        ElseIf 1 < ctCancelDeleteTarget Then
            ctxFileListPlanCancelDeleteTarget.Enabled = True
            ctxFileListPlanCancelDeleteTarget.Tag = Nothing
            ctxFileListPlanCancelDeleteTarget.Text = "すべての削除対象をキャンセル"
        Else
            ctxFileListPlanCancelDeleteTarget.Enabled = False
            ctxFileListPlanCancelDeleteTarget.Tag = Nothing
            ctxFileListPlanCancelDeleteTarget.Text = "削除対象をキャンセル"
        End If

    End Sub

    Private Sub ctxFileListFileHidden_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ctxFileListFileHiddenOn.Click,
                                                                                                                ctxFileListFileHiddenOff.Click
        If lstFile.SelectedRows Is Nothing OrElse lstFile.SelectedRows.Count <= 0 Then Exit Sub
        For Each objRow As DataGridViewRow In lstFile.SelectedRows
            Try
                Dim item As FileListItem = dicFileList(CStr(objRow.Cells(idxColPath).Value))
                If Not item Is Nothing Then
                    If item.ScanResult Is Nothing Then item.ScanResult = New AppBase.ArchiveItemScanArgs.PayloadData
                    item.ScanResult.FileHidden(item.Key) = CBool(sender.Tag)
                    PresentScanResultToRow(item)
                End If
            Catch ex As Exception
#If DEBUG Then
                Throw
#End If
            End Try
        Next

    End Sub

    Private Sub ctxFileListFolderHidden_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ctxFileListFolderHiddenOn.Click,
                                                                                                                  ctxFileListFolderHiddenOff.Click
        If lstFile.SelectedRows Is Nothing OrElse lstFile.SelectedRows.Count <= 0 Then Exit Sub
        For Each objRow As DataGridViewRow In lstFile.SelectedRows
            Try
                Dim item As FileListItem = dicFileList(CStr(objRow.Cells(idxColPath).Value))
                If Not item Is Nothing Then
                    If item.ScanResult Is Nothing Then item.ScanResult = New AppBase.ArchiveItemScanArgs.PayloadData
                    item.ScanResult.DirHidden(item.Key) = CBool(sender.Tag)
                    PresentScanResultToRow(item)
                End If
            Catch ex As Exception
#If DEBUG Then
                Throw
#End If
            End Try
        Next

    End Sub

    Private Sub ctxFileListIsDropFolderRecursiveLoad_CheckedChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ctxFileListIsDropFolderRecursiveLoad.CheckedChanged
        AppBase.Config.ExportableGroup.IsDropFolderRecursiveLoad = ctxFileListIsDropFolderRecursiveLoad.Checked
    End Sub

    Private Sub ctxFileListPlanCancelUserCmd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ctxFileListPlanCancelUserCmd.Click
        For Each Row As DataGridViewRow In lstFile.SelectedRows
            Dim key As String = Nothing
            Dim item As FileListItem = Nothing
            If TypeOf Row.Cells(idxColPath).Value Is String Then key = Row.Cells(idxColPath).Value
            If Not key Is Nothing Then item = dicFileList(key)
            If Not item Is Nothing AndAlso Not item.ScanResult Is Nothing AndAlso item.ScanResult.IsUserCmd Then
                item.ScanResult.IsUserCmd = False
                PresentScanResultToRow(item)
            End If
        Next
    End Sub

    Private Sub ctxFileListPlanCancelIsDelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ctxFileListPlanCancelIsDelete.Click
        For Each Row As DataGridViewRow In lstFile.SelectedRows
            Dim key As String = Nothing
            Dim item As FileListItem = Nothing
            If TypeOf Row.Cells(idxColPath).Value Is String Then key = Row.Cells(idxColPath).Value
            If Not key Is Nothing Then item = dicFileList(key)
            If Not item Is Nothing AndAlso Not item.ScanResult Is Nothing AndAlso item.ScanResult.IsDelete Then
                item.ScanResult.IsDelete = False
                PresentScanResultToRow(item)
            End If
        Next
    End Sub

    Private Sub ctxFileListPlanCancelDeleteTarget_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim s As Windows.Forms.ToolStripMenuItem = TryCast(sender, Windows.Forms.ToolStripMenuItem)
        If Not s Is Nothing Then
            Dim DeleteTargets As FileListItem = TryCast(s.Tag, FileListItem)
            If Not DeleteTargets Is Nothing Then
                DeleteTargets.ScanResult.DeleteFiles.Remove(s.Text)
                If DeleteTargets.ScanResult.DeleteFiles.Count <= 0 Then DeleteTargets.ScanResult.DeleteFiles = Nothing
            Else
                For Each Row As DataGridViewRow In lstFile.SelectedRows
                    Dim key As String = Nothing
                    Dim item As FileListItem = Nothing
                    If TypeOf Row.Cells(idxColPath).Value Is String Then key = Row.Cells(idxColPath).Value
                    If Not key Is Nothing Then item = dicFileList(key)
                    If Not item Is Nothing AndAlso Not item.ScanResult Is Nothing Then item.ScanResult.DeleteFiles = Nothing
                Next
            End If
            RemoveHandler s.Click, AddressOf ctxFileListPlanCancelDeleteTarget_Click
        End If
    End Sub

    Private Sub ctxFileListPlanCancelUserCmd_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles ctxFileListPlanCancelUserCmd.MouseEnter
        ctxFileListPlanCancelUserCmd.Image = AppBase.ShellIcon.GetSingletonInstance(AppBase.ShellIcon.HANDLE.CANCEL_BATCMD_SELECTED)
    End Sub

    Private Sub ctxFileListPlanCancelUserCmd_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles ctxFileListPlanCancelUserCmd.MouseLeave
        ctxFileListPlanCancelUserCmd.Image = AppBase.ShellIcon.GetSingletonInstance(AppBase.ShellIcon.HANDLE.CANCEL_BATCMD)
    End Sub

    Private Sub ctxFileListPlanCancelIsDelete_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles ctxFileListPlanCancelIsDelete.MouseEnter
        ctxFileListPlanCancelIsDelete.Image = AppBase.ShellIcon.GetSingletonInstance(AppBase.ShellIcon.HANDLE.CANCEL_ISDELETE_SELECTED)
    End Sub

    Private Sub ctxFileListPlanCancelIsDelete_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles ctxFileListPlanCancelIsDelete.MouseLeave
        ctxFileListPlanCancelIsDelete.Image = AppBase.ShellIcon.GetSingletonInstance(AppBase.ShellIcon.HANDLE.CANCEL_ISDELETE)
    End Sub

    Private Sub ctxFileListPlanCancelDeleteTarget_MouseEnter(ByVal sender As Object, ByVal e As System.EventArgs) Handles ctxFileListPlanCancelDeleteTarget.MouseEnter
        ctxFileListPlanCancelDeleteTarget.Image = AppBase.ShellIcon.GetSingletonInstance(AppBase.ShellIcon.HANDLE.CANCEL_HASDELETE_SELECTED)
    End Sub

    Private Sub ctxFileListPlanCancelDeleteTarget_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles ctxFileListPlanCancelDeleteTarget.MouseLeave
        ctxFileListPlanCancelDeleteTarget.Image = AppBase.ShellIcon.GetSingletonInstance(AppBase.ShellIcon.HANDLE.CANCEL_HASDELETE)
    End Sub

    '////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    Private Sub lstFile_CellValueChangedImpl(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs)
        If e.ColumnIndex = idxColPlan Then
            Try
                Dim item As FileListItem = dicFileList(CStr(lstFile.Rows(e.RowIndex).Cells(idxColPath).Value))
                If Not item Is Nothing Then
#If DEBUG Then
                    Debug.Assert(Not item.ScanResult Is Nothing)
#End If
                    If item.ScanResult Is Nothing Then item.ScanResult = New AppBase.ArchiveItemScanArgs.PayloadData
                    item.ScanResult.IsUserChecked = CBool(lstFile(e.ColumnIndex, e.RowIndex).Value)
                End If
            Catch ex As Exception
#If DEBUG Then
                Throw
#End If
            End Try
        End If
    End Sub

    Private Sub lstFile_CellValueChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles lstFile.CellValueChanged
        CellValueChanged.Invoke(sender, e)
    End Sub

    Private Sub lstFile_ColumnLayoutChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewColumnEventArgs) _
                                                                                        Handles lstFile.ColumnDisplayIndexChanged, lstFile.ColumnWidthChanged
        ColumnLayoutChanged.Invoke(sender, e)
    End Sub

    Private Sub lstFile_ColumnLayoutChangedImpl(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewColumnEventArgs)
        AppBase.Config.FileListColumnInf.Present(lstFile)
    End Sub

    Private Sub lstFile_CellContentDoubleClick(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles lstFile.CellContentDoubleClick
        If AppBase IsNot Nothing And lstFile.SelectedRows.Count = 1 Then
            ctxFileListFlush_Click(Nothing, Nothing)
            AppBase.MainTask.EnumEntry(lstFile(idxColPath, lstFile.SelectedRows(0).Index).Value)
        End If
    End Sub

    Private Sub lstFile_CellFormatting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellFormattingEventArgs) Handles lstFile.CellFormatting
        If Not e.Value Is Nothing And 0 <= e.RowIndex Then
            If e.ColumnIndex = idxColByteSize Then
                If TypeOf e.Value Is Integer OrElse TypeOf e.Value Is Long Then
                    e.Value = Logic.FileSystem.ByteSizeString(e.Value)
                    e.FormattingApplied = True
                End If
            End If
        End If
    End Sub

    Private Sub lstFile_CellPainting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellPaintingEventArgs) Handles lstFile.CellPainting

        Dim partPaint As DataGridViewPaintParts = e.PaintParts

        If 0 <= e.RowIndex Then

            If lstFile.SelectedRows.Count = 1 Then
                ' Single Row Mode
                If lstFile.Columns(e.ColumnIndex).Frozen = False Then partPaint = partPaint And (Not DataGridViewPaintParts.Focus)
                If (Not lstFile.CurrentCell Is Nothing) AndAlso (e.ColumnIndex <> lstFile.CurrentCell.ColumnIndex And lstFile.Columns(lstFile.CurrentCell.ColumnIndex).Frozen = False) Then
                    partPaint = partPaint And (Not DataGridViewPaintParts.SelectionBackground)
                End If
            Else
                ' Multi Row Mode
                partPaint = partPaint And (Not DataGridViewPaintParts.Focus)
            End If

            Try
                Select Case e.ColumnIndex

                    Case idxColPlan
                        Dim item As FileListItem = dicFileList(lstFile(idxColPath, e.RowIndex).Value.ToString)
                        If Not item.ScanResult Is Nothing AndAlso item.ScanResult.FileExists Then
                            e.PaintBackground(e.ClipBounds, (partPaint And DataGridViewPaintParts.SelectionBackground) = DataGridViewPaintParts.SelectionBackground)
                            Dim img As Drawing.Bitmap = Nothing
                            If item.ScanResult.IsDelete Then
                                img = AppBase.ShellIcon.GetSingletonInstance(AppBase.ShellIcon.HANDLE.STATE_ISDELETE)
                            ElseIf item.ScanResult.IsFilter Then
                                img = AppBase.ShellIcon.GetSingletonInstance(AppBase.ShellIcon.HANDLE.STATE_ISFILTER)
                            ElseIf item.ScanResult.IsUserCmd Then
                                img = AppBase.ShellIcon.GetSingletonInstance(AppBase.ShellIcon.HANDLE.STATE_BATCMD)
                            End If
                            If Not img Is Nothing Then
                                e.Graphics.DrawImage(img, e.CellBounds.X + 2, e.CellBounds.Y + CInt(Fix((e.CellBounds.Height - img.Height) / 2)), img.Width, img.Height)
                            End If
                            If item.ScanResult.HasDelete Then
                                img = AppBase.ShellIcon.GetSingletonInstance(AppBase.ShellIcon.HANDLE.STATE_HASDELETE)
                                e.Graphics.DrawImage(img, e.CellBounds.X + 22, e.CellBounds.Y + CInt(Fix((e.CellBounds.Height - img.Height) / 2)), img.Width, img.Height)
                            End If
                            partPaint = partPaint And (Not DataGridViewPaintParts.Background)
                        End If

                    Case idxColName
                        Dim item As FileListItem = dicFileList(lstFile(idxColPath, e.RowIndex).Value.ToString)
                        If Not item.ScanResult Is Nothing AndAlso item.ScanResult.FileExists Then
                            e.PaintBackground(e.ClipBounds, (partPaint And DataGridViewPaintParts.SelectionBackground) = DataGridViewPaintParts.SelectionBackground)
                            Dim img As Drawing.Bitmap = Logic.FileSystem.GetSystemIcon(item.Key)
                            If Not img Is Nothing Then
                                If item.ScanResult.FileHidden = False Then
                                    e.Graphics.DrawImage(img, e.CellBounds.X + 2, e.CellBounds.Y + CInt(Fix((e.CellBounds.Height - img.Height) / 2)), img.Width, img.Height)
                                Else
                                    Dim cm As New System.Drawing.Imaging.ColorMatrix
                                    Dim ia As New System.Drawing.Imaging.ImageAttributes
                                    cm.Matrix00 = 1
                                    cm.Matrix11 = 1
                                    cm.Matrix22 = 1
                                    cm.Matrix33 = 0.5F
                                    cm.Matrix44 = 1
                                    ia.SetColorMatrix(cm)
                                    Dim p As New Drawing.Point(e.CellBounds.X + 2, e.CellBounds.Y + CInt(Fix((e.CellBounds.Height - img.Height) / 2)))
                                    e.Graphics.DrawImage(img, New Rectangle(p.X, p.Y, img.Width, img.Height), 0, 0, img.Width, img.Height, Drawing.GraphicsUnit.Pixel, ia)
                                End If
                            End If
                            partPaint = partPaint And (Not DataGridViewPaintParts.Background)
                        End If

                    Case idxColFolder
                        Dim item As FileListItem = dicFileList(lstFile(idxColPath, e.RowIndex).Value.ToString)
                        If Not item.ScanResult Is Nothing AndAlso item.ScanResult.DirExists Then
                            e.PaintBackground(e.ClipBounds, (partPaint And DataGridViewPaintParts.SelectionBackground) = DataGridViewPaintParts.SelectionBackground)

                            Dim hIcon As AppBase.ShellIcon.HANDLE = AppBase.ShellIcon.HANDLE.FS_FOLDER

                            If String.IsNullOrWhiteSpace(Logic.FileSystem.GetPathWithoutRoot(Logic.FileSystem.GetPathParent(item.Key))) Then
                                Select Case item.ScanResult.DriveType
                                    Case IO.DriveType.CDRom
                                        hIcon = AppBase.ShellIcon.HANDLE.FS_CDROM
                                    Case IO.DriveType.Network
                                        hIcon = AppBase.ShellIcon.HANDLE.FS_NETWORK
                                    Case IO.DriveType.Ram
                                        hIcon = AppBase.ShellIcon.HANDLE.FS_RAM
                                    Case IO.DriveType.Removable
                                        hIcon = AppBase.ShellIcon.HANDLE.FS_REMOVABLE
                                    Case Else
                                        hIcon = AppBase.ShellIcon.HANDLE.FS_DRIVE
                                End Select
                            End If
                            Dim img As Drawing.Bitmap = AppBase.ShellIcon.GetSingletonInstance(hIcon)

                            If item.ScanResult.DirHidden = False Then
                                e.Graphics.DrawImage(img, e.CellBounds.X + 2, e.CellBounds.Y + CInt(Fix((e.CellBounds.Height - img.Height) / 2)), img.Width, img.Height)
                            Else
                                Dim cm As New System.Drawing.Imaging.ColorMatrix
                                Dim ia As New System.Drawing.Imaging.ImageAttributes
                                cm.Matrix00 = 1
                                cm.Matrix11 = 1
                                cm.Matrix22 = 1
                                cm.Matrix33 = 0.5F
                                cm.Matrix44 = 1
                                ia.SetColorMatrix(cm)
                                Dim p As New Drawing.Point(e.CellBounds.X + 2, e.CellBounds.Y + CInt(Fix((e.CellBounds.Height - img.Height) / 2)))
                                e.Graphics.DrawImage(img, New Rectangle(p.X, p.Y, img.Width, img.Height), 0, 0, img.Width, img.Height, Drawing.GraphicsUnit.Pixel, ia)
                            End If
                            partPaint = partPaint And (Not DataGridViewPaintParts.Background)
                        End If

                End Select
            Catch ex As Exception
#If DEBUG Then
                Throw
#End If
            End Try

        End If

        e.Paint(e.CellBounds, partPaint)
        e.Handled = True

    End Sub

    Private Sub lstFile_SelectionChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles lstFile.SelectionChanged
        For Each Row As DataGridViewRow In lstFile.SelectedRows
            lstFile.InvalidateRow(Row.Index)
        Next
    End Sub

    Private Sub lstFile_CurrentCellDirtyStateChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles lstFile.CurrentCellDirtyStateChanged
        If (Not lstFile.CurrentCell Is Nothing) AndAlso lstFile.IsCurrentCellDirty Then
            If TypeOf lstFile.CurrentCell Is DataGridViewCheckBoxCell Then lstFile.CommitEdit(DataGridViewDataErrorContexts.Commit)
        End If
    End Sub

    Private Sub lstFile_CurrentCellChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles lstFile.CurrentCellChanged
        Logic.DataGridViewUtility.ScrollTo(lstFile.CurrentCell)
        If Not lstFile.CurrentRow Is Nothing Then lstFile.InvalidateRow(lstFile.CurrentRow.Index)
    End Sub

    Private Sub lstFile_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles lstFile.KeyDown

        Select Case e.KeyData
            Case Windows.Forms.Keys.Delete
                FileList_RemoveRow()

            Case Windows.Forms.Keys.Escape
                lstFile.ClearSelection()

        End Select

    End Sub

    Private Sub lstFile_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles lstFile.DragDrop

        If e.Data.GetDataPresent(DataFormats.FileDrop) = False Then Return
        If Not (e.Effect = DragDropEffects.Copy Or e.Effect = DragDropEffects.Move) Then Return

        For ct As Integer = 0 To e.Data.GetData(DataFormats.FileDrop).Length - 1
            Dim Path As Logic.FileSystem.Path = e.Data.GetData(DataFormats.FileDrop)(ct).ToString
            If Path.FileExists Then
                If AppBase.ArchiveOptionConfigCollection.Contains(Path.Extention) Then
                    If FileList_AddRow(Path.ToString) Is Nothing Then Exit For
                End If
            ElseIf Path.DirectoryExists Then
                Try
                    For Each ChildPath As String In IO.Directory.GetFileSystemEntries(Path.ToString, "*",
                                    IIf(AppBase.Config.ExportableGroup.IsDropFolderRecursiveLoad, IO.SearchOption.AllDirectories, IO.SearchOption.TopDirectoryOnly))
                        If AppBase.ArchiveOptionConfigCollection.Contains(ChildPath) Then
                            If FileList_AddRow(ChildPath) Is Nothing Then Exit For
                        End If
                    Next
                Catch ex As Exception
                End Try
            End If
        Next

    End Sub

    Private Sub lstFile_DragEnter(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles lstFile.DragEnter
        If e.Data.GetDataPresent(DataFormats.FileDrop) Then e.Effect = DragDropEffects.Copy
    End Sub

    Private Sub ctxFileListPlanScan_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ctxFileListPlanScan.Click
        If AppBase IsNot Nothing Then
            Dim PathList As New Collections.Generic.List(Of String)
            For Each objRow As DataGridViewRow In lstFile.SelectedRows
                PathList.Add(objRow.Cells(idxColPath).Value)
            Next
            If 0 < PathList.Count Then
                PathList.Sort()
                AppBase.MainTask.Scan(PathList.AsReadOnly)
            End If
        End If
    End Sub

    Private Sub ArchiveItemScan(ByVal e As AppBase.ArchiveItemScanArgs)
        If InvokeRequired Then
            Invoke(New AppBase.ArchiveItemScanArgs.Echoes.Handler(AddressOf ArchiveItemScan), {e})
        Else
            If e.Data.IsUserCmd Or e.Data.IsDelete Or e.Data.HasDelete Then e.Data.IsUserChecked = True
            dicFileList(e.Path.ToString).ScanResult = e.Data
            PresentScanResultToRow(dicFileList(e.Path.ToString))
        End If
    End Sub

    Private Sub ctxFileListFlush_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ctxFileListFlush.Click
        If lstFile.SelectedRows Is Nothing OrElse lstFile.SelectedRows.Count <= 0 Then Exit Sub
        For Each objRow As DataGridViewRow In lstFile.SelectedRows
            Try
                Dim item As FileListItem = dicFileList(CStr(objRow.Cells(idxColPath).Value))
                If Not item Is Nothing Then
                    If item.ScanResult Is Nothing Then item.ScanResult = New AppBase.ArchiveItemScanArgs.PayloadData
                    item.ScanResult.FileInformationFlush(item.Key)
                    PresentScanResultToRow(item)
                End If
            Catch ex As Exception
#If DEBUG Then
                Throw
#End If
            End Try
        Next
    End Sub

    Private Sub ctxFileListItemRemove_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ctxFileListItemRemove.Click
        FileList_RemoveRow()
    End Sub

    Private Sub ctxFileListCrcCheck_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ctxFileListCrcCheck.Click
        If AppBase IsNot Nothing Then
            Dim PathList As New Collections.Generic.List(Of String)
            For Each objRow As DataGridViewRow In lstFile.SelectedRows
                PathList.Add(objRow.Cells(idxColPath).Value)
            Next
            If 0 < PathList.Count Then
                PathList.Sort()
                AppBase.MainTask.CrcCheck(PathList.AsReadOnly)
            End If
        End If
    End Sub

    Private Sub ctxFileListPlanExecute_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ctxFileListPlanExecute.Click
        If AppBase IsNot Nothing Then
            Dim ArgsList As New Collections.Generic.List(Of AppBase.ArchiveItemScanArgs)
            For Each Row As DataGridViewRow In lstFile.SelectedRows
                Dim Value As Object = Row.Cells(idxColPath).Value
                If Value Is Nothing Then Continue For
                Dim Path As String = Value.ToString
                Dim AddItem As FileListItem = dicFileList(Path)
                If AddItem IsNot Nothing AndAlso AddItem.ScanResult IsNot Nothing Then ArgsList.Add(New AppBase.ArchiveItemScanArgs(Path, AddItem.ScanResult))
            Next
            If 0 < ArgsList.Count Then
                ArgsList.Sort(New AppBase.ArchiveItemScanArgs.Comparer)
                AppBase.MainTask.ArchiveTask(ArgsList.AsReadOnly)
            End If
        End If
    End Sub

    Private Sub lstFile_Enter(sender As Object, e As System.EventArgs) Handles lstFile.Enter
        lstFile.DefaultCellStyle.SelectionForeColor = SystemColors.HighlightText
        lstFile.DefaultCellStyle.SelectionBackColor = SystemColors.Highlight
    End Sub

    Private Sub lstFile_Leave(sender As Object, e As System.EventArgs) Handles lstFile.Leave
        lstFile.DefaultCellStyle.SelectionForeColor = SystemColors.ControlText
        lstFile.DefaultCellStyle.SelectionBackColor = SystemColors.Control
    End Sub

End Class
