Module SEAutomationRoutines
    Dim strLocale As String
    Dim WithEvents objFileUIEvents As SolidEdgeFramework.ISEFileUIEvents_Event

    Sub GetSEVersion()

        On Error Resume Next
        Dim strVersion As String

        strVersion = objApp.Version
        If strVersion.Substring(2, 1) = "." Then intVersion = strVersion.Substring(0, 2)
        If strVersion.Substring(3, 1) = "." Then intVersion = strVersion.Substring(0, 3)

    End Sub

    
    Function GetPartObject(ByRef objOccurrence As Object, ByRef strExisting As String, ByRef strNew As String) As Short

        On Error GoTo ErrorTrap

        Dim objPart As Object
        Dim objPartDocument As Object
        Dim objProperties As Object
        Dim strData As String
        Dim intReturn As Short

        GetPartObject = ER_NOERROR

        If objOccurrence.Subassembly Then

            For Each objPart In objOccurrence.OccurrenceDocument.Occurrences
                intReturn = GetPartObject(objPart, strExisting, strNew)
            Next objPart

        Else

            If objOccurrence.Name = strExisting Then
                objOccurrence.Replace(strNew, False)
                GetPartObject = ER_REPLACED
            End If

        End If

ErrorTrap:

        If Err.Number Then
            GetPartObject = ER_FATALERROR
            Exit Function
        End If

    End Function
    Function ReplacePart() As Short

        On Error Resume Next

        Dim strSourcePart As String
        Dim strTargetPart As String
        Dim objOccurrence As Object
        Dim objSelectSet As Object
        Dim strSelectedName As String
        Dim strPart As String
        Dim intReturn As Short
        Dim objADoc As Object

        ReplacePart = ER_NOERROR

        objSelectSet = objApp.ActiveDocument.SelectSet
        strSelectedName = objSelectSet.Item(1).Name

        If objSelectSet.Count <> 1 Then
            MsgBox(LE_NOSELECTED, MsgBoxStyle.OkOnly + MsgBoxStyle.Critical + MsgBoxStyle.SystemModal, LS_MSGBOX_TITLE)
            Exit Function
        End If

        objSelectSet.RemoveAll()
        objApp.StartCommand(32876)

        ' get the part name for the source and target
        strPart = strGlobalPath & SECurrent.ChildName

        ' cycle thorugh until the name is found

        objADoc = objApp.ActiveDocument

        For Each objOccurrence In objADoc.Occurrences
            intReturn = GetPartObject(objOccurrence, strSelectedName, strPart)
            If intReturn = ER_REPLACED Then
                Exit For
            End If
            If intReturn = ER_FATALERROR Then
                MsgBox(LE_FILE & strPart & LE_NOREPLACE, MsgBoxStyle.OkOnly + MsgBoxStyle.Critical + MsgBoxStyle.SystemModal, LS_MSGBOX_TITLE)
                Exit For
            End If

        Next objOccurrence

        If Err.Number Then
            ReplacePart = ER_FATALERROR
        End If

    End Function
    Function SEConnect() As Short

        On Error Resume Next

        SEConnect = ER_NOERROR

        ' connect to solid edge and validate the environment
        objApp = GetObject(, "SolidEdge.Application")
        objFileUIEvents = objApp
        'objFileUIEvents = objApp.FileUIEvents
        AddOrRemoveEventHandlers(True)

        If Err.Number Then
            ' edge probably not loaded
            SEConnect = ER_FATALERROR
            Exit Function
        End If
        If UCase(objApp.ActiveEnvironment) <> "ASSEMBLY" And UCase(objApp.ActiveEnvironment) <> "DMASSEMBLY" Then
            SEConnect = ER_NOASSEMBLY
            Exit Function
        End If

    End Function

    Public Sub AddOrRemoveEventHandlers(ByVal Add As Boolean)
        If Add Then
            ' Add the handlers for events we want to respond to.
            If Not objFileUIEvents Is Nothing Then
                ' Must be a corresponding RemoveHandler for each call to AddHandler.
                AddHandler objFileUIEvents.OnPlacePartUI, AddressOf objFileUIEvents_OnPlacePartUI
                'AddHandler objFileUIEvents.OnCreateInPlacePartUI, AddressOf objFileUIEvents_OnCreateInPlacePartUI

            End If
        Else
            ' Remove the handlers as we are done responding to events
            If Not objFileUIEvents Is Nothing Then
                ' The corresponding RemoveHandler calls.
                RemoveHandler objFileUIEvents.OnPlacePartUI, AddressOf objFileUIEvents_OnPlacePartUI
                'RemoveHandler objFileUIEvents.OnCreateInPlacePartUI, AddressOf objFileUIEvents_OnCreateInPlacePartUI

                ' Must call ReleaseComObject now or GC will do so at shutdown as DLLs are unloading, which is
                ' a major problem since there is no control over the order DLLs are unloaded and that can lead
                ' to exceptions that may or may not be caught by the .NET runtime.
                System.Runtime.InteropServices.Marshal.ReleaseComObject(objFileUIEvents)

                ' fix for PR# 6871627 where you would get an exception here.  May be a timing issue but since we are shutting all the way down anyway...
                Try
                    objFileUIEvents = Nothing
                Catch ex As Exception

                End Try
            End If
        End If
    End Sub

    Private Sub objFileUIEvents_OnPlacePartUI(ByRef Filename As String, ByRef AppendToTitle As String) Handles objFileUIEvents.OnPlacePartUI

        On Error Resume Next

        Filename = strGlobalPath & SECurrent.ChildName

    End Sub



    Function SEBuildPart() As Short

        On Error Resume Next

        Dim strSourcePart As String
        Dim strTargetPart As String
        Dim objProperties As Object
        Dim objSummaryInfo As Object
        Dim objProjectInfo As Object
        Dim objTemp As Object
        Dim intCurrent As Short
        Dim i As Short
        Dim strValue As String
        Dim dblValue As Double

        SEBuildPart = ER_NOERROR

        ' get the part name for the source and target
        strSourcePart = strGlobalPath & SECurrent.ParentName
        strTargetPart = strGlobalPath & SECurrent.ChildName

        ' first test for the source file
        If CheckForFile(strSourcePart) = ER_FILENOTFOUND Then
            MsgBox(LE_FILE & strSourcePart & LE_NOTFOUNDSTOP, MsgBoxStyle.OkOnly + MsgBoxStyle.Critical + MsgBoxStyle.SystemModal, LS_MSGBOX_TITLE)
            SEBuildPart = ER_NOSOURCEFILE
            Err.Clear()
            GoTo Wrapup
        End If

        If CheckForFile(strTargetPart) = ER_FILEFOUND Then
            SEBuildPart = ER_FILEEXISTS
            Err.Clear()
            GoTo Wrapup
        End If

        frmSELibrary.lblMessage.Text = LT_PROCESS_COPYPART
        FileCopy(strSourcePart, strTargetPart)

        System.Windows.Forms.Application.DoEvents()

        If Err.Number Then
            MsgBox(LE_FILE & strTargetPart & LE_COPYFAIL, MsgBoxStyle.OkOnly + MsgBoxStyle.Critical + MsgBoxStyle.SystemModal, LS_MSGBOX_TITLE)
            SEBuildPart = ER_COPYFAIL
            Err.Clear()
            GoTo Wrapup
        End If

        objDoc = objApp.Documents.Open(strTargetPart)
        System.Windows.Forms.Application.DoEvents()

        If Err.Number Then
            MsgBox(LE_FILE & strSourcePart & LE_NOOPEN, MsgBoxStyle.OkOnly + MsgBoxStyle.Critical + MsgBoxStyle.SystemModal, LS_MSGBOX_TITLE)
            SEBuildPart = ER_NOOPEN
            Err.Clear()
            GoTo Wrapup
        End If

        objDoc.Save()

        System.Windows.Forms.Application.DoEvents()

        'hide the window to clean up the interface
        objApp.ActiveWindow.Visible = False
        System.Windows.Forms.Application.DoEvents()

        frmSELibrary.lblMessage.Text = LT_PROCESS_UPDATEPART

        ' delay compute
        objApp.DelayCompute = True

        objVariables = objDoc.Variables

        If objVariables.Count + 1 < UBound(SECurrent.Variables) Then
            If MsgBox(LE_FILE & strTargetPart & LE_NOPARTVARS, MsgBoxStyle.OkOnly + MsgBoxStyle.Critical + MsgBoxStyle.SystemModal, LS_MSGBOX_TITLE) = MsgBoxResult.No Then
                objApp.DelayCompute = False
                objApp.ActiveDocument.Models(1).Recompute()
                objApp.ActiveDocument.Close()
                objApp.ActiveDocument.Windows(1).View.Fit()
                objApp.ActiveDocument.Save()
                SEBuildPart = CShort(LE_NOPARTVARS)

                If Err.Number Then
                    MsgBox(LE_FILE & strTargetPart & LE_NOUPDATE, MsgBoxStyle.OkOnly + MsgBoxStyle.Critical + MsgBoxStyle.SystemModal, LS_MSGBOX_TITLE)
                    SEBuildPart = CShort(LE_NOUPDATE)
                    Err.Clear()
                    GoTo Wrapup
                    'Exit Function
                End If
                GoTo Wrapup
                'Exit Function
            End If
        End If

        For i = 1 To UBound(SECurrent.Variables) - 1

            strValue = ConvertValues(SECurrent.Sizes(i))
            dblValue = CDbl(strValue)
            If dblValue <= 0 Then
                ' this is bad since SE can't handle <= zero stuff
                MsgBox(LE_FILE & strTargetPart & Chr(10) & LE_ZERODIM1 & Str(dblValue) & LE_ZERODIM2, MsgBoxStyle.OkOnly + MsgBoxStyle.Critical + MsgBoxStyle.SystemModal, LS_MSGBOX_TITLE)
            Else
                objTemp = objVariables.Query(SECurrent.Variables(i))
                objTemp.Item(1).Value = objApp.ActiveDocument.UnitsOfMeasure.ParseUnit(1, dblValue)
                System.Windows.Forms.Application.DoEvents()
                objTemp = Nothing
            End If
        Next

        ' force compute
        objApp.DelayCompute = False
        objDoc.Models.Item(1).Recompute()
        objDoc.Save()
        System.Windows.Forms.Application.DoEvents()

        If Err.Number Then
            MsgBox(LE_FILE & strTargetPart & LE_NOUPDATE, MsgBoxStyle.OkOnly + MsgBoxStyle.Critical + MsgBoxStyle.SystemModal, LS_MSGBOX_TITLE)
            SEBuildPart = CShort(LE_NOUPDATE)
            Err.Clear()
            GoTo Wrapup
            'Exit Function
        End If

        ' update the part property information
        objProperties = objDoc.Properties

        objProperties.Item("SummaryInformation")("Title").Value = SEData(intCurrentPartID).PartClass & " " & SECurrent.Sizes(1)
        objProperties.Item("SummaryInformation")("Author").Value = GetUser()
        objProperties.Item("DocumentSummaryInformation")("Category").Value = SEData(intCurrentPartID).Type

        objProperties.Save()
        objProperties = Nothing

        ' save
        objDoc.Save()

        System.Windows.Forms.Application.DoEvents()

        If Err.Number Then
            MsgBox(LE_FILE & strTargetPart & LE_NOPROPERTIES, MsgBoxStyle.OkOnly + MsgBoxStyle.Information + MsgBoxStyle.SystemModal, LS_MSGBOX_TITLE)
            SEBuildPart = CShort(LE_NOUPDATE)
            Err.Clear()
        End If

        ' enable the full property editor
        If frmSELibrary.chkProperties.CheckState = 1 Then

            objApp.ActiveWindow.Visible = True
            System.Windows.Forms.Application.DoEvents()

            ' fit it
            objDoc.Windows.Item(1).View.Fit()

            frmSELibrary.Enabled = False
            frmSELibrary.Visible = False
            objDoc.EditProperties()
            frmSELibrary.Enabled = True
            frmSELibrary.Visible = True
        End If

        ' just in case
        Err.Clear()

        objDoc.Save()

        System.Windows.Forms.Application.DoEvents()
        frmSELibrary.lblMessage.Text = LT_PROCESS_SAVEPART

        If Err.Number Then
            MsgBox(LE_FILE & strSourcePart & LE_NOSAVE, MsgBoxStyle.OkOnly + MsgBoxStyle.Critical + MsgBoxStyle.SystemModal, LS_MSGBOX_TITLE)
            SEBuildPart = CShort(LE_NOSAVE)
            Err.Clear()
            GoTo Wrapup
        End If

        ' close
        objApp.ActiveDocument.Close()

