Public Class SEAssemblyRelationshipBrowser

#Region "Data"

    ' constants to define the indexes for the various relationship status check-boxes
    Dim SolvedIndex As Integer = 0
    Dim UnsolvedIndex As Integer = 1
    Dim SuppressedIndex As Integer = 2
    Dim UnsatisfiedIndex As Integer = 3
    Dim MissingGeometryIndex As Integer = 4
    Dim BetweenSetMembersIndex As Integer = 5
    Dim BetweenFixedIndex As Integer = 6
    Dim UnknownStatusIndex As Integer = 7

    ' constants to define the indexes for the various relationship type check-boxes
    Dim GroundIndex As Integer = 0
    Dim MateIndex As Integer = 1
    Dim PlanarAlignIndex As Integer = 2
    Dim AxialAlignIndex As Integer = 3
    Dim ConnectIndex As Integer = 4
    Dim AngleIndex As Integer = 5
    Dim TangentIndex As Integer = 6
    Dim CamIndex As Integer = 7
    Dim PathIndex As Integer = 8
    Dim GearIndex As Integer = 9
    Dim CenterPlaneIndex As Integer = 10
    Dim RigidSetIndex As Integer = 11

    ' various Solid Edge objects we will need
    Private m_RelationshipObjects As New List(Of Object)
    Private m_SolidEdgeApplication As SolidEdgeFramework.Application
    Private m_ActiveDocument As SolidEdgeAssembly.AssemblyDocument
    Private m_Relations3d As SolidEdgeAssembly.Relations3d
    Private m_HighlightSet As SolidEdgeFramework.HighlightSet
    Private m_SelectSet As SolidEdgeFramework.SelectSet

    ' whether or not the controls on the form have been initialized for use
    Private m_ControlsInitialized As Boolean = False

    ' whether or not to use detailed relationship item tooltips
    Private m_ShowDetailedTooltips As Boolean = False

    ' whether or not to display the various relationship types in the list
    Private m_ShowGround As Boolean = True
    Private m_ShowMate As Boolean = True
    Private m_ShowPlanarAlign As Boolean = True
    Private m_ShowAxial As Boolean = True
    Private m_ShowConnect As Boolean = True
    Private m_ShowAngle As Boolean = True
    Private m_ShowTangent As Boolean = True
    Private m_ShowCam As Boolean = True
    Private m_ShowPath As Boolean = True
    Private m_ShowGear As Boolean = True
    Private m_ShowCenterPlane As Boolean = True
    Private m_ShowRigidSet As Boolean = True

    ' whether or not to display relationships in the list based on the various statuses
    Private m_ShowSolved As Boolean = False
    Private m_ShowUnsolved As Boolean = False
    Private m_ShowSuppressed As Boolean = False
    Private m_ShowUnsatisfied As Boolean = False
    Private m_ShowMissingGeometry As Boolean = False
    Private m_ShowBetweenSetMembers As Boolean = False
    Private m_ShowBetweenFixed As Boolean = False
    Private m_ShowUnknown As Boolean = False

    Private Sub SetMemberData()
        ' Get the application
        Try
            m_SolidEdgeApplication = DirectCast(GetObject(, "SolidEdge.Application"), SolidEdgeFramework.Application)
        Catch ex As Exception
            m_SolidEdgeApplication = Nothing
        End Try

        If Not m_SolidEdgeApplication Is Nothing Then
            ' Get the active select set
            Try
                m_SelectSet = DirectCast(m_SolidEdgeApplication.ActiveSelectSet, SolidEdgeFramework.SelectSet)
            Catch ex As Exception
                m_SelectSet = Nothing
            End Try

            ' Get the active document
            Try
                m_ActiveDocument = DirectCast(m_SolidEdgeApplication.ActiveDocument, SolidEdgeAssembly.AssemblyDocument)
            Catch ex As Exception
                m_ActiveDocument = Nothing
            End Try

            ' Get a highlight set to highlight the relationship faces
            If Not m_ActiveDocument Is Nothing Then

                ' If there are no highlight sets, add one. Otherwise, use the first one.
                If m_ActiveDocument.HighlightSets.Count = 0 Then
                    m_HighlightSet = m_ActiveDocument.HighlightSets.Add
                Else
                    m_HighlightSet = m_ActiveDocument.HighlightSets.Item(1)
                End If

                If Not m_HighlightSet Is Nothing Then
                    ' Set the highlight set color to lime green which is close to the Solid Edge
                    ' default highlight color.
                    m_HighlightSet.Color = System.Drawing.Color.LimeGreen.ToArgb

                    ' Draw the highlight set.
                    m_HighlightSet.Draw()
                End If

                ' Get the Relations3d collection from the assembly document
                Try
                    m_Relations3d = DirectCast(m_ActiveDocument.Relations3d, SolidEdgeAssembly.Relations3d)
                Catch ex As Exception
                    m_Relations3d = Nothing
                End Try
            End If
        End If
    End Sub

    ' Return whether or not the member data has been set up properly and is ready for relationship processing.
    Private Function IsReadyToProcessRelationships() As Boolean
        Dim IsReady As Boolean = False

        IsReady = Not m_SolidEdgeApplication Is Nothing AndAlso
                  Not m_ActiveDocument Is Nothing AndAlso
                  Not m_HighlightSet Is Nothing AndAlso
                  Not m_SelectSet Is Nothing

        Return IsReady
    End Function

#End Region

    Private Sub SEAssemblyRelationshipBrowser_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        RelationshipList.Items.Clear()

        m_SolidEdgeApplication = Nothing
        m_ActiveDocument = Nothing
        m_Relations3d = Nothing
        m_HighlightSet = Nothing

        InitializeControls()

        FillRelationshipListWithRelationshipObjects()

    End Sub

