' *
' * 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)
' *

Partial Public Class AppBase

    Public Class ArchiveItemScanArgs

        Public Class Comparer
            Implements Collections.Generic.IComparer(Of ArchiveItemScanArgs)
            Public Function Compare(x As ArchiveItemScanArgs, y As ArchiveItemScanArgs) As Integer Implements System.Collections.Generic.IComparer(Of ArchiveItemScanArgs).Compare
                If x Is y Then Return 0
                If x Is Nothing Then Return -1
                Return x.Path.CompareTo(y)
            End Function
        End Class

        Public Class PayloadData

            Private m_Task As PDTASK
            Public ReadOnly Property Task As PDTASK
                Get
                    Return m_Task
                End Get
            End Property

            Public FileSize As Integer
            Public DriveType As IO.DriveType
            Public CreationTime As DateTime
            Public LastAccessTime As DateTime
            Public LastWriteTime As DateTime
            Public PresetName As String
            Public MirrorArchivePath As String
            Public DeleteFiles As Logic.FileSystem.Path.Collection

            Public Sub New()
                m_Task = PDTASK.NONE
                FileSize = 0
                DriveType = IO.DriveType.Unknown
                CreationTime = DateTime.MinValue
                LastAccessTime = DateTime.MinValue
                LastWriteTime = DateTime.MinValue
                PresetName = String.Empty
                MirrorArchivePath = String.Empty
                DeleteFiles = Nothing
            End Sub

            Public Sub New(ByVal t As PDTASK)
                MyClass.new()
                m_Task = t
            End Sub

            Public Sub New(ByVal src As PayloadData)
                MyClass.new()
                If src Is Nothing Then Return
                m_Task = src.Task
                DriveType = src.DriveType
                CreationTime = src.CreationTime
                LastAccessTime = src.LastAccessTime
                LastWriteTime = src.LastWriteTime
                PresetName = New String(src.PresetName)
                MirrorArchivePath = New String(src.MirrorArchivePath)
                DeleteFiles = Nothing
                If src.DeleteFiles IsNot Nothing AndAlso 0 < src.DeleteFiles.Count Then
                    DeleteFiles = New Logic.FileSystem.Path.Collection
                    For Each strDelPath As String In src.DeleteFiles
                        DeleteFiles.Add(strDelPath)
                    Next
                End If
            End Sub

            Private Shared ReadOnly TextInfErrAndStatusMsg As New Collections.Generic.Dictionary(Of PDTASK, String) From
            {
                {PDTASK.ERR_FILENOTEXISTS, "ファイルが見つかりません"},
                {PDTASK.ERR_INVALID_CMD, "スキャンコマンドの解析エラー、または置換できないキーワード"},
                {PDTASK.ERR_SCANCMD, "スキャンコマンドの実行エラー"},
                {PDTASK.ERR_SCANCMD_INVALIDEXIT, "スキャンコマンドの異常終了"},
                {PDTASK.DELETE, "削除対象"}
            }
            Private Const InformationMsgSep As String = "="
            Private Shared ReadOnly TextInfMsg As New Collections.Generic.SortedDictionary(Of PDTASK, String) From
            {
                {PDTASK.USERCMD, "プリセット"},
                {PDTASK.HASDELETE, "削除するファイル"}
            }

            Public ReadOnly Property TextInformation As String
                Get
                    Dim ret As New Collections.Generic.List(Of String)

                    ' Error And Status Message
                    For Each e As PDTASK In TextInfErrAndStatusMsg.Keys
                        If (Task And e) = e Then ret.Add(TextInfErrAndStatusMsg(e))
                    Next

                    ' UserCmd
                    If ((Task And PDTASK.USERCMD) = PDTASK.USERCMD) And
                        Not String.IsNullOrWhiteSpace(PresetName) Then
                        ret.Add(String.Format("{0}{1}""{2}""", TextInfMsg(PDTASK.USERCMD), InformationMsgSep, PresetName))
                    End If

                    ' DeleteTarget
                    If ((Task And PDTASK.HASDELETE) = PDTASK.HASDELETE) And
                        Not DeleteFiles Is Nothing AndAlso 0 < DeleteFiles.Count Then
                        ret.Add(String.Format("{0}({1}){2}{3}", TextInfMsg(PDTASK.HASDELETE),
                                                            DeleteFiles.Count, InformationMsgSep, String.Join(",", DeleteFiles)))
                    End If

                    Return String.Join(" ", ret)
                End Get
            End Property

            Public ReadOnly Property FileExists As Boolean
                Get
                    Return (Task And PDTASK.ERR_FILENOTEXISTS) <> PDTASK.ERR_FILENOTEXISTS
                End Get
            End Property

            Public ReadOnly Property FileHidden As Boolean
                Get
                    Return (Task And PDTASK.HIDDEN_FILE) = PDTASK.HIDDEN_FILE
                End Get
            End Property
            Public WriteOnly Property FileHidden(ByVal Path As Logic.FileSystem.Path) As Boolean
                Set(ByVal value As Boolean)
                    If Path.Exists Then
                        Try
                            Dim attr As IO.FileAttributes = IO.File.GetAttributes(Path.ToString)
                            If value Then
                                attr = attr Or FileAttribute.Hidden
                            Else
                                attr = attr And (Not FileAttribute.Hidden)
                            End If
                            IO.File.SetAttributes(Path.ToString, attr)
                        Catch
                        End Try
                    End If
                    FileInformationFlush(Path)
                End Set
            End Property

            Public ReadOnly Property DirExists As Boolean
                Get
                    Return (Task And PDTASK.ERR_DIRNOTEXISTS) <> PDTASK.ERR_DIRNOTEXISTS
                End Get
            End Property
            Public ReadOnly Property DirHidden As Boolean
                Get
                    Return (Task And PDTASK.HIDDEN_DIR) = PDTASK.HIDDEN_DIR
                End Get
            End Property
            Public WriteOnly Property DirHidden(ByVal FilePath As Logic.FileSystem.Path) As Boolean
                Set(ByVal value As Boolean)
                    Dim Parent As Logic.FileSystem.Path = FilePath.Parent
                    If Parent.DirectoryExists Then
                        Try
                            Dim attr As IO.FileAttributes = IO.File.GetAttributes(Parent.ToString)
                            If value Then
                                attr = attr Or FileAttribute.Hidden
                            Else
                                attr = attr And (Not FileAttribute.Hidden)
                            End If
                            IO.File.SetAttributes(Parent.ToString, attr)
                        Catch
                        End Try
                        FileInformationFlush(FilePath.ToString)
                    End If
                End Set
            End Property
            Public Property IsFilter As Boolean
                Get
                    Return (m_Task And PDTASK.FILTERED) = PDTASK.FILTERED
                End Get
                Set(ByVal value As Boolean)
                    If value Then
                        m_Task = m_Task Or PDTASK.FILTERED
                    Else
                        m_Task = m_Task And (Not PDTASK.FILTERED)
                    End If
                End Set
            End Property
            Public Property IsDelete As Boolean
                Get
                    Return (m_Task And PDTASK.DELETE) = PDTASK.DELETE
                End Get
                Set(ByVal value As Boolean)
                    If value Then
                        m_Task = m_Task Or PDTASK.DELETE
                    Else
                        m_Task = m_Task And (Not PDTASK.DELETE)
                    End If
                End Set
            End Property
            Public Property IsUserCmd As Boolean
                Get
                    Return (m_Task And PDTASK.USERCMD) = PDTASK.USERCMD
                End Get
                Set(ByVal value As Boolean)
                    If value Then
                        m_Task = m_Task Or PDTASK.USERCMD
                    Else
                        m_Task = m_Task And (Not PDTASK.USERCMD)
                    End If
                End Set
            End Property
            Public Property HasDelete As Boolean
                Get
                    Return Not DeleteFiles Is Nothing AndAlso (0 < DeleteFiles.Count And _
                    ((m_Task And PDTASK.HASDELETE) = PDTASK.HASDELETE))
                End Get
                Set(ByVal value As Boolean)
                    If value Then
                        m_Task = m_Task Or PDTASK.HASDELETE
                    Else
                        m_Task = m_Task And (Not PDTASK.HASDELETE)
                    End If
                End Set
            End Property
            Public Property IsUserChecked As Boolean
                Get
                    Return (m_Task And PDTASK.USERCHECKED) = PDTASK.USERCHECKED
                End Get
                Set(ByVal value As Boolean)
                    If value Then
                        m_Task = m_Task Or PDTASK.USERCHECKED
                    Else
                        m_Task = m_Task And (Not PDTASK.USERCHECKED)
                    End If
                End Set
            End Property
            Public Property IsErrInvalidCmd As Boolean
                Get
                    Return (m_Task And PDTASK.ERR_INVALID_CMD) = PDTASK.ERR_INVALID_CMD
                End Get
                Set(ByVal value As Boolean)
                    If value Then
                        m_Task = m_Task Or PDTASK.ERR_INVALID_CMD
                    Else
                        m_Task = m_Task And (Not PDTASK.ERR_INVALID_CMD)
                    End If
                End Set
            End Property
            Public Property IsErrScanCmd As Boolean
                Get
                    Return (m_Task And PDTASK.ERR_SCANCMD) = PDTASK.ERR_SCANCMD
                End Get
                Set(ByVal value As Boolean)
                    If value Then
                        m_Task = m_Task Or PDTASK.ERR_SCANCMD
                    Else
                        m_Task = m_Task And (Not PDTASK.ERR_SCANCMD)
                    End If
                End Set
            End Property
            Public Property IsErrScanCmdInvalidExit As Boolean
                Get
                    Return (m_Task And PDTASK.ERR_SCANCMD_INVALIDEXIT) = PDTASK.ERR_SCANCMD_INVALIDEXIT
                End Get
                Set(ByVal value As Boolean)
                    If value Then
                        m_Task = m_Task Or PDTASK.ERR_SCANCMD_INVALIDEXIT
                    Else
                        m_Task = m_Task And (Not PDTASK.ERR_SCANCMD_INVALIDEXIT)
                    End If
                End Set
            End Property
            Public Property IsUserCanceled As Boolean
                Get
                    Return (m_Task And PDTASK.USERCANCEL) = PDTASK.USERCANCEL
                End Get
                Set(ByVal value As Boolean)
                    If value Then
                        m_Task = m_Task Or PDTASK.USERCANCEL
                    Else
                        m_Task = m_Task And (Not PDTASK.USERCANCEL)
                    End If
                End Set
            End Property

            Public Function FileInformationFlush(ByVal Path As Logic.FileSystem.Path) As PayloadData

                FileSize = 0
                DriveType = IO.DriveType.Unknown
                CreationTime = Nothing
                LastAccessTime = Nothing
                LastWriteTime = Nothing
                m_Task = m_Task And (Not PDTASK.ERR_DIRNOTEXISTS)
                m_Task = m_Task And (Not PDTASK.HIDDEN_DIR)
                m_Task = m_Task And (Not PDTASK.ERR_FILENOTEXISTS)
                m_Task = m_Task And (Not PDTASK.HIDDEN_FILE)

                Try
                    Dim Parent As Logic.FileSystem.Path = Path.Parent
                    If Parent.DirectoryExists = False Then Throw New ApplicationException
                    If Parent.IsRootOnly = False AndAlso ((IO.File.GetAttributes(Parent.ToString) And FileAttribute.Hidden) = FileAttribute.Hidden) Then
                        m_Task = m_Task Or PDTASK.HIDDEN_DIR
                    End If
                Catch ex As Exception
                    m_Task = m_Task Or PDTASK.ERR_DIRNOTEXISTS
                End Try

                If DirExists Then
                    Try
                        If Path.IsUncPath(Path.ToString) = False Then
                            DriveType = New IO.DriveInfo(Path.ToString).DriveType
                        Else
                            DriveType = IO.DriveType.Network
                        End If
                    Catch ex As Exception