Wrapup:

        objVariables = Nothing
        objProperties = Nothing
        objSummaryInfo = Nothing
        objProjectInfo = Nothing
        objDoc = Nothing

    End Function
    Function ConvertValues(ByRef strData As String) As String

        On Error Resume Next
        Dim intInt As Short
        Dim intNum As Short
        Dim intDen As Short
        Dim dblData As Double
        Dim intSpace As Short
        Dim intDivide As Short

        intDen = 1

        ' could be decimal form already
        If InStr(1, strData, "/") > 0 Or InStr(1, strData, " ") > 0 Then
            ' definately a fraction or mixed fraction
            ' if it has a space, get the integer portion
            intSpace = InStr(1, strData, " ")
            If intSpace > 0 Then
                ' mixed get integer and fraction
                intInt = Val(Mid(strData, 1, intSpace - 1))
            End If

            intDivide = InStr(1, strData, "/")
            If intDivide > 0 Then
                ' has fraction get numerator
                intNum = Val(Mid(strData, intSpace + 1, intDivide - intSpace - 1))
                intDen = Val(Mid(strData, intDivide + 1, Len(strData) - intDivide))
                If intDen = 0 Then
                    ' poor data entry
                    MsgBox(LE_DIVIDEBYZERO, MsgBoxStyle.Critical + MsgBoxStyle.OkOnly + MsgBoxStyle.SystemModal, LS_MSGBOX_TITLE)
                    intNum = 1
                    intDen = 1
                End If
            End If
            If intDen = 0 Then
                MsgBox(LE_DIVIDEBYZERO, MsgBoxStyle.Critical + MsgBoxStyle.OkOnly + MsgBoxStyle.SystemModal, LS_MSGBOX_TITLE)
                intNum = 1
                intDen = 1
            End If
            dblData = intInt + (intNum / intDen)
            ConvertValues = Format(dblData, C_NUMBERFORMAT)

        Else
            ' decimal or integer could be illegal "2.2 1/2"
            ConvertValues = Format(Val(strData))
        End If

        If Err.Number Then
            ConvertValues = CStr(1)
        End If
    End Function
    Function GetUser() As String

        On Error Resume Next

        Dim strBuffer As String
        Dim lngSize As Integer

        strBuffer = Space(255)
        lngSize = Len(strBuffer)

        GetUserName(strBuffer, lngSize)

        If lngSize > 0 Then
            ' remove spaces
            GetUser = Left(strBuffer, lngSize)
        Else
            GetUser = ""
        End If

        If Err.Number Then
            GetUser = ""
        End If

    End Function
End Module