#Region "Utilities"

    Private Sub BeginUpdate()
        Cursor = Cursors.WaitCursor

        m_SolidEdgeApplication.DelayCompute = True
    End Sub

    Private Sub EndUpdate()
        m_SolidEdgeApplication.DelayCompute = False

        m_SolidEdgeApplication.ActiveWindow.View.Update()

        Cursor = Cursors.Default

        ' Repopulate the unsatisfied relationship list
        FillRelationshipListWithRelationshipObjects()
    End Sub

    ' Returns the string to display in the list for a binary assembly relationship (one that is between two objects).
    Private Function GenerateBinaryRelationshipString(ByVal Relationship As Object, RelationshipType As String) As String
        Dim ReturnString As String
        Dim Occurrence1 As SolidEdgeAssembly.Occurrence = Nothing
        Dim Occurrence2 As SolidEdgeAssembly.Occurrence = Nothing

        ReturnString = RelationshipType

        ' Try to get the two occurrences from the relationship (one of them could be Nothing if the relationship is to an assembly
        ' reference plane).
        Try
            Occurrence1 = DirectCast(Relationship.Occurrence1, SolidEdgeAssembly.Occurrence)
        Catch ex As Exception
            Occurrence1 = Nothing
        End Try

        Try
            Occurrence2 = DirectCast(Relationship.Occurrence2, SolidEdgeAssembly.Occurrence)
        Catch ex As Exception
            Occurrence2 = Nothing
        End Try

        ' Generate the string by adding the occurrence names to the relationship type string if the occurrence is
        ' not Nothing.
        If Not Occurrence1 Is Nothing Then
            If Not Occurrence2 Is Nothing Then
                ReturnString = ReturnString + " ( " + Occurrence1.Name + ", " + Occurrence2.Name + " )"
            Else
                ReturnString = ReturnString + " ( " + Occurrence1.Name + " )"
            End If
        ElseIf Not Occurrence2 Is Nothing Then
            ReturnString = ReturnString + " ( " + Occurrence2.Name + " )"
        End If

        Return ReturnString
    End Function

    ' Returns a string containing the entire path of occurrences all the way down to the input element. It should be noted that
    ' this will activate all occurrences in the path because of the way dealing with references works.
    Private Function GenerateOccurrencePathString(ByVal Element As Object, ByVal IsTopologyReference As Boolean) As String
        Dim ReturnString As String

        ReturnString = ""

        ' Only try to build the path if the element is a topology reference.
        If Not Element Is Nothing AndAlso IsTopologyReference = True Then
            Dim ElementReference As SolidEdgeFramework.Reference = Nothing

            Try
                ElementReference = DirectCast(Element, SolidEdgeFramework.Reference)
            Catch ex As Exception
                ElementReference = Nothing
            End Try

            If Not ElementReference Is Nothing Then
                Dim TopOccurrence As Object = Nothing
                Dim NumberOfSubOccurrences As Integer = 0
                Dim NumberOfBoundSubOccurrences As Integer = 0
                Dim SubOccurrences As System.Array = {0}

                ' The element is a topology reference, so now get all of the occurrences in the path down to the reference.
                ElementReference.GetOccurrencesInPath(TopOccurrence, NumberOfSubOccurrences, NumberOfBoundSubOccurrences, SubOccurrences)

                If Not TopOccurrence Is Nothing Then
                    ' Start the return string with the top occurrence name.
                    ReturnString = ReturnString + TopOccurrence.Name

                    ' If there are sub-occurrences, go through and add each sub-occurrence name to the string (separated by a / ).
                    If Not NumberOfSubOccurrences = 0 Then
                        For Each SubOccurrence In SubOccurrences
                            If Not SubOccurrence Is Nothing Then
                                If Not String.IsNullOrEmpty(ReturnString) Then
                                    ReturnString = ReturnString + "/"
                                End If

                                ReturnString = ReturnString + SubOccurrence.Name
                            End If
                        Next
                    End If
                End If
            End If
        End If

        Return ReturnString
    End Function

    ' Returns the string to display as a tooltip for a binary assembly relationship item (one that is between two objects). Only
    ' return a string if the option to display detailed tooltips is set because it can cause a lot of occurrences to be activated.
    Private Function GenerateBinaryRelationshipTooltipString(ByVal Relationship As Object) As String
        Dim ReturnString As String

        ReturnString = ""

        If m_ShowDetailedTooltips = True Then
            Dim Element1 As Object = Nothing
            Dim Element2 As Object = Nothing
            Dim IsTopologyReference As Boolean = False

            ' Get the occurrence path string for the first element in the relationship.
            Try
                Element1 = DirectCast(Relationship.GetElement1(IsTopologyReference), Object)
            Catch ex As Exception
                Element1 = Nothing
            End Try

            If Not Element1 Is Nothing Then
                Dim Occurrence1Path As String

                Occurrence1Path = GenerateOccurrencePathString(Element1, IsTopologyReference)

                If Not String.IsNullOrEmpty(Occurrence1Path) Then
                    ReturnString = Occurrence1Path
                End If
            End If

            IsTopologyReference = False

            Try
                Element2 = DirectCast(Relationship.GetElement2(IsTopologyReference), Object)
            Catch ex As Exception
                Element2 = Nothing
            End Try

            ' Get the occurrence path string for the second element in the relationship.
            If Not Element2 Is Nothing Then
                Dim Occurrence2Path As String

                Occurrence2Path = GenerateOccurrencePathString(Element2, IsTopologyReference)

                If Not String.IsNullOrEmpty(Occurrence2Path) Then
                    If Not String.IsNullOrEmpty(ReturnString) Then
                        ' Put the second element occurrence path on a new line if the first element
                        ' occurrence path is not empty.
                        ReturnString = ReturnString + Environment.NewLine
                    End If

                    ReturnString = ReturnString + Occurrence2Path
                End If
            End If
        End If

        Return ReturnString
    End Function

    ' Returns the string to display as a tooltip for assembly rigid set relationship items. Only
    ' return a string if the option to display detailed tooltips is set because it can cause a lot of occurrences to be activated.
    Private Function GenerateRigidSetTooltipString(ByVal Relationship As Object) As String
        Dim ReturnString As String

        ReturnString = ""

        If m_ShowDetailedTooltips = True Then
            If Not Relationship Is Nothing Then
                Dim RigidSet As SolidEdgeAssembly.RigidSetRelation3d = Nothing

                Try
                    RigidSet = DirectCast(Relationship, SolidEdgeAssembly.RigidSetRelation3d)
                Catch ex As Exception
                    RigidSet = Nothing
                End Try

                ' Get the occurrence path for each occurrence in the rigid set and add it to the tooltip string (separated by a new line).
                If Not RigidSet Is Nothing Then
                    For Each occ In RigidSet.Occurrences
                        Dim OccurrenceReference As SolidEdgeFramework.Reference = Nothing
                        Dim OccurrencePath As String

                        Try
                            OccurrenceReference = DirectCast(occ, SolidEdgeFramework.Reference)
                        Catch ex As Exception
                            OccurrenceReference = Nothing
                        End Try

                        If OccurrenceReference Is Nothing Then
                            OccurrencePath = occ.Name
                        Else
                            OccurrencePath = GenerateOccurrencePathString(occ, True)

                        End If

                        If Not String.IsNullOrEmpty(ReturnString) Then
                            ReturnString = ReturnString + Environment.NewLine
                            ReturnString = ReturnString + OccurrencePath
                        Else
                            ReturnString = OccurrencePath
                        End If
                    Next
                End If
            End If
        End If

        Return ReturnString
    End Function

    ' Returns whether or not at least one of the relationship type check-boxes is checked. If not, nothing
    ' will be displayed.
    Private Function AtLeastOneConstraintTypeSelected() As Boolean
        Dim bReturn As Boolean = False

        bReturn = m_ShowGround = True Or
                  m_ShowMate = True Or
                  m_ShowPlanarAlign = True Or
                  m_ShowAxial = True Or
                  m_ShowConnect = True Or
                  m_ShowAngle = True Or
                  m_ShowTangent = True Or
                  m_ShowCam = True Or
                  m_ShowPath = True Or
                  m_ShowGear = True Or
                  m_ShowCenterPlane = True Or
                  m_ShowRigidSet = True

        Return bReturn
    End Function

    ' Returns whether or not at least one of the relationship status check-boxes is checked. If not, nothing
    ' will be displayed.
    Private Function AtLeastOneConstraintStatusSelected() As Boolean
        Dim bReturn As Boolean = False

        bReturn = m_ShowSolved = True Or
                  m_ShowUnsolved = True Or
                  m_ShowSuppressed = True Or
                  m_ShowUnsatisfied = True Or
                  m_ShowMissingGeometry = True Or
                  m_ShowBetweenSetMembers = True Or
                  m_ShowBetweenFixed = True Or
                  m_ShowUnknown = True

        Return bReturn
    End Function