#If DEBUG Then
                        Throw
#End If
                    End Try
                End If

                Try
                    If (m_Task And PDTASK.ERR_DIRNOTEXISTS) = _
                        PDTASK.ERR_DIRNOTEXISTS OrElse Path.FileExists = False Then
                        Throw New ApplicationException
                    End If
                    Dim inf As New IO.FileInfo(Path.ToString)
                    FileSize = inf.Length
                    CreationTime = inf.CreationTime
                    LastAccessTime = inf.LastAccessTime
                    LastWriteTime = inf.LastWriteTime
                    If (inf.Attributes And FileAttribute.Hidden) = FileAttribute.Hidden Then
                        m_Task = m_Task Or PDTASK.HIDDEN_FILE
                    End If
                Catch ex As Exception
                    m_Task = m_Task Or PDTASK.ERR_FILENOTEXISTS
                End Try

                Return Me

            End Function

        End Class ' ArchiveItemScanArgs.PayloadData

        Public Path As Logic.FileSystem.Path
        Public Data As PayloadData

        Public Sub New()
            MyBase.New()
            Path = Nothing
            Data = Nothing
        End Sub

        Public Sub New(ByVal src As ArchiveItemScanArgs)
            MyClass.new()
            If src Is Nothing Then Return
            Path = src.Path
            Data = New PayloadData(src.Data)
        End Sub

        Public Sub New(ByVal setPath As Logic.FileSystem.Path, Optional ByVal t As PDTASK = PDTASK.NONE)
            MyClass.new()
            If setPath Is Nothing OrElse setPath.IsNullOrWhiteSpace Then
                Path = String.Empty
            Else
                Path = New Logic.FileSystem.Path(setPath.ToString)
            End If
            Data = New PayloadData(t)
        End Sub

        Public Sub New(ByVal Path As Logic.FileSystem.Path, ByVal Data As PayloadData)
            Me.Path = Path
            Me.Data = Data
        End Sub

        Public Function PathEquals(ByVal src As String) As Boolean
            Return String.Equals(Path, src)
        End Function

        Public Property DirHidden As Boolean
            Get
                Return Data.DirHidden
            End Get
            Set(ByVal value As Boolean)
                Data.DirHidden(Path) = value
            End Set
        End Property

        Public Property FileHidden As Boolean
            Get
                Return Data.FileHidden
            End Get
            Set(ByVal value As Boolean)
                Data.FileHidden(Path) = value
            End Set
        End Property

        Public Class Echoes
            Inherits Logic.Echoes(Of ArchiveItemScanArgs)
        End Class

    End Class ' ArchiveItemScanArgs

End Class
