Option Strict Off
Option Explicit On
Imports System.Linq
Imports System.Collections.Generic
Imports System
Imports System.Windows.Forms
Imports System.Windows
Imports gmRTL.Core
Namespace ScanToolLib
   Public Class clsScanControl

   Public Class statusEventArgs : Inherits System.EventArgs
      Public msg As String
      Public Sub New(ByVal msg As String)
         Me.msg = msg
      End Sub
   End Class
   Public Delegate Sub statusEventHandler(sender as Object,e As statusEventArgs)
   Public Event status_Event As EventHandler(Of statusEventArgs)
   Protected Overridable Sub Onstatus_Event(msg As String)
      Dim e As statusEventArgs
      e = New statusEventArgs(msg)
      RaiseEvent status_Event(Me, e)
   End Sub
   Public txtFolderFilter As String = ""
   Public txtFilFilter As String = ""
   Public txtContentFilter As String = ""
   Public txtSaveTo As String = ""
   Public txtRootPath As String = ""
   Public optRpt As String = ""
   Public mfoldercnt As Boolean = False
   Public chkNoCase As Boolean = False
   Dim comReporter As clsCOMReporter = Nothing
   Dim vbpRefReporter As clsVBPRefReporter = Nothing
   Dim vbpBinReporter As clsVBPBinReporter = Nothing
   Dim vbpModReporter As clsVBPModReporter = Nothing
   Dim vbpSrcReporter As clsVBPSrcReporter = Nothing
   Dim vbpCntReporter As clsVBPCntReporter = Nothing
   Dim dirLister As clsDirList = Nothing
   Dim filHandler As Object = Nothing
   ' XML Config file constants

   Private Const CFG_XMLDOC As String = "ScanTool"
   Private Const CFG_ROOTPATH As String = "RootPath"
   Private Const CFG_SAVETO As String = "SaveTo"
   Private Const CFG_REPORT_MODE As String = "ReportMode"
   Private Const CFG_FOLDER_FILTER As String = "FolderFilter"
   Private Const CFG_FILE_FILTER As String = "FileFilter"
   Private Const CFG_IGNORE_CASE As String = "IgnoreCase"
   Private Const CFG_CONTENT_FILTER As String = "ContentFilter"
   Private Const CFG_IGNORE_CASE_TRUE As String = "true"
   Private Const CFG_IGNORE_CASE_FALSE As String = "false"
   Public Sub runReport()
      Const FUNC_NAME As String = "runReport"
      Try
         gmRTL.Core.GlobalException.ClearErrorObject()

         report()

         setStatus(optRpt & " report successfully written to " & txtSaveTo)

      Catch exc As System.Exception
         gmRTL.Core.GlobalException.SetErrorObject(exc)
      End Try

      If (Err.Number <> 0) Then
         setStatus("Completed with error " & TypeName(Me) & "::" & FUNC_NAME & " " & Environment.NewLine & Err.Description)
      End If
   End Sub
   Private Sub report()
      Const FUNC_NAME As String = "report"
      Dim fld As System.IO.DirectoryInfo = Nothing
      Dim rpt As System.IO.StreamWriter = Nothing
      Try
         gmRTL.Core.GlobalException.ClearErrorObject()

         If (txtRootPath = "") Then
            Err.Raise(17,"Please set a root path",String.Empty)
         End If

         setFileProcessor()


         fld = new System.IO.DirectoryInfo(txtRootPath)

         rpt = modScanToolLib.openOutputText(txtSaveTo)

         Dim dirPats As String() = Array.Empty(Of String)()
         dirPats = Strings.Split(Strings.LCase(txtFolderFilter),",",-1,CompareMethod.Binary)

         Dim filPats As String() = Array.Empty(Of String)()
         filPats = Strings.Split(Strings.LCase(txtFilFilter),",",-1,CompareMethod.Binary)

         If (mfoldercnt) Then
            rpt.WriteLine("PATH" & vbTab & "SUBFOLDERS" & vbTab & "FILES" & vbTab & "SIZE")
            reportFolder(fld,rpt,dirPats,filPats)
         Else
            rpt.WriteLine(Convert.ToString(Interaction.CallByName(filHandler,"header",CallType.Get,Nothing)))
            reportFolder(fld,rpt,dirPats,filPats)
         End If

         rpt.Close()

      Catch exc As System.Exception
         gmRTL.Core.GlobalException.SetErrorObject(exc)
      End Try

      rpt = Nothing
      fld = Nothing

      If (Err.Number <> 0) Then
         Err.Raise(Err.Number,String.Empty,TypeName(Me) & "::" & FUNC_NAME & " " & Environment.NewLine & Err.Description)
      End If

   End Sub
   Private Sub reportFolder(ByVal fld As System.IO.DirectoryInfo,ByVal rpt As System.IO.StreamWriter,ByVal dirPats() As String,ByVal filPats() As String)
      Const FUNC_NAME As String = "reportFolder"
      Dim fil As System.IO.FileInfo = Nothing
      Dim subfld As System.IO.DirectoryInfo = Nothing
      Try
         gmRTL.Core.GlobalException.ClearErrorObject()

         Dim i As Integer = 0
         Dim filPatCnt As Integer = 0
         filPatCnt = UBound(filPats,1)
         Dim dirPatCnt As Integer = 0
         dirPatCnt = UBound(dirPats,1)

         Dim fldpath As String = ""
         fldpath = Strings.LCase(fld.FullName) & "\"
         setStatus(fldpath)

         Dim scanDir As Boolean = False
         For i = 0 To dirPatCnt Step 1
            scanDir = fldpath Like dirPats(i)
            If (scanDir) Then
               Exit For
            End If
         Next

         If (scanDir) Then

            Dim filCnt As Integer = 0
            filCnt = 0
            Dim filSiz As Double = 0.0
            filSiz = 0

            Dim forTemp0 As System.IO.FileInfo
            For Each forTemp0 in fld.GetFiles()
               fil = forTemp0

               Dim filname As String = ""
               filname = Strings.LCase(fil.Name)

               Dim scanFil As Boolean = False
               For i = 0 To filPatCnt Step 1
                  scanFil = filname Like filPats(i)
                  If (scanFil) Then
                     Exit For
                  End If
               Next

               If (scanFil) Then

                  setStatus(fil.FullName)

                  If (mfoldercnt) Then
                     filCnt = filCnt + 1
                     filSiz = filSiz + fil.Length
                  Else
                     Interaction.CallByName(filHandler,"processFile",CallType.Method,New Object(){fil,rpt})
                  End If

               End If

            Next

            If (mfoldercnt) Then

               modScanToolLib.writeRpt(rpt,fld.FullName & vbTab & fld.GetDirectories().Length & vbTab & filCnt & vbTab & filSiz & Environment.NewLine)
            End If

         End If

         ' recurse through all subfolders

         Dim forTemp1 As System.IO.DirectoryInfo
         For Each forTemp1 in fld.GetDirectories()
            subfld = forTemp1
            reportFolder(subfld,rpt,dirPats,filPats)
         Next

      Catch exc As System.Exception
         gmRTL.Core.GlobalException.SetErrorObject(exc)
      End Try

      subfld = Nothing
      fil = Nothing

      If (Err.Number <> 0) Then
         Err.Raise(Err.Number,String.Empty,TypeName(Me) & "::" & FUNC_NAME & " " & Environment.NewLine & Err.Description)
      End If
   End Sub
   Private Sub setStatus(ByVal msg As String)
      Onstatus_Event(msg)
   End Sub
   Public Sub setParms()

      Select Case optRpt
         Case "DirList"
            txtFolderFilter = "*"
            txtFilFilter = "*"
            txtContentFilter = ""
         Case "COMGuid"
            txtFolderFilter = "*"
            txtFilFilter = "*.ocx,*.exe,*.dll,*.olb,*.tlb"
         Case "VBPRef"
            txtFolderFilter = "*"
            txtFilFilter = "*.vbp"
         Case "VBPBin"
            txtFolderFilter = "*"
            txtFilFilter = "*.vbp"
         Case "VBPMod"
            txtFolderFilter = "*"
            txtFilFilter = "*.vbp"
         Case "VBPSource"
            txtFolderFilter = "*"
            txtFilFilter = "*.vbp"
         Case "VBPCount"
            txtFolderFilter = "*"
            txtFilFilter = "*.vbp"
         Case "FolderCnt"
            txtFolderFilter = "*"
            txtFilFilter = "*"
         Case Else
            Err.Raise(17,String.Empty,"Unknown mode " & optRpt)
      End Select

      txtSaveTo = optRpt & ".tdf"

   End Sub
   Public Sub setFileProcessor()
      mfoldercnt = False
      Select Case optRpt
         Case "DirList"
            dirLister = New clsDirList
            dirLister.contentFilter = txtContentFilter
            dirLister.noCase = chkNoCase
            filHandler = dirLister
         Case "COMGuid"
            comReporter = New clsCOMReporter
            filHandler = comReporter
         Case "VBPRef"
            vbpRefReporter = New clsVBPRefReporter
            filHandler = vbpRefReporter
         Case "VBPBin"
            vbpBinReporter = New clsVBPBinReporter
            filHandler = vbpBinReporter
         Case "VBPMod"
            vbpModReporter = New clsVBPModReporter
            filHandler = vbpModReporter
         Case "VBPSource"
            vbpSrcReporter = New clsVBPSrcReporter
            filHandler = vbpSrcReporter
         Case "VBPCount"
            vbpCntReporter = New clsVBPCntReporter
            filHandler = vbpCntReporter
         Case "FolderCnt"
            mfoldercnt = True
      End Select
   End Sub
   Public Function Show() As String
      Dim rpt As String = ""
      rpt = rpt & "optRpt           = [" & optRpt & "]" & Environment.NewLine
      rpt = rpt & "txtFolderFilter  = [" & txtFolderFilter & "]" & Environment.NewLine
      rpt = rpt & "txtFilFilter     = [" & txtFilFilter & "]" & Environment.NewLine
      rpt = rpt & "txtContentFilter = [" & txtContentFilter & "]" & Environment.NewLine
      rpt = rpt & "txtSaveTo        = [" & txtSaveTo & "]" & Environment.NewLine
      rpt = rpt & "txtRootPath      = [" & txtRootPath & "]" & Environment.NewLine
      rpt = rpt & "mfoldercnt       = [" & mfoldercnt & "]" & Environment.NewLine
      rpt = rpt & "chkNoCase        = [" & chkNoCase & "]" & Environment.NewLine
      Show = rpt
   End Function
   Public Sub loadScantoolConfig(ByVal filename As String)
      Const FUNC_NAME As String = "loadScantoolConfig"
      Dim domConfig As System.Xml.XmlDocument = Nothing
      Try
         gmRTL.Core.GlobalException.ClearErrorObject()

         domConfig = New System.Xml.XmlDocument

         domConfig.Load(filename)
         If (Not domConfig.HasChildNodes) Then
            Err.Raise(17,TypeName(Me),"Unable to load XML documentt: " & filename)
         End If


         Debug.WriteLine(domConfig.InnerXml)

         Me.txtSaveTo = modScanToolLib.readNode(domConfig,"//" & CFG_XMLDOC & "//" & CFG_SAVETO)
         Me.txtRootPath = modScanToolLib.readNode(domConfig,"//" & CFG_XMLDOC & "//" & CFG_ROOTPATH)
         Me.txtFilFilter = modScanToolLib.readNode(domConfig,"//" & CFG_XMLDOC & "//" & CFG_FILE_FILTER)
         Me.txtFolderFilter = modScanToolLib.readNode(domConfig,"//" & CFG_XMLDOC & "//" & CFG_FOLDER_FILTER)
         Me.txtContentFilter = modScanToolLib.readNode(domConfig,"//" & CFG_XMLDOC & "//" & CFG_CONTENT_FILTER)
         Me.optRpt = modScanToolLib.readNode(domConfig,"//" & CFG_XMLDOC & "//" & CFG_REPORT_MODE)
         Me.chkNoCase = modScanToolLib.readNode(domConfig,"//" & CFG_XMLDOC & "//" & CFG_CONTENT_FILTER & "//@" & CFG_IGNORE_CASE) = CFG_IGNORE_CASE_TRUE

      Catch exc As System.Exception
         gmRTL.Core.GlobalException.SetErrorObject(exc)
      End Try

      domConfig = Nothing

      If (Err.Number <> 0) Then
         Err.Raise(Err.Number,String.Empty,TypeName(Me) & "::" & FUNC_NAME & " " & Environment.NewLine & Err.Description)
      End If
   End Sub
   Public Sub saveScantoolConfig(ByVal filename As String)
      Const FUNC_NAME As String = "saveScantoolConfig"
      Dim domConfig As System.Xml.XmlDocument = Nothing
      Try
         gmRTL.Core.GlobalException.ClearErrorObject()

         domConfig = New System.Xml.XmlDocument

         Dim elmRoot As System.Xml.XmlElement = Nothing

         elmRoot = domConfig.CreateElement(CFG_XMLDOC)
         domConfig.AppendChild(elmRoot)

         Dim elmParam As System.Xml.XmlElement = Nothing

         elmParam = modScanToolLib.writeTextNode(elmRoot,CFG_ROOTPATH,txtRootPath)
         elmParam = modScanToolLib.writeTextNode(elmRoot,CFG_REPORT_MODE,optRpt)
         elmParam = modScanToolLib.writeTextNode(elmRoot,CFG_SAVETO,txtSaveTo)
         elmParam = modScanToolLib.writeTextNode(elmRoot,CFG_FILE_FILTER,txtFilFilter)
         elmParam = modScanToolLib.writeTextNode(elmRoot,CFG_FOLDER_FILTER,txtFolderFilter)
         elmParam = modScanToolLib.writeTextNode(elmRoot,CFG_CONTENT_FILTER,txtContentFilter)
         elmParam.SetAttribute(CFG_IGNORE_CASE,IIf(chkNoCase,CFG_IGNORE_CASE_TRUE,CFG_IGNORE_CASE_FALSE))

         Debug.WriteLine(domConfig.InnerXml)

         domConfig.Save(filename)

      Catch exc As System.Exception
         gmRTL.Core.GlobalException.SetErrorObject(exc)
      End Try

      domConfig = Nothing

      If (Err.Number <> 0) Then
         Err.Raise(Err.Number,String.Empty,TypeName(Me) & "::" & FUNC_NAME & " " & Environment.NewLine & Err.Description)
      End If
   End Sub
   End Class
End Namespace