#End Region

#Region "Control Handling"

    Private Sub InitializeControls()
        m_ShowDetailedTooltips = False
        m_ControlsInitialized = False

        RelationshipTypeListBox.SetItemChecked(GroundIndex, True)
        RelationshipTypeListBox.SetItemChecked(MateIndex, True)
        RelationshipTypeListBox.SetItemChecked(PlanarAlignIndex, True)
        RelationshipTypeListBox.SetItemChecked(AxialAlignIndex, True)
        RelationshipTypeListBox.SetItemChecked(ConnectIndex, True)
        RelationshipTypeListBox.SetItemChecked(AngleIndex, True)
        RelationshipTypeListBox.SetItemChecked(TangentIndex, True)
        RelationshipTypeListBox.SetItemChecked(CamIndex, True)
        RelationshipTypeListBox.SetItemChecked(PathIndex, True)
        RelationshipTypeListBox.SetItemChecked(GearIndex, True)
        RelationshipTypeListBox.SetItemChecked(CenterPlaneIndex, True)
        RelationshipTypeListBox.SetItemChecked(RigidSetIndex, True)

        m_ShowGround = True
        m_ShowMate = True
        m_ShowPlanarAlign = True
        m_ShowAxial = True
        m_ShowConnect = True
        m_ShowAngle = True
        m_ShowTangent = True
        m_ShowCam = True
        m_ShowPath = True
        m_ShowGear = True
        m_ShowCenterPlane = True
        m_ShowRigidSet = True

        StatusCheckedListBox.SetItemChecked(SolvedIndex, False)
        StatusCheckedListBox.SetItemChecked(UnsolvedIndex, False)
        StatusCheckedListBox.SetItemChecked(SuppressedIndex, False)
        StatusCheckedListBox.SetItemChecked(UnsatisfiedIndex, False)
        StatusCheckedListBox.SetItemChecked(MissingGeometryIndex, False)
        StatusCheckedListBox.SetItemChecked(BetweenSetMembersIndex, False)
        StatusCheckedListBox.SetItemChecked(BetweenFixedIndex, False)
        StatusCheckedListBox.SetItemChecked(UnknownStatusIndex, False)

        m_ShowSolved = False
        m_ShowUnsolved = False
        m_ShowSuppressed = False
        m_ShowUnsatisfied = False
        m_ShowMissingGeometry = False
        m_ShowBetweenSetMembers = False
        m_ShowBetweenFixed = False
        m_ShowUnknown = False

        m_ControlsInitialized = True
    End Sub

    ' Called when the selected item changes in the relationship list.
    Private Sub RelationshipList_SelectedIndexChanged(sender As System.Object, e As System.EventArgs) Handles RelationshipList.SelectedIndexChanged
        m_HighlightSet.RemoveAll()

        ' Highlight each selected relationship's data.
        If Not RelationshipList.SelectedItems.Count = 0 Then
            Dim SelectedRelationships As ListView.SelectedListViewItemCollection = Nothing

            Try
                SelectedRelationships = DirectCast(RelationshipList.SelectedItems, ListView.SelectedListViewItemCollection)
            Catch ex As Exception
                SelectedRelationships = Nothing
            End Try

            If Not SelectedRelationships Is Nothing Then
                Dim SelectedRelationship As ListViewItem

                Try
                    For Each SelectedRelationship In SelectedRelationships
                        HighlightRelationshipData(m_RelationshipObjects(SelectedRelationship.Index))
                    Next
                Catch ex As Exception
                    FillRelationshipListWithRelationshipObjects()
                End Try
            End If
        End If

        m_HighlightSet.Draw()
    End Sub

    Private Sub StatusComboBox_SelectedIndexChanged(sender As System.Object, e As System.EventArgs)
        If Not m_SolidEdgeApplication Is Nothing Then
            FillRelationshipListWithRelationshipObjects()
        End If
    End Sub

    Private Sub Refresh_Click(sender As System.Object, e As System.EventArgs) Handles RefreshButton.Click
        FillRelationshipListWithRelationshipObjects()
    End Sub

    Private Sub ForceRecomputeButton_Click(sender As System.Object, e As System.EventArgs) Handles ForceRecomputeButton.Click
        SetMemberData()

        If IsReadyToProcessRelationships() Then
            If Not m_Relations3d.Count = 0 Then
                BeginUpdate()

                If m_Relations3d.Item(1).Suppress = True Then
                    m_Relations3d.Item(1).Suppress = False
                    m_Relations3d.Item(1).Suppress = True
                Else
                    m_Relations3d.Item(1).Suppress = True
                    m_Relations3d.Item(1).Suppress = False
                End If

                EndUpdate()
            End If
        End If

    End Sub

    Private Sub TooltipCheckBox_CheckedChanged(sender As System.Object, e As System.EventArgs) Handles TooltipCheckBox.CheckedChanged
        m_ShowDetailedTooltips = TooltipCheckBox.Checked

        RelationshipList.ShowItemToolTips = m_ShowDetailedTooltips

        ' go through and update the tooltip information
        FillRelationshipListWithRelationshipObjects()
    End Sub

    Private Sub RelationshipTypeListBox_ItemCheck(sender As System.Object, e As System.Windows.Forms.ItemCheckEventArgs) Handles RelationshipTypeListBox.ItemCheck
        Select Case e.Index
            Case AngleIndex
                m_ShowAngle = e.NewValue
            Case AxialAlignIndex
                m_ShowAxial = e.NewValue
            Case CamIndex
                m_ShowCam = e.NewValue
            Case CenterPlaneIndex
                m_ShowCenterPlane = e.NewValue
            Case ConnectIndex
                m_ShowConnect = e.NewValue
            Case GearIndex
                m_ShowGear = e.NewValue
            Case GroundIndex
                m_ShowGround = e.NewValue
            Case MateIndex
                m_ShowMate = e.NewValue
            Case PathIndex
                m_ShowPath = e.NewValue
            Case PlanarAlignIndex
                m_ShowPlanarAlign = e.NewValue
            Case RigidSetIndex
                m_ShowRigidSet = e.NewValue
            Case TangentIndex
                m_ShowTangent = e.NewValue
        End Select

        If m_ControlsInitialized = True Then
            FillRelationshipListWithRelationshipObjects()
        End If
    End Sub

    Private Sub StatusTypeListBox_ItemCheck(sender As System.Object, e As System.Windows.Forms.ItemCheckEventArgs) Handles StatusCheckedListBox.ItemCheck
        Select Case e.Index
            Case SolvedIndex
                m_ShowSolved = e.NewValue
            Case UnsolvedIndex
                m_ShowUnsolved = e.NewValue
            Case SuppressedIndex
                m_ShowSuppressed = e.NewValue
            Case UnsatisfiedIndex
                m_ShowUnsatisfied = e.NewValue
            Case MissingGeometryIndex
                m_ShowMissingGeometry = e.NewValue
            Case BetweenSetMembersIndex
                m_ShowBetweenSetMembers = e.NewValue
            Case BetweenFixedIndex
                m_ShowBetweenFixed = e.NewValue
            Case UnknownStatusIndex
                m_ShowUnknown = e.NewValue
        End Select

        If m_ControlsInitialized = True Then
            FillRelationshipListWithRelationshipObjects()
        End If
    End Sub

    Private Sub CheckAll_Click(sender As System.Object, e As System.EventArgs) Handles CheckAll.Click
        RelationshipListCheckAll(True)
    End Sub

    Private Sub UncheckAll_Click(sender As System.Object, e As System.EventArgs) Handles UncheckAll.Click
        RelationshipListCheckAll(False)
    End Sub

    Private Sub SuppressUnsuppressMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles SuppressUnsuppressMenuItem.Click
        If IsReadyToProcessRelationships() Then
            BeginUpdate()

            Try
                For Each RelationshipItem In RelationshipList.CheckedItems
                    If m_RelationshipObjects(RelationshipItem.Index).Suppress = True Then
                        m_RelationshipObjects(RelationshipItem.Index).Suppress = False
                    Else
                        m_RelationshipObjects(RelationshipItem.Index).Suppress = True
                    End If
                Next
            Catch ex As Exception
            End Try

            EndUpdate()
        End If
    End Sub

    Private Sub DeleteMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles DeleteMenuItem.Click
        If IsReadyToProcessRelationships() Then
            BeginUpdate()

            Try
                For Each RelationshipItem In RelationshipList.CheckedItems
                    m_RelationshipObjects(RelationshipItem.Index).Delete()
                Next
            Catch ex As Exception
            End Try

            EndUpdate()
        End If
    End Sub

    Private Sub FlipMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles FlipMenuItem.Click
        If IsReadyToProcessRelationships() Then
            BeginUpdate()

            Try
                For Each RelationshipItem In RelationshipList.CheckedItems
                    Select Case m_RelationshipObjects(RelationshipItem.Index).Type
                        Case SolidEdgeFramework.ObjectType.igPlanarRelation3d
                            If m_RelationshipObjects(RelationshipItem.Index).NormalsAligned = False Then
                                m_RelationshipObjects(RelationshipItem.Index).NormalsAligned = True
                            Else
                                m_RelationshipObjects(RelationshipItem.Index).NormalsAligned = False
                            End If
                        Case SolidEdgeFramework.ObjectType.igTangentRelation3d
                            If m_RelationshipObjects(RelationshipItem.Index).HalfSpacePositive = False Then
                                m_RelationshipObjects(RelationshipItem.Index).HalfSpacePositive = True
                            Else
                                m_RelationshipObjects(RelationshipItem.Index).HalfSpacePositive = False
                            End If
                        Case SolidEdgeFramework.ObjectType.igCenterPlaneRelation3d
                            m_RelationshipObjects(RelationshipItem.Index).Flip()
                    End Select
                Next
            Catch ex As Exception
            End Try

            EndUpdate()
        End If
    End Sub

    Private Sub SelectComponentsMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles SelectComponentsMenuItem.Click
        If IsReadyToProcessRelationships() Then
            If Not RelationshipList.CheckedItems.Count = 0 Then
                Cursor = Cursors.WaitCursor

                m_SelectSet.SuspendDisplay()

                ' First, clear the select set
                m_SelectSet.RemoveAll()

                Try
                    ' Now, add the components for each checked relationship
                    For Each RelationshipItem In RelationshipList.CheckedItems
                        SelectRelationshipComponents(m_RelationshipObjects(RelationshipItem.Index))
                    Next
                Catch ex As Exception
                End Try

                m_SelectSet.ResumeDisplay()
                m_SelectSet.RefreshDisplay()

                Cursor = Cursors.Default
            End If
        End If
    End Sub

    Private Sub RelationshipListCheckAll(ByVal check As Boolean)
        For Each RelationshipItem In RelationshipList.Items
            RelationshipItem.Checked = check
        Next
    End Sub

    Private Sub ConstraintTypeCheckAll(ByVal check As Boolean)
        m_ControlsInitialized = False

        RelationshipTypeListBox.SetItemChecked(GroundIndex, check)
        RelationshipTypeListBox.SetItemChecked(MateIndex, check)
        RelationshipTypeListBox.SetItemChecked(PlanarAlignIndex, check)
        RelationshipTypeListBox.SetItemChecked(AxialAlignIndex, check)
        RelationshipTypeListBox.SetItemChecked(ConnectIndex, check)
        RelationshipTypeListBox.SetItemChecked(AngleIndex, check)
        RelationshipTypeListBox.SetItemChecked(TangentIndex, check)
        RelationshipTypeListBox.SetItemChecked(CamIndex, check)
        RelationshipTypeListBox.SetItemChecked(PathIndex, check)
        RelationshipTypeListBox.SetItemChecked(GearIndex, check)
        RelationshipTypeListBox.SetItemChecked(CenterPlaneIndex, check)
        RelationshipTypeListBox.SetItemChecked(RigidSetIndex, check)

        m_ControlsInitialized = True

        FillRelationshipListWithRelationshipObjects()
    End Sub

    Private Sub StatusCheckAll(ByVal check As Boolean)
        m_ControlsInitialized = False

        StatusCheckedListBox.SetItemChecked(SolvedIndex, check)
        StatusCheckedListBox.SetItemChecked(UnsolvedIndex, check)
        StatusCheckedListBox.SetItemChecked(SuppressedIndex, check)
        StatusCheckedListBox.SetItemChecked(UnsatisfiedIndex, check)
        StatusCheckedListBox.SetItemChecked(MissingGeometryIndex, check)
        StatusCheckedListBox.SetItemChecked(BetweenSetMembersIndex, check)
        StatusCheckedListBox.SetItemChecked(BetweenFixedIndex, check)
        StatusCheckedListBox.SetItemChecked(UnknownStatusIndex, check)

        m_ControlsInitialized = True

        FillRelationshipListWithRelationshipObjects()
    End Sub

    Private Sub CheckAllMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles CheckAllMenuItem.Click
        Dim contextMenuItem As ToolStripMenuItem = TryCast(sender, ToolStripMenuItem)
        Dim contextMenuStrip As ContextMenuStrip = TryCast(contextMenuItem.Owner, ContextMenuStrip)

        If Not contextMenuStrip Is Nothing Then
            Select Case contextMenuStrip.SourceControl.Name
                Case "RelationshipTypeListBox"
                    ConstraintTypeCheckAll(True)
                Case "StatusCheckedListBox"
                    StatusCheckAll(True)
            End Select
        End If
    End Sub

    Private Sub UncheckAllMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles UncheckAllMenuItem.Click
        Dim contextMenuItem As ToolStripMenuItem = TryCast(sender, ToolStripMenuItem)
        Dim contextMenuStrip As ContextMenuStrip = TryCast(contextMenuItem.Owner, ContextMenuStrip)

        If Not contextMenuStrip Is Nothing Then
            Select Case contextMenuStrip.SourceControl.Name
                Case "RelationshipTypeListBox"
                    ConstraintTypeCheckAll(False)
                Case "StatusCheckedListBox"
                    StatusCheckAll(False)
            End Select
        End If
    End Sub

    Private Sub Finish_Click(sender As System.Object, e As System.EventArgs) Handles Finish.Click
        Close()
    End Sub

