Imports XCCLibrary
Imports SldWorks

Public Class Individual_3D
    Private Shared gratingParameters As DataRow
    Private Shared designName As String
    Public Shared partDT As New DataTable
    Public Shared Sub BuildGrating()
        Dim exportTable As DataTable
        exportTable = User_Input.Create_ExportTable()

        XCCBaseClass.newDesign()
        ExternalClass.PopulateTamplateXMLGroup()

        Dim inst_ As Integer
        Dim parentID As Integer = 0
        gratingParameters = exportTable.Rows(0)

        inst_ = ExternalClass.instantiate_parts(parentID, gratingParameters("TYPE"), "")
        ExternalClass.modify_parameter_value("DP_GRATING_WIDTH", inst_, gratingParameters("WIDTH"))
        ExternalClass.modify_parameter_value("DP_GRATING_LENGTH", inst_, gratingParameters("LENGTH"))
        ExternalClass.modify_parameter_value("DP_LOADBAR_THICKNESS", inst_, gratingParameters("LOADBAR_THICKNESS"))
        ExternalClass.modify_parameter_value("DP_LOADBAR_HEIGHT", inst_, gratingParameters("LOADBAR_HEIGHT"))
        ExternalClass.modify_parameter_value("DP_LOADBAR_SPACING", inst_, gratingParameters("LOADBAR_SPACING"))
        ExternalClass.modify_parameter_value("DP_CROSSBAR_SPACING", inst_, gratingParameters("CROSSBAR_SPACING"))

        If gratingParameters("TYPE") = "pressure_welded" Or gratingParameters("TYPE") = "pressure_welded_serrated" Then
            ExternalClass.modify_parameter_value("DP_CROSSBAR_DIAMETER", inst_, gratingParameters("CROSSBAR_DIAMETER"))
        Else
            ExternalClass.modify_parameter_value("DP_CROSSBAR_THICKNESS", inst_, gratingParameters("CROSSBAR_THICKNESS"))
            ExternalClass.modify_parameter_value("DP_CROSSBAR_HEIGHT", inst_, gratingParameters("CROSSBAR_HEIGHT"))
        End If

        ExternalClass.modify_parameter_value("DP_OFFSET_X", inst_, 0)
        ExternalClass.modify_parameter_value("DP_OFFSET_Y", inst_, 0)

        parentID = inst_
        For Each recessDR As DataRow In Data.recessData.Rows
            Inst_Recesses(parentID, gratingParameters, recessDR)
        Next

        Individual_Frame_3D.Build_Frame(gratingParameters, parentID)

        importClass.copyGroupsByDataSet(ExternalClass.groupds_new)
        Dim grNr = groupClass.NewGroupID
        Dim designTable = designModel.selectDesign("*")
        designName = designTable.rows(0)("designName")
        groupClass.InstantiateGroup(designName, grNr, "START")

        Recess_Indent()
        Save_Assembly()

        For Each DR As DataRow In Individual_Frame_3D.frameDT.Rows
            If DR("TYPE") = "SIDE" Then
                Individual_Frame_3D.Generate_End_Frame_Pieces()
                Individual_Frame_Drawing.Create_Assemblies()
                Individual_Frame_Drawing.Generate_Drawings()
                Exit For
            End If
        Next


    End Sub

    Private Shared Sub Save_Assembly()
        Dim swApp As SldWorks.SldWorks
        swApp = CType(System.Runtime.InteropServices.Marshal.GetActiveObject("SldWorks.Application"), SldWorks.SldWorks)

        Dim status As Integer

        Dim sourcePath, destPath As String
        Dim childrenSourcePaths As New List(Of String)
        Dim childrenDestPaths As New List(Of String)

        sourcePath = Settings.filesFolder & "\Files\CADStart\" & designName & ".SLDASM"
        destPath = Settings.folderPaths("object_" & Data.objectNum & "_models3D_gratings_sw") & "\GRATING_ASSEMBLY.SLDASM"

        childrenSourcePaths.Add(Settings.HLCtFolder & "\HLCt\Parts\START.SLDPRT")
        childrenDestPaths.Add(Settings.folderPaths("object_" & Data.objectNum & "_models3D_gratings_sw_support") & "\MASTER.SLDPRT")

        Dim instanceCounter As New Dictionary(Of String, Integer)
        For i = 0 To partDT.Rows.Count - 1
            childrenSourcePaths.Add(Settings.filesFolder & "\Files\CADStart\" & partDT.Rows(i)("partName") & ".SLDPRT")

            Dim partName As String = partDT.Rows(i)("partName")
            Dim partNameArray As String() = partName.Split("_")

            Dim newName As String = ""
            For j = 0 To partNameArray.Length - 4
                newName += partNameArray(j) & "_"
            Next

            Try
                instanceCounter(newName.Substring(0, newName.Length - 1)) += 1
            Catch ex As Exception
                instanceCounter.Add(newName.Substring(0, newName.Length - 1), 1)
            End Try

            If partNameArray(0) = "FRAME" Then
                childrenDestPaths.Add(Settings.folderPaths("object_" & Data.objectNum & "_models3D_frames_sw") & "\" & newName &
                                  instanceCounter(newName.Substring(0, newName.Length - 1)) & ".SLDPRT")
            Else
                childrenDestPaths.Add(Settings.folderPaths("object_" & Data.objectNum & "_models3D_gratings_sw") & "\" & newName &
                                  instanceCounter(newName.Substring(0, newName.Length - 1)) & ".SLDPRT")
            End If
        Next

        swApp.CloseAllDocuments(True)
        status = swApp.CopyDocument(sourcePath, destPath, childrenSourcePaths.ToArray(), childrenDestPaths.ToArray(), 2)
    End Sub

    Private Shared Sub Inst_Recesses(parentID As Integer, gratingParameters As DataRow, recessDR As DataRow)
        Dim inst_ As Integer

        If recessDR("RECESS TYPE") = "SQUARE" Then
            Dim squareL As Integer = recessDR("LENGTH") + gratingParameters("LOADBAR_THICKNESS")
            Dim squareW As Integer = recessDR("WIDTH") + gratingParameters("LOADBAR_THICKNESS")

            inst_ = ExternalClass.instantiate_parts(parentID, "recess_rectangle", "")

            ExternalClass.modify_parameter_value("DP_LENGTH", inst_, squareL + gratingParameters("LOADBAR_THICKNESS"))
            ExternalClass.modify_parameter_value("DP_WIDTH", inst_, squareW)
            ExternalClass.modify_parameter_value("DP_EDGEBAR_HEIGHT", inst_, gratingParameters("LOADBAR_HEIGHT"))
            ExternalClass.modify_parameter_value("DP_EDGEBAR_THICKNESS", inst_, gratingParameters("LOADBAR_THICKNESS"))
            ExternalClass.modify_parameter_value("DP_BOX_HEIGHT", inst_, gratingParameters("LOADBAR_HEIGHT"))

            If recessDR("CORNER") = 1 Then
                ExternalClass.modify_parameter_value("DP_OFFSET_W", inst_, gratingParameters("WIDTH") - squareW)
                ExternalClass.modify_parameter_value("DP_OFFSET_L", inst_, 0)

                'Position
                ExternalClass.modify_parameter_value("DP_V_EDGEBAR_POS", inst_, squareL)
                ExternalClass.modify_parameter_value("DP_V_EDGEBAR_BOTTOM", inst_, gratingParameters("LOADBAR_THICKNESS"))
                ExternalClass.modify_parameter_value("DP_H_EDGEBAR_POS", inst_, 0)

            ElseIf recessDR("CORNER") = 2 Then
                ExternalClass.modify_parameter_value("DP_OFFSET_W", inst_, gratingParameters("WIDTH") - squareW)
                ExternalClass.modify_parameter_value("DP_OFFSET_L", inst_, gratingParameters("LENGTH") - squareL - gratingParameters("LOADBAR_THICKNESS"))

                'Position
                ExternalClass.modify_parameter_value("DP_V_EDGEBAR_POS", inst_, 0)
                ExternalClass.modify_parameter_value("DP_V_EDGEBAR_BOTTOM", inst_, gratingParameters("LOADBAR_THICKNESS"))
                ExternalClass.modify_parameter_value("DP_H_EDGEBAR_POS", inst_, 0)

            ElseIf recessDR("CORNER") = 3 Then
                ExternalClass.modify_parameter_value("DP_OFFSET_W", inst_, 0)
                ExternalClass.modify_parameter_value("DP_OFFSET_L", inst_, gratingParameters("LENGTH") - squareL - gratingParameters("LOADBAR_THICKNESS"))

                'Position
                ExternalClass.modify_parameter_value("DP_V_EDGEBAR_POS", inst_, 0)
                ExternalClass.modify_parameter_value("DP_V_EDGEBAR_BOTTOM", inst_, 0)
                ExternalClass.modify_parameter_value("DP_H_EDGEBAR_POS", inst_, squareW - gratingParameters("LOADBAR_THICKNESS"))
            Else
                ExternalClass.modify_parameter_value("DP_OFFSET_W", inst_, 0)
                ExternalClass.modify_parameter_value("DP_OFFSET_L", inst_, 0)

                'Position
                ExternalClass.modify_parameter_value("DP_V_EDGEBAR_POS", inst_, squareL)
                ExternalClass.modify_parameter_value("DP_V_EDGEBAR_BOTTOM", inst_, 0)
                ExternalClass.modify_parameter_value("DP_H_EDGEBAR_POS", inst_, squareW - gratingParameters("LOADBAR_THICKNESS"))
            End If

        ElseIf recessDR("RECESS TYPE") = "ANGLE" Then
            inst_ = ExternalClass.instantiate_parts(parentID, "recess_angle", "")

            ExternalClass.modify_parameter_value("DP_EDGEBAR_HEIGHT", inst_, gratingParameters("LOADBAR_HEIGHT"))
            ExternalClass.modify_parameter_value("DP_EDGEBAR_THICKNESS", inst_, gratingParameters("LOADBAR_THICKNESS"))

            If recessDR("CORNER") = 1 Then
                ExternalClass.modify_parameter_value("DP_LENGTH", inst_, recessDR("WIDTH"))
                ExternalClass.modify_parameter_value("DP_WIDTH", inst_, recessDR("LENGTH"))
                ExternalClass.modify_parameter_value("DP_OFFSET_W", inst_, gratingParameters("WIDTH"))
                ExternalClass.modify_parameter_value("DP_OFFSET_L", inst_, 0)
                ExternalClass.modify_parameter_value("DP_ROTATION", inst_, 90)

            ElseIf recessDR("CORNER") = 2 Then
                ExternalClass.modify_parameter_value("DP_LENGTH", inst_, recessDR("LENGTH"))
                ExternalClass.modify_parameter_value("DP_WIDTH", inst_, recessDR("WIDTH"))
                ExternalClass.modify_parameter_value("DP_OFFSET_W", inst_, gratingParameters("WIDTH"))
                ExternalClass.modify_parameter_value("DP_OFFSET_L", inst_, gratingParameters("LENGTH"))
                ExternalClass.modify_parameter_value("DP_ROTATION", inst_, 180)

            ElseIf recessDR("CORNER") = 3 Then
                ExternalClass.modify_parameter_value("DP_LENGTH", inst_, recessDR("WIDTH"))
                ExternalClass.modify_parameter_value("DP_WIDTH", inst_, recessDR("LENGTH"))
                ExternalClass.modify_parameter_value("DP_OFFSET_W", inst_, 0)
                ExternalClass.modify_parameter_value("DP_OFFSET_L", inst_, gratingParameters("LENGTH"))
                ExternalClass.modify_parameter_value("DP_ROTATION", inst_, 270)

            Else
                ExternalClass.modify_parameter_value("DP_LENGTH", inst_, recessDR("LENGTH"))
                ExternalClass.modify_parameter_value("DP_WIDTH", inst_, recessDR("WIDTH"))
                ExternalClass.modify_parameter_value("DP_OFFSET_W", inst_, 0)
                ExternalClass.modify_parameter_value("DP_OFFSET_L", inst_, 0)
                ExternalClass.modify_parameter_value("DP_ROTATION", inst_, 0)

            End If

        ElseIf recessDR("RECESS TYPE") = "SIDE SQUARE" Then
            inst_ = ExternalClass.instantiate_parts(parentID, "recess_side_square", "")

            ExternalClass.modify_parameter_value("DP_EDGEBAR_HEIGHT", inst_, gratingParameters("LOADBAR_HEIGHT"))
            ExternalClass.modify_parameter_value("DP_EDGEBAR_THICKNESS", inst_, gratingParameters("LOADBAR_THICKNESS"))

            If recessDR("SIDE") = 1 Then
                ExternalClass.modify_parameter_value("DP_LENGTH", inst_, recessDR("WIDTH"))
                ExternalClass.modify_parameter_value("DP_WIDTH", inst_, recessDR("LENGTH"))
                ExternalClass.modify_parameter_value("DP_OFFSET_W", inst_, gratingParameters("WIDTH"))
                ExternalClass.modify_parameter_value("DP_OFFSET_L", inst_, recessDR("OFFSET"))
                ExternalClass.modify_parameter_value("DP_ROTATION", inst_, 90)

            ElseIf recessDR("SIDE") = 2 Then
                ExternalClass.modify_parameter_value("DP_LENGTH", inst_, recessDR("LENGTH"))
                ExternalClass.modify_parameter_value("DP_WIDTH", inst_, recessDR("WIDTH"))
                ExternalClass.modify_parameter_value("DP_OFFSET_W", inst_, gratingParameters("WIDTH") - recessDR("OFFSET"))
                ExternalClass.modify_parameter_value("DP_OFFSET_L", inst_, gratingParameters("LENGTH"))
                ExternalClass.modify_parameter_value("DP_ROTATION", inst_, 180)

            ElseIf recessDR("SIDE") = 3 Then
                ExternalClass.modify_parameter_value("DP_LENGTH", inst_, recessDR("WIDTH"))
                ExternalClass.modify_parameter_value("DP_WIDTH", inst_, recessDR("LENGTH"))
                ExternalClass.modify_parameter_value("DP_OFFSET_W", inst_, 0)
                ExternalClass.modify_parameter_value("DP_OFFSET_L", inst_, gratingParameters("LENGTH") - recessDR("OFFSET"))
                ExternalClass.modify_parameter_value("DP_ROTATION", inst_, 270)

            Else
                ExternalClass.modify_parameter_value("DP_LENGTH", inst_, recessDR("LENGTH"))
                ExternalClass.modify_parameter_value("DP_WIDTH", inst_, recessDR("WIDTH"))
                ExternalClass.modify_parameter_value("DP_OFFSET_W", inst_, recessDR("OFFSET"))
                ExternalClass.modify_parameter_value("DP_OFFSET_L", inst_, 0)
                ExternalClass.modify_parameter_value("DP_ROTATION", inst_, 0)

            End If

        ElseIf recessDR("RECESS TYPE") = "MIDDLE SQUARE" Then
            inst_ = ExternalClass.instantiate_parts(parentID, "recess_middle_square", "")

            ExternalClass.modify_parameter_value("DP_LENGTH", inst_, recessDR("LENGTH"))
            ExternalClass.modify_parameter_value("DP_WIDTH", inst_, recessDR("WIDTH"))
            ExternalClass.modify_parameter_value("DP_EDGEBAR_HEIGHT", inst_, gratingParameters("LOADBAR_HEIGHT"))
            ExternalClass.modify_parameter_value("DP_EDGEBAR_THICKNESS", inst_, gratingParameters("LOADBAR_THICKNESS"))
            ExternalClass.modify_parameter_value("DP_OFFSET_W", inst_, recessDR("OFFSET Y"))
            ExternalClass.modify_parameter_value("DP_OFFSET_L", inst_, recessDR("OFFSET X"))
        End If


    End Sub

    Private Shared Sub Recess_Indent()
        Dim swApp As SldWorks.SldWorks
        swApp = CType(System.Runtime.InteropServices.Marshal.GetActiveObject("SldWorks.Application"), SldWorks.SldWorks)

        Dim boolstatus As Boolean
        Dim AssemblyExtension As SldWorks.ModelDocExtension

        Dim Assembly = swApp.ActiveDoc
        Dim SelMgr = Assembly.SelectionManager()
        AssemblyExtension = Assembly.Extension
        Dim sldata = SelMgr.CreateSelectData

        Dim swErrors As Integer
        Dim swWarnings As Integer
        Dim components = Assembly.GetComponents(True)

        partDT = partModel.selectPart("*")

        Assembly.ClearSelection2(True)

        ' Grating part
        Dim gratingPartName As String = partDT.Rows(0)("partName")
        boolstatus = AssemblyExtension.SelectByID2(gratingPartName & "-1@" & designName, "COMPONENT", 0, 0, 0, False, 0, Nothing, 0)
        Dim gratingPart = SelMgr.GetSelectedObject6(1, -1)

        Assembly.EditPart

        Dim modelDoc As IModelDoc2
        modelDoc = Assembly
        boolstatus = AssemblyExtension.SelectByID2("HorizontalSplitBody@" & gratingPartName & "-1@" & designName, "BODYFEATURE", 0, 0, 0, False, 0, Nothing, 0)
        modelDoc.EditSuppress2()
        boolstatus = AssemblyExtension.SelectByID2("VerticalSplitBody@" & gratingPartName & "-1@" & designName, "BODYFEATURE", 0, 0, 0, False, 0, Nothing, 0)
        modelDoc.EditSuppress2()

        Dim indexGrating As Integer
        For i = 0 To components.Length - 1
            If components(i).Name2 = gratingPartName & "-1" Then
                indexGrating = i
                Exit For
            End If
        Next

        Dim gratingComponent As SldWorks.Component2 = components(indexGrating)
        Dim gratingBodies = components(indexGrating).GetBodies2(0)

        Dim recessParts = partDT.Select("parentName = '" & gratingPartName & "'")
        'Dim recessParts As DataTable = New DataTable
        'For Each DR As DataRow In partDT.Rows
        '    Dim partName As String = DR("partName")
        '    If partName.Split("_")(0) = "RECESS" Then
        '        recessParts.Rows.Add(DR)
        '    End If
        'Next



        Dim recessPartName As String
        For i = 0 To recessParts.Count - 1
            Dim partName As String = recessParts(i)("partName")
            If partName.Split("_")(0) = "RECESS" Then
                Assembly.ClearSelection2(True)

                ' Recess part
                recessPartName = partName
                boolstatus = AssemblyExtension.SelectByID2(recessPartName & "-1@" & designName, "COMPONENT", 0, 0, 0, False, 0, Nothing, 0)
                Dim recessPart = SelMgr.GetSelectedObject6(1, -1)

                Dim indexRecess As Integer
                For j = 0 To components.Length - 1
                    If components(j).Name2 = recessPartName & "-1" Then
                        indexRecess = j
                        Exit For
                    End If
                Next

                Dim recessBodies = components(indexRecess).GetBodies2(0)
                Dim recessComponent As SldWorks.Component2 = components(indexRecess)
                Dim bodiesToCut = Check_Interference(gratingComponent, recessComponent)

                For j = 0 To bodiesToCut.Length - 1
                    sldata.Mark = 1

                    Dim bodyName As String = bodiesToCut(j).Name & "@" & gratingPartName & "-1@" & designName
                    boolstatus = AssemblyExtension.SelectByID2(bodyName, "SOLIDBODY", 0, 0, 0, True, 1, Nothing, 0)

                    sldata.Mark = 4

                    Dim indexBody As Integer
                    For k = 0 To recessBodies.Length - 1
                        If recessBodies(k).Name = "Cut-Body" Then
                            indexBody = k
                            Exit For
                        End If
                    Next

                    Dim recessFace = recessBodies(indexBody).GetFirstFace
                    recessFace.Select4(True, sldata)

                    Assembly.FeatureManager.InsertIndent(0.01, 0, False, True, True, False)
                    Assembly.ClearSelection2(True)
                Next
            End If
        Next


        If gratingParameters("TYPE") = "pressure_welded_serrated" Then
            For i = 1 To 5
                boolstatus = AssemblyExtension.SelectByID2("Serrated-Cut" & i & "@" & gratingPartName & "-1@" & designName, "BODYFEATURE", 0, 0, 0, False, 0, Nothing, 0)
                modelDoc.EditUnsuppress2()
            Next

        ElseIf gratingParameters("TYPE") = "type_a_serrated" Then
            For i = 1 To 2
                boolstatus = AssemblyExtension.SelectByID2("Serrated-Cut" & i & "@" & gratingPartName & "-1@" & designName, "BODYFEATURE", 0, 0, 0, False, 0, Nothing, 0)
                modelDoc.EditUnsuppress2()
            Next
        End If


        Assembly.EditAssembly

        components = Assembly.GetComponents(True)
        For i = 0 To UBound(components)
            Dim partDoc = components(i).GetModelDoc2()
            boolstatus = partDoc.Save3(1, swErrors, swWarnings)
        Next
        boolstatus = Assembly.Save3(1, swErrors, swWarnings)
    End Sub

    Private Shared Function Check_Interference(comp1 As SldWorks.Component2, comp2 As SldWorks.Component2) ' Test Albins mocro för interference

        Dim swApp As SldWorks.SldWorks
        Dim swModel As SldWorks.ModelDoc2
        Dim swAssy As SldWorks.AssemblyDoc
        Dim CompArray(1) As SldWorks.Component2
        Dim vCompArray
        Dim vIntCompArray
        Dim vIntFaceArray

        Dim interfering

        swApp = CType(System.Runtime.InteropServices.Marshal.GetActiveObject("SldWorks.Application"), SldWorks.SldWorks)
        swModel = swApp.ActiveDoc
        swAssy = swModel

        CompArray(0) = comp1
        CompArray(1) = comp2

        vCompArray = CompArray
        swAssy.ToolsCheckInterference2(2, (vCompArray), interfering, vIntCompArray, vIntFaceArray)

        Dim Bodies(UBound(vIntFaceArray)) As Object
        Dim BodyNames(UBound(vIntFaceArray)) As String
        Dim CompNames(UBound(vIntFaceArray)) As String

        For i = 0 To UBound(vIntFaceArray)

            Bodies(i) = vIntFaceArray(i).GetBody
            BodyNames(i) = Bodies(i).Name
            CompNames(i) = vIntCompArray(i).Name2

        Next

        Dim gratingName As String = CompNames(0)
        Dim bodiesToCutList As New List(Of Object)

        bodiesToCutList.Add(Bodies(0))
        For i = 1 To CompNames.Length - 1

            If CompNames(i) <> gratingName Then
                Exit For
            ElseIf BodyNames(i) <> BodyNames(i - 1) Then
                bodiesToCutList.Add(Bodies(i))
            End If
        Next

        Dim bodiesToCut() As Object
        bodiesToCut = bodiesToCutList.ToArray()

        Return bodiesToCut
    End Function

End Class
