Imports Microsoft.VisualBasic.FileIO

Public Class LinkChecker
    Dim FolderPath, strFileNames(), Filters(5) As String
    Dim intFileNameCount, nFilters As Integer
    Dim StopProcess As Boolean

    Private Sub btnProcess_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnProcess.Click
        Dim i As Integer

        If chkLogFile.CheckState = 1 Then
            BuildArrayFromLogFile(intFileNameCount)
        Else

            If filFiles.Items.Count > 0 Or optAllFiles.Checked Then
                intFileNameCount = -1
                If optSelected.Checked Then
                    ReDim strFileNames(filFiles.Items.Count)
                    For i = 0 To filFiles.Items.Count - 1
                        If filFiles.GetSelected(i) Then
                            intFileNameCount = intFileNameCount + 1
                            strFileNames(intFileNameCount) = FolderPath & "\" & filFiles.Items(i)
                        End If
                    Next
                ElseIf optAllInDirectory.Checked Then
                    ReDim strFileNames(filFiles.Items.Count)
                    For i = 0 To filFiles.Items.Count - 1
                        intFileNameCount = intFileNameCount + 1
                        strFileNames(intFileNameCount) = FolderPath & "\" & filFiles.Items(i)
                    Next
                ElseIf optAllFiles.Checked Then
                    Status("Creating list of files to process ...", FolderPath & "*.*")
                    ReadFileNamesFromDirectory(FolderPath, intFileNameCount, strFileNames)

                    System.Windows.Forms.Application.DoEvents()
                    If StopProcess Then
                        MsgBox("Processing aborted.")
                        Exit Sub
                    End If
                End If

                ' Check to be sure at least one part file has been specified.
                If intFileNameCount = -1 Then
                    If optAllFiles.Checked Then
                        ' Turn off the display of the status dialog.
                        Status()
                    End If

                    If optSelected.Checked Then
                        MsgBox("No part files are selected.")
                    ElseIf optAllInDirectory.Checked Then
                        MsgBox("No part files exist in the directory specified.")
                    ElseIf optAllFiles.Checked Then
                        MsgBox("No part files exist in the directories specified.")
                    End If
                    Exit Sub
                End If

            End If
        End If

        If intFileNameCount > -1 Then Process()

        lblFileProcessing.Text = "Processing complete"

    End Sub

    Private Sub LinkChecker_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        lblInstructions.Text = "Select the directory containing the Solid Edge files.  Select the file types.  Click the Process button to start the process of counting features in each file."
        btnProcess.Enabled = False
        lblFileProcessing.Visible = False
        lblProcessing.Visible = False
        chkParPsm.Enabled = False
        chkAsm.Enabled = False
        chkPwd.Enabled = False
        chkDft.Enabled = False
        chkLogFile.Enabled = False
        nFilters = -1
    End Sub

    Private Sub chkParPsm_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkParPsm.CheckedChanged
        SetFilters()
    End Sub

    Private Sub chkAsm_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkAsm.CheckedChanged
        SetFilters()
    End Sub

    Private Sub chkDft_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkDft.CheckedChanged
        SetFilters()
    End Sub

    Private Sub chkPwd_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkPwd.CheckedChanged
        SetFilters()
    End Sub

    Private Sub chkLogFile_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles chkLogFile.CheckedChanged
        Dim i, len As Integer
        Dim Filter, Filename As String

        filFiles.Items.Clear()
        If chkLogFile.CheckState = 1 Then
            Filter = "*.txt"
            For i = 0 To 1
                If i = 1 Then Filter = "*.log"
                For Each foundFile As String In FileSystem.GetFiles(FolderPath, SearchOption.SearchTopLevelOnly, Filter)
                    len = foundFile.Length
                    Filename = foundFile.Substring(FolderPath.Length + 1, len - FolderPath.Length - 1)
                    filFiles.Items.Add(Filename)
                Next
            Next
            chkAsm.Enabled = False
            chkParPsm.Enabled = False
            chkPwd.Enabled = False
            chkDft.Enabled = False
            filFiles.SelectionMode = SelectionMode.One
            lblInstructions.Text = "You have elected to get files from a log/txt file.  Files must be fully defined including full path.  Select one file and click Process "
            btnProcess.Enabled = True
        ElseIf chkLogFile.CheckState = 0 Then
            chkAsm.Enabled = True
            chkParPsm.Enabled = True
            chkPwd.Enabled = True
            chkDft.Enabled = True
            filFiles.SelectionMode = SelectionMode.MultiExtended
            If optSelected.Checked Then
                lblInstructions.Text = "Select the file types."
            Else
                lblInstructions.Text = "Click Process button or change Files to Process option"
            End If
            lblInstructions.Update()
            btnProcess.Enabled = False
        End If
    End Sub
    Private Sub SetFilters()
        Dim MyString As String
        Dim FileTypes() As String = {"*.asm", "*.par", "*.psm", "*dft", "*.pwd"}
        Dim i As Integer

        MyString = ""
        nFilters = -1
        If chkAsm.CheckState = 1 Then
            nFilters = nFilters + 1
            Filters(nFilters) = FileTypes(0)
        End If

        If chkParPsm.CheckState = 1 Then
            For i = 0 To 1
                nFilters = nFilters + 1
                Filters(nFilters) = FileTypes(i + 1)
            Next
        End If

        If chkDft.CheckState = 1 Then
            nFilters = nFilters + 1
            Filters(nFilters) = FileTypes(3)
        End If

        If chkPwd.CheckState = 1 Then
            nFilters = nFilters + 1
            Filters(nFilters) = FileTypes(4)
        End If

        filFiles.Items.Clear()

        For i = 0 To nFilters
            FileList(FolderPath, Filters(i))
        Next

        If filFiles.Items.Count > 0 Then
            btnProcess.Enabled = True
        Else
            btnProcess.Enabled = False
        End If
        If optSelected.Checked Then
            lblInstructions.Text = "Select specific files and click Process button or change Files to Process option"
        Else
            lblInstructions.Text = "Click Process button or change Files to Process option"
        End If
        lblInstructions.Update()
    End Sub

    Private Sub FileList(ByVal Path, ByVal Filter)
        Dim FileName As String
        Dim lenPath, len As Integer

        lenPath = Path.Length

        For Each foundFile As String In FileSystem.GetFiles(Path, SearchOption.SearchTopLevelOnly, Filter)
            len = foundFile.Length
            FileName = foundFile.Substring(lenPath + 1, len - lenPath - 1)
            filFiles.Items.Add(FileName)
        Next
    End Sub

    Private Sub btnBrowse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBrowse.Click
        Dim i As Short

        FolderBrowserDialog1.ShowDialog()
        FolderPath = FolderBrowserDialog1.SelectedPath
        FileSystem.CurrentDirectory = FolderPath

        lblPath.Text = "Folder Path: " & FolderPath
        lblPath.Update()
        lblInstructions.Text = "Select file types."
        lblInstructions.Update()
        chkParPsm.Enabled = True
        chkAsm.Enabled = True
        chkPwd.Enabled = True
        chkDft.Enabled = True
        chkLogFile.Enabled = True
        If nFilters > -1 Then
            filFiles.Items.Clear()

            For i = 0 To nFilters
                FileList(FolderPath, Filters(i))
            Next
        End If

    End Sub

    Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click
        End
    End Sub

    Public Sub Status(Optional ByRef Message As Object = Nothing, Optional ByRef Filename As Object = Nothing)
        ' Check to see if a message was passed in the argument.
        If IsNothing(Message) Then
            ' Turn off the display of the form.
            lblFileProcessing.Visible = False
            lblProcessing.Visible = False
        Else
            ' Set up the text to display.
            lblFileProcessing.Text = Filename
            lblProcessing.Text = Message

            ' Display the form.
            lblFileProcessing.Visible = True
            lblProcessing.Visible = True

            ' Force a refresh.
            lblFileProcessing.Refresh()
            lblProcessing.Refresh()
            System.Windows.Forms.Application.DoEvents()
        End If
    End Sub

    Public Sub ReadFileNamesFromDirectory(ByVal FilePath As String, ByRef intFileNameCount As Short, ByRef strFileNames() As String)
        Dim i As Short
        Dim strDirList() As String
        Dim nSubDir, nFiles As Integer

        ' If there are any subdirectories in the current directory save their
        ' names in an array so they can be processed below.

        ' Set the counter.
        ReDim strDirList(0)
        strDirList(0) = ""

        nSubDir = FileSystem.GetDirectories(FilePath).Count

        If nSubDir > 0 Then
            ' Allocate memory to store the directories.
            ReDim strDirList(nSubDir)

            ' Save the directory names into the array.
            For i = 0 To nSubDir - 1
                strDirList(i) = FileSystem.GetDirectories(FilePath).Item(i)
            Next
        End If

        ' If there are any files in the current directory save their names
        ' into the filename array.

        nFiles = FileSystem.GetFiles(FilePath).Count
        ' Allocate more space in the filename array to store the filenames.
        ReDim Preserve strFileNames(intFileNameCount + nFiles)

        If nFiles > 0 Then

            ' Save all the filenames of the files in the current directory
            ' into the filename array.
            For i = 0 To nFilters
                For Each foundFile As String In FileSystem.GetFiles( _
                    FilePath, _
                    SearchOption.SearchTopLevelOnly, Filters(i))
                    intFileNameCount = intFileNameCount + 1

                    strFileNames(intFileNameCount) = foundFile
                Next
            Next
        End If

        ' Loop through subdirectories of the current directory and get their files.
        For i = 0 To nSubDir - 1
            ' Recursively call this subroutine.
            ReadFileNamesFromDirectory(strDirList(i), intFileNameCount, strFileNames)
        Next
    End Sub

    Public Sub BuildArrayFromLogFile(ByRef intFileNameCount As Short)

        Dim Cnt As Short
        Dim j As Short
        Dim i As Short
        Dim OpenCount As Short
        Dim line As String
        Dim MyFile As String

        MyFile = ""

        For j = 0 To filFiles.Items.Count - 1
            If filFiles.GetSelected(j) Then
                intFileNameCount = intFileNameCount + 1
                MyFile = FolderPath & "\" & filFiles.Items(j)
            End If
        Next

        FileOpen(1, MyFile, OpenMode.Input) ' Open file for input.

        'this DoLoop will count number of entries in log file and redimension array
        Do While Not EOF(1) ' Check for end of file.
            line = LineInput(1)
            Cnt = Cnt + 1
        Loop
        FileClose(1)
        ReDim strFileNames(Cnt)
        i = -1

        FileOpen(1, MyFile, OpenMode.Input)
        Do While Not EOF(1) ' Check for end of file.
            On Error Resume Next
            line = LineInput(1)
            If line.Length > 0 Then     'ignore blank lines
                i = i + 1
                strFileNames(i) = line ' Read line of data.
            End If
        Loop
        FileClose(1) ' Close file.
        intFileNameCount = i
    End Sub
    Public Sub Process()
        Dim i, j, k, MyAttr As Short
        Dim objRevMgrApp As Object
        Dim objDocument As Object
        Dim objLinkedDocCollection As Object
        Dim objThisLink As Object
        Dim LinkCnt As Short
        Dim LinkName As String
        Dim MissingFileString As String
        Dim IsLinkMissing As Boolean
        Dim IsFileWriteProtected As Boolean
        Dim CntDocsWithMissingLinks As Short
        Dim CntDocsWriteProtected As Short

        ' Initialize flag to indicate if the user wants to stop processing files.
        StopProcess = False

        ' Build up list of files to process depending on which option was selected.

        MissingFileString = ""
        IsLinkMissing = False
        IsFileWriteProtected = False
        CntDocsWithMissingLinks = 0
        CntDocsWriteProtected = 0

        FileOpen(1, System.IO.Path.GetTempPath & "\BatchResults.txt", OpenMode.Output)
        FileOpen(2, System.IO.Path.GetTempPath & "\BatchErrorDetails.txt", OpenMode.Output)
        FileOpen(3, System.IO.Path.GetTempPath & "\BatchMissingLinks.txt", OpenMode.Output)
        FileOpen(4, System.IO.Path.GetTempPath & "\BatchWriteProtectedFiles.txt", OpenMode.Output)

        On Error Resume Next
        objRevMgrApp = CreateObject("RevisionManager.Application")

        If Err.Number Then
            MsgBox("Cannot start Revision Manager.")
            Err.Clear()
            Exit Sub
        End If

        On Error GoTo ErrorFound

        PrintLine(1, "Summary Results Processing Files")
        PrintLine(1, "Total files to process = " & (intFileNameCount + 1))
        For i = 0 To intFileNameCount

            ' Check the global variable to see if the stop process command button has been selected
            System.Windows.Forms.Application.DoEvents()
            If StopProcess Then
                MsgBox("Processing aborted.")
                GoTo RegularEnd
            End If

            Status("Processing file " & (i + 1) & " of " & (intFileNameCount + 1) & ":", strFileNames(i))

            On Error Resume Next
            objDocument = objRevMgrApp.Open(strFileNames(i))
            If Err.Number Then
                MsgBox(Err.Number & " - " & Err.Description)
                Err.Clear()
            End If

            'Before doing anything, need to see if the container is write-protected.
            'If it is, don't process and write to file it's write-protected.

            MyAttr = GetAttr(strFileNames(i))
            If MyAttr <> 32 Then
                If MyAttr <> 0 Then
                    PrintLine(4, strFileNames(i))
                    IsFileWriteProtected = True
                    CntDocsWriteProtected = CntDocsWriteProtected + 1
                End If
            End If

            objLinkedDocCollection = objDocument.LinkedDocuments
            If Err.Number Then
                MsgBox(Err.Number & " - " & Err.Description)
                Err.Clear()
            End If

            'start processing each of the linked documents
            LinkCnt = objLinkedDocCollection.Count

            If LinkCnt > 0 Then
                For j = 1 To LinkCnt
                    objThisLink = objLinkedDocCollection(j)
                    LinkName = objThisLink.FullName

                    'check to see if the linked name exists, if not write it out
                    If FileExists(LinkName) = False Then
                        MissingFileString = MissingFileString & "     " & LinkName & vbCrLf
                        IsLinkMissing = True
                    End If
                    'Print #1, "     " & LinkName

                    objThisLink = Nothing
                    LinkName = ""
                Next  ' end looping thru collection of links in the document

                If IsLinkMissing Then
                    PrintLine(2, i & ";" & strFileNames(i))
                    PrintLine(2, MissingFileString)
                    PrintLine(1, strFileNames(i) & "-MissingLinks")
                    PrintLine(3, strFileNames(i))
                    CntDocsWithMissingLinks = CntDocsWithMissingLinks + 1

                ElseIf IsFileWriteProtected Then
                    PrintLine(1, strFileNames(i) & "-WRITEPROTECTED")
                Else
                    PrintLine(1, strFileNames(i) & "-OK")
                End If
            Else
                PrintLine(1, strFileNames(i) & "-NOLINKS")
            End If ' end of if  for LinkCnt > 0

            IsLinkMissing = False
            IsFileWriteProtected = False
            MissingFileString = ""
            LinkCnt = 0

        Next
        objThisLink = Nothing
        objLinkedDocCollection = Nothing
        objDocument = Nothing
        objRevMgrApp = Nothing

        PrintLine(1, "Total Docs with Missing Links = " & CntDocsWithMissingLinks)
        PrintLine(1, "Total Docs write protected = " & CntDocsWriteProtected)