#End Region

#Region "Relationships"

    Private Sub AddPath(ByVal Relationship As Object)
        If m_ShowPath = True Then
            AddRelationshipItem(Relationship, GenerateBinaryRelationshipString(Relationship, "Path"), GenerateBinaryRelationshipTooltipString(Relationship))
        End If
    End Sub

    Private Sub AddGear(ByVal Relationship As Object)
        If m_ShowGear = True Then
            AddRelationshipItem(Relationship, GenerateBinaryRelationshipString(Relationship, "Gear"), GenerateBinaryRelationshipTooltipString(Relationship))
        End If
    End Sub

    Private Sub AddCamFollower(ByVal Relationship As Object)
        If m_ShowCam = True Then
            AddRelationshipItem(Relationship, GenerateBinaryRelationshipString(Relationship, "Cam"), GenerateBinaryRelationshipTooltipString(Relationship))
        End If
    End Sub

    Private Sub AddCenterPlane(ByVal Relationship As Object)
        If m_ShowCenterPlane = True Then
            AddRelationshipItem(Relationship, "Center-Plane", "")
        End If
    End Sub

    Private Sub AddRigidSet(ByVal Relationship As Object)
        If m_ShowRigidSet = True Then
            AddRelationshipItem(Relationship, "Rigid Set", GenerateRigidSetTooltipString(Relationship))
        End If
    End Sub

    Private Sub AddAngular(ByVal Relationship As Object)
        If m_ShowAngle = True Then
            AddRelationshipItem(Relationship, GenerateBinaryRelationshipString(Relationship, "Angle"), GenerateBinaryRelationshipTooltipString(Relationship))
        End If
    End Sub

    Private Sub AddTangent(ByVal Relationship As Object)
        If m_ShowTangent = True Then
            AddRelationshipItem(Relationship, GenerateBinaryRelationshipString(Relationship, "Tangent"), GenerateBinaryRelationshipTooltipString(Relationship))
        End If
    End Sub

    Private Sub AddConnect(ByVal Relationship As Object)
        If m_ShowConnect = True Then
            AddRelationshipItem(Relationship, GenerateBinaryRelationshipString(Relationship, "Connect"), GenerateBinaryRelationshipTooltipString(Relationship))
        End If
    End Sub

    Private Sub AddAxial(ByVal Relationship As Object)
        If m_ShowAxial = True Then
            AddRelationshipItem(Relationship, GenerateBinaryRelationshipString(Relationship, "Axial"), GenerateBinaryRelationshipTooltipString(Relationship))
        End If
    End Sub

    Private Sub AddPlanar(ByVal Relationship As Object)
        Dim ItemText As String
        Dim AddRelationship As Boolean = False

        If Relationship.NormalsAligned = False Then
            AddRelationship = m_ShowMate
            ItemText = "Mate"
        Else
            AddRelationship = m_ShowPlanarAlign
            ItemText = "Planar Align"
        End If

        If AddRelationship = True Then
            AddRelationshipItem(Relationship, GenerateBinaryRelationshipString(Relationship, ItemText), GenerateBinaryRelationshipTooltipString(Relationship))
        End If
    End Sub

    Private Sub AddGround(ByVal Relationship As Object)
        If m_ShowGround = True Then
            Dim ItemText As String

            ItemText = "Ground" + " ( " + Relationship.Occurrence.Name + " )"

            AddRelationshipItem(Relationship, ItemText, Relationship.Occurrence.Name)
        End If
    End Sub

    Private Sub AddRelationshipItem(ByVal Relationship As Object, RelationText As String, TooltipText As String)
        If Not Relationship Is Nothing Then
            Dim TextColor As Color = Color.Black
            Dim RelationshipItem As ListViewItem

            m_RelationshipObjects.Add(Relationship)

            If Relationship.Suppress = True Then
                TextColor = Color.DarkGray
            End If

            RelationshipItem = RelationshipList.Items.Add(RelationText)
            RelationshipItem.ForeColor = TextColor

            If m_ShowDetailedTooltips Then
                RelationshipItem.ToolTipText = TooltipText
            Else
                RelationshipItem.ToolTipText = "Right-click to display a context menu containing relationship maintenance commands."
            End If
        End If
    End Sub

    Private Sub AddRelationship(ByVal Relationship As Object)
        Select Case Relationship.Type
            Case SolidEdgeFramework.ObjectType.igPlanarRelation3d
                AddPlanar(Relationship)
            Case SolidEdgeFramework.ObjectType.igGroundRelation3d
                AddGround(Relationship)
            Case SolidEdgeFramework.ObjectType.igAxialRelation3d
                AddAxial(Relationship)
            Case SolidEdgeFramework.ObjectType.igPointRelation3d
                AddConnect(Relationship)
            Case SolidEdgeFramework.ObjectType.igTangentRelation3d
                AddTangent(Relationship)
            Case SolidEdgeFramework.ObjectType.igAngularRelation3d
                AddAngular(Relationship)
            Case SolidEdgeFramework.ObjectType.igRigidSetRelation3d
                AddRigidSet(Relationship)
            Case SolidEdgeFramework.ObjectType.igCenterPlaneRelation3d
                AddCenterPlane(Relationship)
            Case SolidEdgeFramework.ObjectType.igCamFollowerRelation3d
                AddCamFollower(Relationship)
            Case SolidEdgeFramework.ObjectType.igGearRelation3d
                AddGear(Relationship)
            Case SolidEdgeFramework.ObjectType.igPathRelation3d
                AddPath(Relationship)
        End Select
    End Sub

    Private Sub FillRelationshipListWithRelationshipObjects()
        Dim objRelation As Object

        RelationshipList.Items.Clear()

        m_RelationshipObjects.Clear()

        Cursor = Cursors.WaitCursor

        SetMemberData()

        If IsReadyToProcessRelationships() AndAlso AtLeastOneConstraintTypeSelected() = True AndAlso AtLeastOneConstraintStatusSelected() = True Then
            m_HighlightSet.RemoveAll()
            m_HighlightSet.Draw()

            If m_ControlsInitialized = True Then
                RelationshipList.BeginUpdate()
                m_SolidEdgeApplication.DelayCompute = True

                For Each objRelation In m_Relations3d
                    Select Case objRelation.DetailedStatus
                        Case SolidEdgeConstants.Relation3dStatusConstants.igRelation3dStatusSolved
                            If m_ShowSolved = True Then
                                AddRelationship(objRelation)
                            End If
                        Case SolidEdgeConstants.Relation3dStatusConstants.igRelation3dStatusUnsolved
                            If m_ShowUnsolved = True Then
                                AddRelationship(objRelation)
                            End If
                        Case SolidEdgeConstants.Relation3dDetailedStatusConstants.igRelation3dDetailedStatusSuppressed
                            If m_ShowSuppressed = True Then
                                AddRelationship(objRelation)
                            End If
                        Case SolidEdgeConstants.Relation3dDetailedStatusConstants.igRelation3dDetailedStatusUnsatisfied
                            If m_ShowUnsatisfied = True Then
                                AddRelationship(objRelation)
                            End If
                        Case SolidEdgeConstants.Relation3dDetailedStatusConstants.igRelation3dDetailedStatusMissingGeometry
                            If m_ShowMissingGeometry = True Then
                                AddRelationship(objRelation)
                            End If
                        Case SolidEdgeConstants.Relation3dDetailedStatusConstants.igRelation3dDetailedStatusBetweenSetMembers
                            If m_ShowBetweenSetMembers = True Then
                                AddRelationship(objRelation)
                            End If
                        Case SolidEdgeConstants.Relation3dDetailedStatusConstants.igRelation3dDetailedStatusBetweenFixed
                            If m_ShowBetweenFixed = True Then
                                AddRelationship(objRelation)
                            End If
                        Case SolidEdgeConstants.Relation3dDetailedStatusConstants.igRelation3dDetailedStatusUnknown
                            If m_ShowUnknown = True Then
                                AddRelationship(objRelation)
                            End If
                    End Select
                Next

                m_SolidEdgeApplication.DelayCompute = False
            End If
        End If

        RelationshipList.EndUpdate()

        If m_RelationshipObjects.Count = 0 Then
            FoundRelationshipCountLabel.Text = "There are no relationships with the selected status."
        Else
            FoundRelationshipCountLabel.Text = "Relationships with the selected status: " + m_RelationshipObjects.Count.ToString
        End If

        FoundRelationshipCountLabel.Left = ClientSize.Width \ 2 - FoundRelationshipCountLabel.Width \ 2

        Cursor = Cursors.Default
    End Sub

