Imports SldWorks
Public Class Multiple_Drawing

    Public Shared Sub Create_Models_For_Drawing()
        Dim gratingsPointsDS As DataSet = Create_GratingPoints()

        Dim gratingHeight As Decimal = User_Input.gratingHeight / 1000

        Dim swApp As SldWorks.SldWorks
        swApp = CType(System.Runtime.InteropServices.Marshal.GetActiveObject("SldWorks.Application"), SldWorks.SldWorks)
        Dim Model As ModelDoc2
        Dim RootPoint(2) As Decimal
        Dim Normal(2) As Decimal
        swApp.UserControl = True

        Dim swSkMgr As SketchManager
        Dim longstatus As Integer
        Dim boolstatus As Boolean
        Dim swModelDocExtension As ModelDocExtension
        Dim status As Boolean
        Dim swFeatureMgr As FeatureManager
        Dim swFeature As Feature
        Dim iPart As PartDoc

        Dim numOfGratings As Integer = Grating_Fill.numOfVertical * Grating_Fill.numOfHorizontal

        For i = 0 To numOfGratings - 1
            Model = swApp.NewDocument("C:\ProgramData\SOLIDWORKS\SOLIDWORKS 2020\templates\part.prtdot", 0, 0, 0)

            swSkMgr = Model.SketchManager
            swSkMgr.InsertSketch(True)
            boolstatus = Model.Extension.SelectByID2("Front Plane", "PLANE", 0, 0, 0, False, 0, Nothing, 0)
            Model.ClearSelection2(True)

            For Each DR As DataRow In gratingsPointsDS.Tables(i).Rows
                Dim skPoint As SketchPoint
                Dim pX = DR("X")
                Dim pY = DR("Y")
                skPoint = swSkMgr.CreatePoint(pX, pY, 0)
            Next

            For Each DR1 As DataRow In gratingsPointsDS.Tables(i).Rows
                Dim skLine As SketchLine
                Dim rowIndex = gratingsPointsDS.Tables(i).Rows.IndexOf(DR1)
                Dim DR2 As DataRow

                Try
                    DR2 = gratingsPointsDS.Tables(i).Rows(rowIndex + 1)
                Catch ex As Exception
                    DR2 = gratingsPointsDS.Tables(i).Rows(0)
                End Try

                Dim pX1 = DR1("X")
                Dim pY1 = DR1("Y")
                Dim pX2 = DR2("X")
                Dim pY2 = DR2("Y")

                skLine = swSkMgr.CreateLine(pX1, pY1, 0, pX2, pY2, 0)
            Next

            swSkMgr.InsertSketch(True)

            swModelDocExtension = Model.Extension
            status = swModelDocExtension.SelectByID2("Sketch1", "SKETCH", 0, 0, 0, False, 0, Nothing, 0)

            swFeatureMgr = Model.FeatureManager
            swFeature = swFeatureMgr.FeatureExtrusion3(True, False, False, 0, 0, gratingHeight, 0, False, False, False, False, 0, 0, False, False, False, False, True, True, True, 0, 0, False)


            ' MIddle points if needed


            Model.ClearSelection2(True)
            boolstatus = Model.Extension.SelectByID2("Front Plane", "PLANE", 0, 0, 0, False, 0, Nothing, 0)
            Model.FeatureManager.InsertRefPlane(8, gratingHeight, 0, 0, 0, 0)

            iPart = swApp.ActiveDoc
            Dim newName As String
            newName = Settings.folderPaths("object_" & Data.objectNum & "_models3D_gratings_sw_support") & "\simplified_grating_" & i + 1 & ".SLDPRT"


            ' Title head data


            longstatus = iPart.SaveAs3(newName, 0, 0)
            swApp.CloseDoc(newName)
        Next

        ' --- Assembly ---
        Dim assembly As IAssemblyDoc
        Dim AssemblyExtension As SldWorks.ModelDocExtension
        Model = swApp.NewDocument("C:\ProgramData\SolidWorks\SOLIDWORKS 2020\templates\Assembly.asmdot", 0, 0, 0)
        assembly = Model
        AssemblyExtension = assembly.Extension

        Dim compNames(numOfGratings - 1) As String
        Dim coordNames(numOfGratings - 1) As String
        Dim transMatrix As Object = Nothing
        For i = 0 To numOfGratings - 1
            compNames(i) = Settings.folderPaths("object_" & Data.objectNum & "_models3D_gratings_sw_support") & "\simplified_grating_" & i + 1 & ".SLDPRT"
            coordNames(i) = ""
        Next

        Dim assemComps As Object
        assemComps = assembly.AddComponents3((compNames), (transMatrix), (coordNames))

        Model.ViewZoomtofit2()
        longstatus = Model.SaveAs3(Settings.folderPaths("object_" & Data.objectNum & "_models3D_gratings_sw_support") & "\simplified_grating_assembly.SLDASM", 0, 0)

        ' --- Delete Obsolete ---
        Dim listOfObsolete As List(Of Integer)
        listOfObsolete = Multiple_3D.Find_Obsolete()

        For i = 0 To listOfObsolete.Count - 1
            assembly.ClearSelection2(True)
            boolstatus = AssemblyExtension.SelectByID2("simplified_grating_" & listOfObsolete(i) & "-1@simplified_grating_assembly", "COMPONENT", 0, 0, 0, False, 0, Nothing, 0)
            assembly.EditDelete

            My.Computer.FileSystem.DeleteFile(Settings.folderPaths("object_" & Data.objectNum & "_models3D_gratings_sw_support") & "\simplified_grating_" & listOfObsolete(i) & ".SLDPRT")
        Next

        Dim swErrors As Integer
        Dim swWarnings As Integer
        boolstatus = assembly.Save3(1, swErrors, swWarnings)
    End Sub

    Private Shared Function Create_GratingPoints()
        Dim pointsDS As New DataSet

        Dim numOfGratings As Integer = Grating_Fill.numOfVertical * Grating_Fill.numOfHorizontal

        For i = 0 To numOfGratings - 1
            Dim pointsDT As New DataTable
            pointsDT.Columns.Add("NAME", GetType(String))
            pointsDT.Columns.Add("TYPE", GetType(String))
            pointsDT.Columns.Add("X", GetType(Decimal))
            pointsDT.Columns.Add("Y", GetType(Decimal))

            Dim GAPointsDT As New DataTable
            GAPointsDT.Columns.Add("NAME", GetType(String))
            GAPointsDT.Columns.Add("X", GetType(Decimal))
            GAPointsDT.Columns.Add("Y", GetType(Decimal))

            ' --- Determine grossArea points ----
            Dim pX(3) As Decimal
            Dim pY(3) As Decimal

            Dim columnNum As Integer = (i + Grating_Fill.numOfHorizontal) Mod Grating_Fill.numOfHorizontal
            If columnNum <> (Grating_Fill.numOfHorizontal - 1) Then
                ' Columnn: alla utom sista
                pX(0) = Data.grossAreaPoints.Rows(0)("X") + Grating_Fill.minLength * columnNum / 1000
                pX(1) = pX(0) + Grating_Fill.minLength / 1000
                pX(2) = pX(1)
                pX(3) = pX(0)
            Else
                ' Column: sista
                pX(0) = Data.grossAreaPoints.Rows(0)("X") + Grating_Fill.minLength * columnNum / 1000
                pX(1) = Data.grossAreaPoints.Rows(1)("X")
                pX(2) = pX(1)
                pX(3) = pX(0)
            End If

            Dim rowNum As Integer = Math.Floor(i / Grating_Fill.numOfHorizontal)
            If rowNum < Grating_Fill.numOfVertical - 2 Then
                ' Row: alla utom sista och näst sista
                pY(0) = Data.grossAreaPoints.Rows(0)("Y") - Grating_Fill.maxSingleWidth * rowNum / 1000
                pY(1) = pY(0)
                pY(2) = pY(0) - Grating_Fill.maxSingleWidth / 1000
                pY(3) = pY(2)
            ElseIf rowNum < Grating_Fill.numOfVertical - 1 Then
                ' Row: Näst sista
                pY(0) = Data.grossAreaPoints.Rows(0)("Y") - Grating_Fill.maxSingleWidth * rowNum / 1000
                pY(1) = pY(0)
                If Grating_Fill.widthRevNeeded = True Then
                    pY(2) = pY(0) - Grating_Fill.revWidth / 1000
                Else
                    pY(2) = pY(0) - Grating_Fill.maxSingleWidth / 1000
                End If
                pY(3) = pY(2)
            Else
                ' Row: Sista
                If Grating_Fill.widthRevNeeded = True Then
                    pY(0) = Data.grossAreaPoints.Rows(0)("Y") - Grating_Fill.maxSingleWidth * (rowNum - 1) / 1000 - Grating_Fill.revWidth / 1000
                Else
                    pY(0) = Data.grossAreaPoints.Rows(0)("Y") - Grating_Fill.maxSingleWidth * rowNum / 1000
                End If
                pY(1) = pY(0)
                pY(2) = Data.grossAreaPoints.Rows(3)("Y")
                pY(3) = pY(2)
            End If

            For j = 0 To 3
                Dim DR As DataRow = pointsDT.NewRow()
                DR("NAME") = "GA_" & j + 1
                DR("TYPE") = "GA"
                DR("X") = pX(j)
                DR("Y") = pY(j)
                pointsDT.Rows.Add(DR)

                DR = GAPointsDT.NewRow()
                DR("NAME") = "GA_" & j + 1
                DR("X") = pX(j)
                DR("Y") = pY(j)
                GAPointsDT.Rows.Add(DR)
            Next

            ' --- Add recess points ---
            Dim recessPointsDT As New DataTable
            recessPointsDT.Columns.Add("NAME", GetType(String))
            recessPointsDT.Columns.Add("TYPE", GetType(String))
            recessPointsDT.Columns.Add("SIDE", GetType(Integer))
            recessPointsDT.Columns.Add("X", GetType(Decimal))
            recessPointsDT.Columns.Add("Y", GetType(Decimal))

            For j = 1 To 4
                For Each DR As DataRow In Data.gratingPoints.Rows
                    Dim recessDR As DataRow = recessPointsDT.NewRow()
                    recessDR("NAME") = DR("NAME")
                    recessDR("SIDE") = j
                    recessDR("X") = DR("X")
                    recessDR("Y") = DR("Y")
                    Dim pointName As String = DR("NAME")
                    If pointName.Substring(0, 2) = "CA" Then
                        recessDR("TYPE") = "Corner Angle"
                    ElseIf pointName.Substring(0, 2) = "CR" Then
                        recessDR("TYPE") = "Corner Rectangle"
                    ElseIf pointName.Substring(0, 2) = "CS" Then
                        recessDR("TYPE") = "Side Rectangle"
                    Else
                        Continue For
                    End If

                    If j = 1 Then
                        If DR("Y") = pointsDT.Rows(0)("Y") Then
                            If DR("X") >= pointsDT.Rows(0)("X") AndAlso DR("X") <= pointsDT.Rows(1)("X") Then
                                recessPointsDT.Rows.Add(recessDR)
                            End If
                        End If
                    ElseIf j = 2 Then
                        If DR("X") = pointsDT.Rows(1)("X") Then
                            If DR("Y") <= pointsDT.Rows(1)("Y") AndAlso DR("Y") >= pointsDT.Rows(2)("Y") Then
                                recessPointsDT.Rows.Add(recessDR)
                            End If
                        End If
                    ElseIf j = 3 Then
                        If DR("Y") = pointsDT.Rows(2)("Y") Then
                            If DR("X") <= pointsDT.Rows(2)("X") AndAlso DR("X") >= pointsDT.Rows(3)("X") Then
                                recessPointsDT.Rows.Add(recessDR)
                            End If
                        End If
                    Else
                        If DR("X") = pointsDT.Rows(3)("X") Then
                            If DR("Y") >= pointsDT.Rows(3)("Y") AndAlso DR("Y") <= pointsDT.Rows(0)("Y") Then
                                recessPointsDT.Rows.Add(recessDR)
                            End If
                        End If
                    End If
                Next
            Next

            ' --- intersecting recesses ---
            For Each DR As DataRow In Data.recessData.Rows
                If DR("RECESS TYPE") = "ANGLE" Then
                    Dim recessName As String = DR("NAME")
                    Dim recessAlreadyOK As Boolean = False
                    For Each DR2 As DataRow In recessPointsDT.Rows
                        Dim pointName As String = DR2("NAME")
                        If pointName.Substring(0, 3) = recessName Then
                            recessAlreadyOK = True
                            Exit For
                        End If
                    Next
                    If recessAlreadyOK = True Then
                        Continue For
                    End If

                    ' Recess points
                    Dim p0(1) As Decimal
                    Dim p1(1) As Decimal
                    Dim p2(1) As Decimal

                    p0(0) = Data.gratingPoints.Select("NAME = '" & recessName & "_1" & "'")(0)("X")
                    p0(1) = Data.gratingPoints.Select("NAME = '" & recessName & "_1" & "'")(0)("Y")

                    p1(0) = Data.gratingPoints.Select("NAME = '" & recessName & "_2" & "'")(0)("X")
                    p1(1) = Data.gratingPoints.Select("NAME = '" & recessName & "_2" & "'")(0)("Y")

                    If DR("CORNER") = 1 OrElse DR("CORNER") = 3 Then
                        p2(0) = p0(0)
                        p2(1) = p1(1)
                    Else
                        p2(0) = p1(0)
                        p2(1) = p0(1)
                    End If

                    Dim pointsInRecess As New Dictionary(Of String, Boolean)
                    For Each pDR As DataRow In pointsDT.Rows
                        Dim gp(1) As Decimal
                        gp(0) = pDR("X")
                        gp(1) = pDR("Y")

                        pointsInRecess.Add(pDR("NAME"), Calculate_Triangle_Bool(gp, p0, p1, p2))
                    Next

                    Dim numOfPInRec As Integer = 0
                    For Each bool As Boolean In pointsInRecess.Values
                        If bool = True Then
                            numOfPInRec += 1
                        End If
                    Next

                    If numOfPInRec = 0 OrElse numOfPInRec = 4 Then
                        Continue For
                    End If

                    ' - Straight line equation: y = kx + m 
                    Dim k As Decimal = (p1(1) - p0(1)) / (p1(0) - p0(0))
                    Dim m As Decimal = p0(1) - (k * p0(0))

                    Dim npDR As DataRow

                    Dim x1 As Decimal = (GAPointsDT.Rows(0)("Y") - m) / k
                    If x1 > GAPointsDT.Rows(0)("X") AndAlso x1 < GAPointsDT.Rows(1)("X") Then
                        ' lägg till på sida 1
                        npDR = pointsDT.NewRow()
                        npDR("NAME") = recessName & "_1" ' fixa
                        npDR("TYPE") = "Recess CA"
                        npDR("X") = x1
                        npDR("Y") = GAPointsDT.Rows(0)("Y")

                        Dim inIndex As Integer = Get_RowIndex(pointsDT, 1, npDR("X"), npDR("Y"), GAPointsDT)

                        pointsDT.Rows.InsertAt(npDR, inIndex + 1)
                    End If

                    Dim y2 As Decimal = k * GAPointsDT.Rows(1)("X") + m
                    If y2 < GAPointsDT.Rows(1)("Y") AndAlso y2 > GAPointsDT.Rows(2)("Y") Then
                        ' lägg till på sida 2
                        npDR = pointsDT.NewRow()
                        npDR("NAME") = recessName & "_2" ' fixa
                        npDR("TYPE") = "Recess CA"
                        npDR("X") = GAPointsDT.Rows(1)("X")
                        npDR("Y") = y2

                        Dim inIndex As Integer = Get_RowIndex(pointsDT, 2, npDR("X"), npDR("Y"), GAPointsDT)

                        pointsDT.Rows.InsertAt(npDR, inIndex + 1)
                    End If

                    Dim x3 As Decimal = (GAPointsDT.Rows(2)("Y") - m) / k
                    If x3 < GAPointsDT.Rows(2)("X") AndAlso x3 > GAPointsDT.Rows(3)("X") Then
                        ' lägg till på sida 3
                        npDR = pointsDT.NewRow()
                        npDR("NAME") = recessName & "_3" ' fixa
                        npDR("TYPE") = "Recess CA"
                        npDR("X") = x3
                        npDR("Y") = GAPointsDT.Rows(2)("Y")

                        Dim inIndex As Integer = Get_RowIndex(pointsDT, 3, npDR("X"), npDR("Y"), GAPointsDT)

                        pointsDT.Rows.InsertAt(npDR, inIndex + 1)
                    End If

                    Dim y4 As Decimal = k * GAPointsDT.Rows(3)("X") + m
                    If y4 > GAPointsDT.Rows(3)("Y") AndAlso y4 < GAPointsDT.Rows(0)("Y") Then
                        ' lägg till på sida 4
                        npDR = pointsDT.NewRow()
                        npDR("NAME") = recessName & "_4" ' fixa
                        npDR("TYPE") = "Recess CA"
                        npDR("X") = GAPointsDT.Rows(3)("X")
                        npDR("Y") = y4

                        Dim inIndex As Integer = Get_RowIndex(pointsDT, 4, npDR("X"), npDR("Y"), GAPointsDT)

                        pointsDT.Rows.InsertAt(npDR, inIndex + 1)
                    End If

                    For Each key As String In pointsInRecess.Keys
                        If pointsInRecess(key) = True Then
                            Dim removeIndex As Integer = 0
                            For k = 0 To pointsDT.Rows.Count - 1
                                If pointsDT.Rows(k)("NAME") = key Then
                                    removeIndex = k
                                End If
                            Next
                            pointsDT.Rows.RemoveAt(removeIndex)
                        End If
                    Next
                End If
            Next


            ' --- Point on grating side - recesses ---
            For Each DR As DataRow In recessPointsDT.Rows
                If DR("TYPE") = "Corner Angle" Then
                    Dim pointName As String = DR("NAME")
                    If pointName.Split("_")(1) = 1 Then
                        Dim DR3 As DataRow = pointsDT.NewRow()
                        DR3("NAME") = DR("NAME")
                        DR3("TYPE") = "Recess CA"
                        DR3("X") = DR("X")
                        DR3("Y") = DR("Y")

                        Dim index As Integer = Get_RowIndex(pointsDT, DR("SIDE"), DR("X"), DR("Y"), GAPointsDT)
                        pointsDT.Rows.InsertAt(DR3, index + 1)

                        If pointsDT.Rows.Count > index + 2 Then
                            Dim temp As String = pointsDT.Rows(index + 2)("NAME")
                            If temp.Substring(0, 2) = "GA" Then
                                pointsDT.Rows.RemoveAt(index + 2)
                            End If
                        Else
                            Dim temp As String = pointsDT.Rows(0)("NAME")
                            If temp.Substring(0, 2) = "GA" Then
                                pointsDT.Rows.RemoveAt(0)
                            End If
                        End If

                        'Check if remove next point aswell (If angle crosses more than one grating)

                        Dim cornerPoint(1) As Decimal
                        Dim pointNumGA As Integer = DR("SIDE") + 2
                        If pointNumGA > 4 Then
                            pointNumGA -= 4
                        End If

                        cornerPoint(0) = GAPointsDT.Select("NAME = 'GA_" & pointNumGA & "'")(0)("X")
                        cornerPoint(1) = GAPointsDT.Select("NAME = 'GA_" & pointNumGA & "'")(0)("Y")

                        Create_SecondAnglePoint(pointsDT, DR, cornerPoint, GAPointsDT, recessPointsDT, "")
                    Else
                        Dim DR3 As DataRow = pointsDT.NewRow()
                        DR3("NAME") = DR("NAME")
                        DR3("TYPE") = "Recess CA"
                        DR3("X") = DR("X")
                        DR3("Y") = DR("Y")

                        Dim index As Integer = Get_RowIndex(pointsDT, DR("SIDE"), DR("X"), DR("Y"), GAPointsDT)
                        pointsDT.Rows.InsertAt(DR3, index + 1)

                        Dim temp As String = pointsDT.Rows(index)("NAME")
                        If temp.Substring(0, 2) = "GA" Then
                            pointsDT.Rows.RemoveAt(index)
                        End If

                        Dim cornerPoint(1) As Decimal
                        Dim pointNumGA As Integer = DR("SIDE") - 1
                        If pointNumGA < 1 Then
                            pointNumGA += 4
                        End If

                        cornerPoint(0) = GAPointsDT.Select("NAME = 'GA_" & pointNumGA & "'")(0)("X")
                        cornerPoint(1) = GAPointsDT.Select("NAME = 'GA_" & pointNumGA & "'")(0)("Y")

                        Create_SecondAnglePoint(pointsDT, DR, cornerPoint, GAPointsDT, recessPointsDT, "GA_" & pointNumGA)
                    End If
                End If
            Next

            pointsDT.TableName = "Grating " & i & " - C" & columnNum & " R" & rowNum
            pointsDS.Tables.Add(pointsDT)
        Next

        Return pointsDS
    End Function

    Private Shared Function Get_RowIndex(pDT As DataTable, side As Integer, pX As Decimal, pY As Decimal, GApDT As DataTable)

        Dim rowName As String = ""
        Dim newX As Decimal = pX
        Dim newY As Decimal = pY

        If side = 1 Then
            Dim sidePoints = pDT.Select("Y = '" & pY & "'")
            If sidePoints.Length = 0 Then
                newX = GApDT.Select("NAME = 'GA_1'")(0)("X")
            End If
            For Each DR2 As DataRow In sidePoints
                If DR2("X") < pX Then
                    rowName = DR2("NAME")
                Else
                    newX = GApDT.Select("NAME = 'GA_1'")(0)("X")
                    Exit For
                End If
            Next
        ElseIf side = 2 Then
            Dim sidePoints = pDT.Select("X = '" & pX & "'")
            If sidePoints.Length = 0 Then
                newY = GApDT.Select("NAME = 'GA_2'")(0)("Y")
            End If
            For Each DR2 As DataRow In sidePoints
                If DR2("Y") > pY Then
                    rowName = DR2("NAME")
                Else
                    newY = GApDT.Select("NAME = 'GA_2'")(0)("Y")
                    Exit For
                End If
            Next
        ElseIf side = 3 Then
            Dim sidePoints = pDT.Select("Y = '" & pY & "'")
            If sidePoints.Length = 0 Then
                newX = GApDT.Select("NAME = 'GA_3'")(0)("X")
            End If
            For Each DR2 As DataRow In sidePoints
                If DR2("X") > pX Then
                    rowName = DR2("NAME")
                Else
                    newX = GApDT.Select("NAME = 'GA_3'")(0)("X")
                    Exit For
                End If
            Next
        Else
            Dim sidePoints = pDT.Select("X = '" & pX & "'")
            If sidePoints.Length = 0 Then
                newY = GApDT.Select("NAME = 'GA_4'")(0)("Y")
            Else
                If sidePoints(0)("NAME") = "GA_1" Then
                    Dim pointList As New List(Of DataRow)
                    For i = 1 To sidePoints.Length - 1
                        pointList.Add(sidePoints(i))
                    Next
                    pointList.Add(sidePoints(0))

                    For Each DR2 As DataRow In pointList
                        If DR2("Y") < pY Then
                            rowName = DR2("NAME")
                        Else
                            newY = GApDT.Select("NAME = 'GA_4'")(0)("Y")
                            Exit For
                        End If
                    Next
                Else
                    For Each DR2 As DataRow In sidePoints
                        If DR2("Y") < pY Then
                            rowName = DR2("NAME")
                        Else
                            newY = GApDT.Select("NAME = 'GA_4'")(0)("Y")
                            Exit For
                        End If
                    Next
                End If
            End If
        End If

        Dim index As Integer = 0
        If rowName = "" Then
            Dim newSide As Integer = side - 1
            If newSide = 0 Then
                newSide = 4
            End If
            index = Get_RowIndex(pDT, newSide, newX, newY, GApDT)
        Else
            For j = 0 To pDT.Rows.Count - 1
                If pDT.Rows(j)("NAME") = rowName Then
                    index = j
                    Exit For
                End If
            Next
        End If

        Return index
    End Function

    Private Shared Sub Create_SecondAnglePoint(pDT As DataTable, rpDR As DataRow, gp As Decimal(), GApDT As DataTable, rDT As DataTable, pNameToRemove As String)
        Dim p0(1) As Decimal
        Dim p1(1) As Decimal
        Dim p2(1) As Decimal

        Dim newDR As DataRow = pDT.NewRow
        newDR("TYPE") = "Recess CA"

        Dim side As Integer = 0
        Dim pointName As String = rpDR("NAME")
        If pointName.Split("_")(1) = 1 Then
            Dim DR = Data.gratingPoints.Select("NAME = '" & pointName.Split("_")(0) & "_2" & "'")
            newDR("NAME") = pointName.Split("_")(0) & "_2"

            p0(0) = rpDR("X")
            p0(1) = rpDR("Y")

            p2(0) = DR(0)("X")
            p2(1) = DR(0)("Y")

            If rpDR("SIDE") + 1 > 4 Then
                side = rpDR("SIDE") + 1 - 4
            Else
                side = rpDR("SIDE") + 1
            End If
        Else
            Dim DR = Data.gratingPoints.Select("NAME = '" & pointName.Split("_")(0) & "_1" & "'")
            newDR("NAME") = pointName.Split("_")(0) & "_1"

            p0(0) = rpDR("X")
            p0(1) = rpDR("Y")

            p2(0) = DR(0)("X")
            p2(1) = DR(0)("Y")

            If rpDR("SIDE") - 1 < 1 Then
                side = rpDR("SIDE") - 1 + 4
            Else
                side = rpDR("SIDE") - 1
            End If
        End If

        For Each rDR As DataRow In rDT.Rows
            If rDR("NAME") = newDR("NAME") Then
                Exit Sub
            End If
        Next

        If rpDR("SIDE") = 1 OrElse rpDR("SIDE") = 3 Then
            p1(0) = p2(0)
            p1(1) = p0(1)
        ElseIf rpDR("SIDE") = 2 OrElse rpDR("SIDE") = 4 Then
            p1(0) = p0(0)
            p1(1) = p2(1)
        End If

        Dim gpInside As Boolean = Calculate_Triangle_Bool(gp, p0, p1, p2)

        Dim insertIndex As Integer = 0
        If gpInside = False Then
            ' If false => new point at side rpDR("SIDE")+1
            If side = 1 Then
                Dim c As Decimal = GApDT.Select("NAME = 'GA_1'")(0)("Y") - rpDR("Y")
                Dim z As Decimal = Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("Y") - rpDR("Y")
                Dim x As Decimal = 0
                If pointName.Split("_")(1) = 1 Then
                    x = Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("X") - GApDT.Select("NAME = 'GA_1'")(0)("X")
                    newDR("X") = GApDT.Select("NAME = 'GA_1'")(0)("X") + c * x / z      ' Triangle likformighet
                Else
                    x = GApDT.Select("NAME = 'GA_2'")(0)("X") - Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("X")
                    newDR("X") = GApDT.Select("NAME = 'GA_2'")(0)("X") - c * x / z      ' Triangle likformighet
                End If
                newDR("Y") = GApDT.Select("NAME = 'GA_1'")(0)("Y")
            ElseIf side = 2 Then
                Dim c As Decimal = GApDT.Select("NAME = 'GA_2'")(0)("X") - rpDR("X")
                Dim z As Decimal = Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("X") - rpDR("X")
                Dim x As Decimal = 0
                If pointName.Split("_")(1) = 1 Then
                    x = GApDT.Select("NAME = 'GA_2'")(0)("Y") - Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("Y")
                    newDR("Y") = GApDT.Select("NAME = 'GA_2'")(0)("Y") - c * x / z      ' Triangle likformighet
                Else
                    x = Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("Y") - GApDT.Select("NAME = 'GA_3'")(0)("Y")
                    newDR("Y") = GApDT.Select("NAME = 'GA_3'")(0)("Y") + c * x / z      ' Triangle likformighet
                End If
                newDR("X") = GApDT.Select("NAME = 'GA_2'")(0)("X")
            ElseIf side = 3 Then
                Dim c As Decimal = rpDR("Y") - GApDT.Select("NAME = 'GA_3'")(0)("Y")
                Dim z As Decimal = rpDR("Y") - Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("Y")
                Dim x As Decimal = 0
                If pointName.Split("_")(1) = 1 Then
                    x = GApDT.Select("NAME = 'GA_3'")(0)("X") - Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("X")
                    newDR("X") = GApDT.Select("NAME = 'GA_3'")(0)("X") - c * x / z      ' Triangle likformighet
                Else
                    x = Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("X") - GApDT.Select("NAME = 'GA_4'")(0)("X")
                    newDR("X") = GApDT.Select("NAME = 'GA_4'")(0)("X") + c * x / z      ' Triangle likformighet
                End If
                newDR("Y") = GApDT.Select("NAME = 'GA_3'")(0)("Y")
            Else
                Dim c As Decimal = rpDR("X") - GApDT.Select("NAME = 'GA_4'")(0)("X")
                Dim z As Decimal = rpDR("X") - Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("X")
                Dim x As Decimal = 0
                If pointName.Split("_")(1) = 1 Then
                    x = Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("Y") - GApDT.Select("NAME = 'GA_4'")(0)("Y")
                    newDR("Y") = GApDT.Select("NAME = 'GA_4'")(0)("Y") + c * x / z      ' Triangle likformighet
                Else
                    x = GApDT.Select("NAME = 'GA_1'")(0)("Y") - Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("Y")
                    newDR("Y") = GApDT.Select("NAME = 'GA_1'")(0)("Y") - c * x / z      ' Triangle likformighet
                End If
                newDR("X") = GApDT.Select("NAME = 'GA_4'")(0)("X")
            End If

            newDR("X") = Math.Round(newDR("X"), 3)
            newDR("Y") = Math.Round(newDR("Y"), 3)

            insertIndex = Get_RowIndex(pDT, side, newDR("X"), newDR("Y"), GApDT) + 1
        Else
            ' If true => remove point gp and new point at side rpDR("SIDE")+2
            Dim temp As String = newDR("NAME")
            If temp.Split("_")(1) = 1 Then
                If side = 1 Then
                    side = 4
                Else
                    side -= 1
                End If
            Else
                If side = 4 Then
                    side = 1
                Else
                    side += 1
                End If
            End If

            If side = 1 Then
                Dim x As Decimal = rpDR("X") - Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("X")
                Dim y As Decimal = Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("Y") - rpDR("Y")
                Dim b As Decimal = 0
                If pointName.Split("_")(1) = 1 Then
                    b = Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("Y") - GApDT.Select("NAME = 'GA_1'")(0)("Y")
                    newDR("X") = GApDT.Select("NAME = 'GA_1'")(0)("X") + x * b / y - (GApDT.Select("NAME = 'GA_1'")(0)("X") - Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("X"))   ' Triangle likformighet
                Else
                    b = GApDT.Select("NAME = 'GA_2'")(0)("Y") - Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("Y")
                    newDR("X") = GApDT.Select("NAME = 'GA_2'")(0)("X") - x * b / y + (Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("X") - GApDT.Select("NAME = 'GA_2'")(0)("X"))   ' Triangle likformighet
                End If
                newDR("Y") = GApDT.Select("NAME = 'GA_1'")(0)("Y")
            ElseIf side = 2 Then
                Dim x As Decimal = Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("Y") - rpDR("Y")
                Dim y As Decimal = Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("X") - rpDR("X")
                Dim b As Decimal = 0
                If pointName.Split("_")(1) = 1 Then
                    b = Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("X") - GApDT.Select("NAME = 'GA_2'")(0)("X")
                    newDR("Y") = GApDT.Select("NAME = 'GA_2'")(0)("Y") - x * b / y + (Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("Y") - GApDT.Select("NAME = 'GA_2'")(0)("Y"))
                Else
                    b = GApDT.Select("NAME = 'GA_3'")(0)("X") - Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("X")
                    newDR("Y") = GApDT.Select("NAME = 'GA_3'")(0)("Y") + x * b / y - (GApDT.Select("NAME = 'GA_3'")(0)("Y") - Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("Y"))
                End If
                newDR("X") = GApDT.Select("NAME = 'GA_2'")(0)("X")
            ElseIf side = 3 Then
                Dim x As Decimal = Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("X") - rpDR("X")
                Dim y As Decimal = rpDR("Y") - Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("Y")
                Dim b As Decimal = 0
                If pointName.Split("_")(1) = 1 Then
                    b = GApDT.Select("NAME = 'GA_3'")(0)("Y") - Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("Y")
                    newDR("X") = GApDT.Select("NAME = 'GA_3'")(0)("X") - x * b / y + (Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("X") - GApDT.Select("NAME = 'GA_3'")(0)("X"))
                Else
                    b = Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("Y") - GApDT.Select("NAME = 'GA_4'")(0)("Y")
                    newDR("X") = GApDT.Select("NAME = 'GA_4'")(0)("X") + x * b / y - (GApDT.Select("NAME = 'GA_4'")(0)("X") - Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("X"))
                End If
                newDR("Y") = GApDT.Select("NAME = 'GA_3'")(0)("Y")
            Else
                Dim x As Decimal = rpDR("Y") - Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("Y")
                Dim y As Decimal = rpDR("X") - Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("X")
                Dim b As Decimal = 0
                If pointName.Split("_")(1) = 1 Then
                    b = GApDT.Select("NAME = 'GA_4'")(0)("X") - Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("X")
                    newDR("Y") = GApDT.Select("NAME = 'GA_4'")(0)("Y") + x * b / y - (GApDT.Select("NAME = 'GA_4'")(0)("Y") - Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("Y"))
                Else
                    b = Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("X") - GApDT.Select("NAME = 'GA_1'")(0)("X")
                    newDR("Y") = GApDT.Select("NAME = 'GA_1'")(0)("Y") - x * b / y + (Data.gratingPoints.Select("NAME = '" & newDR("NAME") & "'")(0)("Y") - GApDT.Select("NAME = 'GA_1'")(0)("Y"))
                End If
                newDR("X") = GApDT.Select("NAME = 'GA_4'")(0)("X")
            End If

            insertIndex = Get_RowIndex(pDT, side, newDR("X"), newDR("Y"), GApDT)

            pDT.Rows.InsertAt(newDR, insertIndex + 1)

            Dim removeIndex As Integer = 0
            For k = 0 To pDT.Rows.Count - 1
                If pDT.Rows(k)("NAME") = pNameToRemove Then
                    removeIndex = k
                End If
            Next

            pDT.Rows.RemoveAt(removeIndex)
        End If
    End Sub

    Private Shared Function Calculate_Triangle_Bool(gp As Decimal(), p0 As Decimal(), p1 As Decimal(), p2 As Decimal())

        Dim s As Decimal = p0(1) * p2(0) - p0(0) * p2(1) + (p2(1) - p0(1)) * gp(0) + (p0(0) - p2(0)) * gp(1)
        Dim t As Decimal = p0(0) * p1(1) - p0(1) * p1(0) + (p0(1) - p1(1)) * gp(0) + (p1(0) - p0(0)) * gp(1)

        If (s < 0 AndAlso t >= 0) OrElse (s >= 0 AndAlso t < 0) Then
            Return False
        End If

        Dim area As Decimal = -p1(1) * p2(0) + p0(1) * (p2(0) - p1(0)) + p0(0) * (p1(1) - p2(1)) + p1(0) * p2(1)

        If area < 0 Then
            If s <= 0 AndAlso s + t >= area Then
                Return True
            Else
                Return False
            End If
        Else
            If s >= 0 AndAlso s + t <= area Then
                Return True
            Else
                Return False
            End If
        End If
    End Function
End Class