RegularEnd:
        ' Dismiss the status form.
        objRevMgrApp = Nothing
        FileClose(1)
        FileClose(2)
        FileClose(3)
        FileClose(4)
        Exit Sub

ErrorFound:
        ' Dismiss the status form.
        Status()
        objDocument = Nothing
        MsgBox("An error has occurred.  Processing has been stopped." & Chr(13) & "Last file " & "processed is " & strFileNames(i))
        FileClose(1)
        FileClose(2)

        Exit Sub
    End Sub

    Function FileExists(ByRef TestFile As String) As Boolean
        Dim value As Boolean
        Dim ret As String

        On Error Resume Next
        ret = CStr(FileDateTime(TestFile))
        value = Err.Number = 0
        If Err.Number <> 0 Then
            MsgBox(Err.Number & " - " & Err.Description)
        End If
        FileExists = value

    End Function

    Private Sub cmdStop_Click()
        StopProcess = True
    End Sub

    Private Sub optSelected_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles optSelected.CheckedChanged
        lblInstructions.Text = "Select specific files and click Process button or change Files to Process option"
        lblInstructions.Update()
    End Sub

    Private Sub optAllInDirectory_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles optAllInDirectory.CheckedChanged
        lblInstructions.Text = "Click Process button or change Files to Process option"
        lblInstructions.Update()
    End Sub

    Private Sub optAllFiles_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles optAllFiles.CheckedChanged
        lblInstructions.Text = "Click Process button or change Files to Process option"
        lblInstructions.Update()
    End Sub


End Class