#End Region

#Region "ComponentSelection"

    ' Adds the object to the select set with exception handling.
    Private Sub AddToSelectSet(ByVal ObjectToAdd As Object)
        If Not Relationship Is Nothing AndAlso Not m_SelectSet Is Nothing Then
            Try
                m_SelectSet.Add(ObjectToAdd)
            Catch ex As Exception
            End Try
        End If
    End Sub

    ' Adds the binary relationship's components to the select set (relationship between two objects).
    Private Sub SelectBinaryComponents(ByVal Relationship As Object)
        If Not Relationship Is Nothing AndAlso IsReadyToProcessRelationships() AndAlso Not m_SelectSet Is Nothing Then
            Dim IsTopologyReference As Boolean = False
            Dim Occurrence1 As SolidEdgeAssembly.Occurrence = Nothing
            Dim Occurrence2 As SolidEdgeAssembly.Occurrence = Nothing

            Try
                Occurrence1 = DirectCast(Relationship.Occurrence1, SolidEdgeAssembly.Occurrence)
            Catch ex As Exception
                Occurrence1 = Nothing
            End Try

            Try
                Occurrence2 = DirectCast(Relationship.Occurrence2, SolidEdgeAssembly.Occurrence)
            Catch ex As Exception
                Occurrence2 = Nothing
            End Try

            ' Add the first occurrence to the select set if it isn't Nothing (it could be nothing if the relationship is to an assembly
            ' reference plane).
            If Not Occurrence1 Is Nothing Then
                AddToSelectSet(Occurrence1)
            End If

            ' Add the second occurrence to the select set if it isn't Nothing (it could be nothing if the relationship is to an assembly
            ' reference plane).
            If Not Occurrence2 Is Nothing Then
                AddToSelectSet(Occurrence2)
            End If
        End If
    End Sub

    ' Adds the assembly rigid set relationship's components to the select set
    Private Sub SelectRigidSetComponents(ByVal Relationship As Object)
        If Not Relationship Is Nothing AndAlso IsReadyToProcessRelationships() AndAlso Not m_SelectSet Is Nothing Then
            Dim RigidSet As SolidEdgeAssembly.RigidSetRelation3d = Nothing

            Try
                RigidSet = DirectCast(Relationship, SolidEdgeAssembly.RigidSetRelation3d)
            Catch ex As Exception
                RigidSet = Nothing
            End Try

            ' Add each of the rigid set's components to the select set.
            If Not RigidSet Is Nothing Then
                For Each occ In RigidSet.Occurrences
                    If Not occ Is Nothing Then
                        AddToSelectSet(occ)
                    End If
                Next
            End If
        End If
    End Sub

    ' Adds the ground relationship's component to the select set.
    Private Sub SelectGroundComponent(ByVal Relationship As Object)
        If Not Relationship Is Nothing AndAlso IsReadyToProcessRelationships() AndAlso Not m_SelectSet Is Nothing Then
            If Not Relationship.Occurrence Is Nothing Then
                AddToSelectSet(Relationship.Occurrence)
            End If
        End If
    End Sub

    ' Adds the input relationship's components to the select set if they are occurrences.
    Private Sub SelectRelationshipComponents(ByVal Relationship As Object)
        If Not Relationship Is Nothing AndAlso Not m_SelectSet Is Nothing Then
            ' Now, call the appropriate routine to add the components to the select set
            ' based on relationship type (since each can have a varying number of components and methods of getting them).
            Select Case Relationship.Type
                Case SolidEdgeFramework.ObjectType.igPlanarRelation3d
                    SelectBinaryComponents(Relationship)
                Case SolidEdgeFramework.ObjectType.igAxialRelation3d
                    SelectBinaryComponents(Relationship)
                Case SolidEdgeFramework.ObjectType.igPointRelation3d
                    SelectBinaryComponents(Relationship)
                Case SolidEdgeFramework.ObjectType.igTangentRelation3d
                    SelectBinaryComponents(Relationship)
                Case SolidEdgeFramework.ObjectType.igAngularRelation3d
                    SelectBinaryComponents(Relationship)
                Case SolidEdgeFramework.ObjectType.igGroundRelation3d
                    SelectGroundComponent(Relationship)
                Case SolidEdgeFramework.ObjectType.igRigidSetRelation3d
                    SelectRigidSetComponents(Relationship)
                Case SolidEdgeFramework.ObjectType.igCenterPlaneRelation3d
                Case SolidEdgeFramework.ObjectType.igCamFollowerRelation3d
                Case SolidEdgeFramework.ObjectType.igGearRelation3d
                Case SolidEdgeFramework.ObjectType.igPathRelation3d
            End Select
        End If
    End Sub

#End Region

#Region "Highlight"

    ' Highlights the object with exception handling.
    Private Sub HighlightObject(ByVal ObjectToHighlight As Object)
        If Not ObjectToHighlight Is Nothing AndAlso Not m_HighlightSet Is Nothing Then
            Try
                m_HighlightSet.AddItem(ObjectToHighlight)
            Catch ex As Exception
            End Try
        End If
    End Sub

    ' Highlights the two elements for a binary relationship.
    Private Sub HighlightBinary(ByVal Relationship As Object)
        If Not Relationship Is Nothing AndAlso Not m_HighlightSet Is Nothing Then
            Dim IsTopologyReference As Boolean = False
            Dim Element1 As Object = Nothing
            Dim Element2 As Object = Nothing

            Try
                Element1 = DirectCast(Relationship.GetElement1(IsTopologyReference), Object)
            Catch ex As Exception
                Element1 = Nothing
            End Try

            Try
                Element2 = DirectCast(Relationship.GetElement2(IsTopologyReference), Object)
            Catch ex As Exception
                Element2 = Nothing
            End Try

            ' Add the first element to the highlight set if it isn't Nothing.
            If Not Element1 Is Nothing Then
                HighlightObject(Element1)
            End If

            ' Add the second element to the highlight set if it isn't Nothing.
            If Not Element2 Is Nothing Then
                HighlightObject(Element2)
            End If
        End If
    End Sub

    ' Highlights each occurrence for an assembly rigid set relationship.
    Private Sub HighlightRigidSet(ByVal Relationship As Object)
        If Not Relationship Is Nothing AndAlso Not m_HighlightSet Is Nothing Then
            Dim RigidSet As SolidEdgeAssembly.RigidSetRelation3d = Nothing

            Try
                RigidSet = DirectCast(Relationship, SolidEdgeAssembly.RigidSetRelation3d)
            Catch ex As Exception
                RigidSet = Nothing
            End Try

            ' Add each occurrence in the rigid set to the highlight set.
            If Not RigidSet Is Nothing Then
                For Each occ In RigidSet.Occurrences
                    If Not occ Is Nothing Then
                        HighlightObject(occ)
                    End If
                Next
            End If
        End If
    End Sub

    ' Highlights each occurrence for a cam relationship.
    Private Sub HighlightCam(ByVal Relationship As Object)
        If Not Relationship Is Nothing AndAlso Not m_HighlightSet Is Nothing Then
            Dim Cam As SolidEdgeAssembly.CamFollowerRelation3d = Nothing

            Try
                Cam = DirectCast(Relationship, SolidEdgeAssembly.CamFollowerRelation3d)
            Catch ex As Exception
                Cam = Nothing
            End Try

            If Not Cam Is Nothing Then
                Dim Occurrence1 As Object = Nothing
                Dim Occurrence2 As Object = Nothing

                Try
                    Occurrence1 = DirectCast(Cam.Occurrence1, Object)
                Catch ex As Exception
                    Occurrence1 = Nothing
                End Try

                Try
                    Occurrence2 = DirectCast(Cam.Occurrence2, Object)
                Catch ex As Exception
                    Occurrence2 = Nothing
                End Try

                ' Add the first occurrence to the highlight set if it isn't Nothing.
                If Not Occurrence1 Is Nothing Then
                    HighlightObject(Occurrence1)
                End If

                ' Add the second occurrence to the highlight set if it isn't Nothing.
                If Not Occurrence2 Is Nothing Then
                    HighlightObject(Occurrence2)
                End If
            End If
        End If
    End Sub

    ' Highlights each occurrence for a path relationship.
    Private Sub HighlightPath(ByVal Relationship As Object)
        If Not Relationship Is Nothing AndAlso Not m_HighlightSet Is Nothing Then
            Dim PathRelationship As SolidEdgeAssembly.PathRelation3d = Nothing

            Try
                PathRelationship = DirectCast(Relationship, SolidEdgeAssembly.PathRelation3d)
            Catch ex As Exception
                PathRelationship = Nothing
            End Try

            If Not PathRelationship Is Nothing Then
                Dim Occurrence1 As Object = Nothing
                Dim Occurrence2 As Object = Nothing

                Try
                    Occurrence1 = DirectCast(PathRelationship.Occurrence1, Object)
                Catch ex As Exception
                    Occurrence1 = Nothing
                End Try

                Try
                    Occurrence2 = DirectCast(PathRelationship.Occurrence2, Object)
                Catch ex As Exception
                    Occurrence2 = Nothing
                End Try

                ' Add the first occurrence to the highlight set if it isn't Nothing.
                If Not Occurrence1 Is Nothing Then
                    HighlightObject(Occurrence1)
                End If

                ' Add the second occurrence to the highlight set if it isn't Nothing.
                If Not Occurrence2 Is Nothing Then
                    HighlightObject(Occurrence2)
                End If
            End If
        End If
    End Sub

    ' Highlights the ground relationship's occurrence.
    Private Sub HighlightGround(ByVal Relationship As Object)
        If Not Relationship Is Nothing AndAlso Not m_HighlightSet Is Nothing Then
            If Not Relationship.Occurrence Is Nothing Then
                HighlightObject(Relationship.Occurrence)
            End If
        End If
    End Sub

    ' Highlights the relationship's elements.
    Private Sub HighlightRelationshipData(ByVal Relationship As Object)
        If Not Relationship Is Nothing AndAlso Not m_HighlightSet Is Nothing Then
            ' Call the appropriate routine based on relationship type because the
            ' relationships can be between different types of items.
            Select Case Relationship.Type
                Case SolidEdgeFramework.ObjectType.igPlanarRelation3d
                    HighlightBinary(Relationship)
                Case SolidEdgeFramework.ObjectType.igAxialRelation3d
                    HighlightBinary(Relationship)
                Case SolidEdgeFramework.ObjectType.igPointRelation3d
                    HighlightBinary(Relationship)
                Case SolidEdgeFramework.ObjectType.igTangentRelation3d
                    HighlightBinary(Relationship)
                Case SolidEdgeFramework.ObjectType.igAngularRelation3d
                    HighlightBinary(Relationship)
                Case SolidEdgeFramework.ObjectType.igGearRelation3d
                    HighlightBinary(Relationship)
                Case SolidEdgeFramework.ObjectType.igGroundRelation3d
                    HighlightGround(Relationship)
                Case SolidEdgeFramework.ObjectType.igRigidSetRelation3d
                    HighlightRigidSet(Relationship)
                Case SolidEdgeFramework.ObjectType.igCamFollowerRelation3d
                    HighlightCam(Relationship)
                Case SolidEdgeFramework.ObjectType.igPathRelation3d
                    HighlightPath(Relationship)
                Case SolidEdgeFramework.ObjectType.igCenterPlaneRelation3d
            End Select
        End If
    End Sub

#End Region

End Class
