Public Class Draw_Grating
    Private Shared guiPanelL, guiPanelW As Integer

    Public Shared DirSymbolPoints As New List(Of Integer())
    Private Shared ArrowSymbolPoints As New Dictionary(Of String, Integer())

    Public Shared measureLabels As New Dictionary(Of String, Integer())

    Public Shared sideSquareMesLine As New Dictionary(Of String, Integer())


    Public Shared Sub Load_DrawingPanel()
        AddHandler Individual.Panel_Grating.Paint, AddressOf DrawingPanel_Paint

        Get_DrawboxParameters()

        Create_DirSymbolPoints()
        Create_ArrowSymbolPoints()

        ' Initialize start points
        Data.Init_GrossAreaPoints()
        Data.Init_GratingPoints()

        Update_GratingPoints()
    End Sub

    ' --- Retrive parameters for the drawing box ---
    Private Shared Sub Get_DrawboxParameters()
        guiPanelL = Individual.Panel_Grating.Size.Width
        guiPanelW = Individual.Panel_Grating.Size.Height

        Data.guiPanelMidX = guiPanelL / 2
        Data.guiPanelMidY = guiPanelW / 2

        Data.guiMaxDrawL = guiPanelL - 80
        Data.guiMaxDrawW = guiPanelW - 80

        Data.drawAR = Data.guiMaxDrawL / Data.guiMaxDrawW

        Data.gratingAR = Data.gratingL / Data.gratingW
    End Sub

    ' --- Create points for grating direction symbol ---
    Private Shared Sub Create_DirSymbolPoints()
        DirSymbolPoints.Add({-27 + Data.guiPanelMidX, -2 + Data.guiPanelMidY})
        DirSymbolPoints.Add({17 + Data.guiPanelMidX, -2 + Data.guiPanelMidY})
        DirSymbolPoints.Add({9 + Data.guiPanelMidX, -10 + Data.guiPanelMidY})
        DirSymbolPoints.Add({12 + Data.guiPanelMidX, -13 + Data.guiPanelMidY})
        DirSymbolPoints.Add({27 + Data.guiPanelMidX, 2 + Data.guiPanelMidY})
        DirSymbolPoints.Add({-17 + Data.guiPanelMidX, 2 + Data.guiPanelMidY})
        DirSymbolPoints.Add({-9 + Data.guiPanelMidX, 10 + Data.guiPanelMidY})
        DirSymbolPoints.Add({-12 + Data.guiPanelMidX, 13 + Data.guiPanelMidY})
        DirSymbolPoints.Add({-27 + Data.guiPanelMidX, -2 + Data.guiPanelMidY})
    End Sub

    ' --- Create points for arrow symbol ---
    Private Shared Sub Create_ArrowSymbolPoints()
        Dim offset As Integer = 20
        ArrowSymbolPoints.Add("p1", {offset, guiPanelW - offset})
        ArrowSymbolPoints.Add("p2", {offset, guiPanelW - offset - 40})
        ArrowSymbolPoints.Add("p3", {offset - 5, guiPanelW - offset - 35})
        ArrowSymbolPoints.Add("p4", {offset, guiPanelW - offset - 40})
        ArrowSymbolPoints.Add("p5", {offset + 5, guiPanelW - offset - 35})
        ArrowSymbolPoints.Add("p6", {offset, guiPanelW - offset - 40})
        ArrowSymbolPoints.Add("p7", {offset, guiPanelW - offset})
        ArrowSymbolPoints.Add("p8", {offset + 40, guiPanelW - offset})
        ArrowSymbolPoints.Add("p9", {offset + 35, guiPanelW - offset - 5})
        ArrowSymbolPoints.Add("p10", {offset + 40, guiPanelW - offset})
        ArrowSymbolPoints.Add("p11", {offset + 35, guiPanelW - offset + 5})
    End Sub

    ' --- Updates all the gratings points ---
    Public Shared Sub Update_GratingPoints()
        Data.gratingAR = Data.gratingL / Data.gratingW

        If Data.gratingAR < Data.drawAR Then
            ' Change draw width
            Data.scaleDiff = Data.gratingW / Data.guiMaxDrawW
            ' Gross area points
            Data.grossAreaPoints.Rows(0)("GUI X") = Data.guiPanelMidX - Data.gratingL / (Data.scaleDiff * 2)
            Data.grossAreaPoints.Rows(0)("GUI Y") = Data.guiPanelMidY - Data.guiMaxDrawW / 2
            Data.grossAreaPoints.Rows(1)("GUI X") = Data.guiPanelMidX + Data.gratingL / (Data.scaleDiff * 2)
            Data.grossAreaPoints.Rows(1)("GUI Y") = Data.guiPanelMidY - Data.guiMaxDrawW / 2
            Data.grossAreaPoints.Rows(2)("GUI X") = Data.guiPanelMidX + Data.gratingL / (Data.scaleDiff * 2)
            Data.grossAreaPoints.Rows(2)("GUI Y") = Data.guiPanelMidY + Data.guiMaxDrawW / 2
            Data.grossAreaPoints.Rows(3)("GUI X") = Data.guiPanelMidX - Data.gratingL / (Data.scaleDiff * 2)
            Data.grossAreaPoints.Rows(3)("GUI Y") = Data.guiPanelMidY + Data.guiMaxDrawW / 2

            ' Grating points
            Data.gratingPoints.Rows(0)("GUI X") = Data.guiPanelMidX - Data.gratingL / (Data.scaleDiff * 2)
            Data.gratingPoints.Rows(0)("GUI Y") = Data.guiPanelMidY - Data.guiMaxDrawW / 2
            Data.gratingPoints.Rows(1)("GUI X") = Data.guiPanelMidX + Data.gratingL / (Data.scaleDiff * 2)
            Data.gratingPoints.Rows(1)("GUI Y") = Data.guiPanelMidY - Data.guiMaxDrawW / 2
            Data.gratingPoints.Rows(2)("GUI X") = Data.guiPanelMidX + Data.gratingL / (Data.scaleDiff * 2)
            Data.gratingPoints.Rows(2)("GUI Y") = Data.guiPanelMidY + Data.guiMaxDrawW / 2
            Data.gratingPoints.Rows(3)("GUI X") = Data.guiPanelMidX - Data.gratingL / (Data.scaleDiff * 2)
            Data.gratingPoints.Rows(3)("GUI Y") = Data.guiPanelMidY + Data.guiMaxDrawW / 2

        Else
            ' Change draw height
            Data.scaleDiff = Data.gratingL / Data.guiMaxDrawL

            ' Gross area points
            Data.grossAreaPoints.Rows(0)("GUI X") = Data.guiPanelMidX - Data.guiMaxDrawL / 2
            Data.grossAreaPoints.Rows(0)("GUI Y") = Data.guiPanelMidY - Data.gratingW / (Data.scaleDiff * 2)
            Data.grossAreaPoints.Rows(1)("GUI X") = Data.guiPanelMidX + Data.guiMaxDrawL / 2
            Data.grossAreaPoints.Rows(1)("GUI Y") = Data.guiPanelMidY - Data.gratingW / (Data.scaleDiff * 2)
            Data.grossAreaPoints.Rows(2)("GUI X") = Data.guiPanelMidX + Data.guiMaxDrawL / 2
            Data.grossAreaPoints.Rows(2)("GUI Y") = Data.guiPanelMidY + Data.gratingW / (Data.scaleDiff * 2)
            Data.grossAreaPoints.Rows(3)("GUI X") = Data.guiPanelMidX - Data.guiMaxDrawL / 2
            Data.grossAreaPoints.Rows(3)("GUI Y") = Data.guiPanelMidY + Data.gratingW / (Data.scaleDiff * 2)

            ' Grating points
            Data.gratingPoints.Rows(0)("GUI X") = Data.guiPanelMidX - Data.guiMaxDrawL / 2
            Data.gratingPoints.Rows(0)("GUI Y") = Data.guiPanelMidY - Data.gratingW / (Data.scaleDiff * 2)
            Data.gratingPoints.Rows(1)("GUI X") = Data.guiPanelMidX + Data.guiMaxDrawL / 2
            Data.gratingPoints.Rows(1)("GUI Y") = Data.guiPanelMidY - Data.gratingW / (Data.scaleDiff * 2)
            Data.gratingPoints.Rows(2)("GUI X") = Data.guiPanelMidX + Data.guiMaxDrawL / 2
            Data.gratingPoints.Rows(2)("GUI Y") = Data.guiPanelMidY + Data.gratingW / (Data.scaleDiff * 2)
            Data.gratingPoints.Rows(3)("GUI X") = Data.guiPanelMidX - Data.guiMaxDrawL / 2
            Data.gratingPoints.Rows(3)("GUI Y") = Data.guiPanelMidY + Data.gratingW / (Data.scaleDiff * 2)
        End If

        ' Gross area points
        Data.grossAreaPoints.Rows(0)("X") = (-Data.gratingL / 2) / 1000
        Data.grossAreaPoints.Rows(0)("Y") = (Data.gratingW / 2) / 1000
        Data.grossAreaPoints.Rows(1)("X") = (Data.gratingL / 2) / 1000
        Data.grossAreaPoints.Rows(1)("Y") = (Data.gratingW / 2) / 1000
        Data.grossAreaPoints.Rows(2)("X") = (Data.gratingL / 2) / 1000
        Data.grossAreaPoints.Rows(2)("Y") = (-Data.gratingW / 2) / 1000
        Data.grossAreaPoints.Rows(3)("X") = (-Data.gratingL / 2) / 1000
        Data.grossAreaPoints.Rows(3)("Y") = (-Data.gratingW / 2) / 1000

        ' Grating points
        Data.gratingPoints.Rows(0)("X") = (-Data.gratingL / 2) / 1000
        Data.gratingPoints.Rows(0)("Y") = (Data.gratingW / 2) / 1000
        Data.gratingPoints.Rows(1)("X") = (Data.gratingL / 2) / 1000
        Data.gratingPoints.Rows(1)("Y") = (Data.gratingW / 2) / 1000
        Data.gratingPoints.Rows(2)("X") = (Data.gratingL / 2) / 1000
        Data.gratingPoints.Rows(2)("Y") = (-Data.gratingW / 2) / 1000
        Data.gratingPoints.Rows(3)("X") = (-Data.gratingL / 2) / 1000
        Data.gratingPoints.Rows(3)("Y") = (-Data.gratingW / 2) / 1000

        Individual.Panel_Grating.Refresh()
    End Sub

    ' --- Draw all the lines for the panel and grating ---
    Public Shared Sub DrawingPanel_Paint(sender As Object, e As PaintEventArgs)
        Draw_Grating(e.Graphics, 7)

        ' Draw arrow symbol
        Dim symPen As Pen = New Pen(Color.Black, 1)
        For i = 1 To ArrowSymbolPoints.Count - 1
            e.Graphics.DrawLine(symPen, ArrowSymbolPoints("p" & i)(0), ArrowSymbolPoints("p" & i)(1),
                                ArrowSymbolPoints("p" & i + 1)(0), ArrowSymbolPoints("p" & i + 1)(1))
        Next

    End Sub

    Public Shared Sub Draw_Grating(g As Graphics, fontSize As Integer)
        ' Draw grating gross area (red)
        Dim penCon As Pen = New Pen(Color.Red, 2)
        penCon.DashPattern = {4, 6}
        g.DrawLine(penCon, Data.grossAreaPoints(0)("GUI X"), Data.grossAreaPoints(0)("GUI Y"),
                            Data.grossAreaPoints(1)("GUI X"), Data.grossAreaPoints(1)("GUI Y"))
        g.DrawLine(penCon, Data.grossAreaPoints(1)("GUI X"), Data.grossAreaPoints(1)("GUI Y"),
                            Data.grossAreaPoints(2)("GUI X"), Data.grossAreaPoints(2)("GUI Y"))
        g.DrawLine(penCon, Data.grossAreaPoints(2)("GUI X"), Data.grossAreaPoints(2)("GUI Y"),
                            Data.grossAreaPoints(3)("GUI X"), Data.grossAreaPoints(3)("GUI Y"))
        g.DrawLine(penCon, Data.grossAreaPoints(3)("GUI X"), Data.grossAreaPoints(3)("GUI Y"),
                            Data.grossAreaPoints(0)("GUI X"), Data.grossAreaPoints(0)("GUI Y"))

        ' Draw grating direction symbol
        Dim symPen As Pen = New Pen(Color.Black, 1)
        For i = 0 To DirSymbolPoints.Count - 2
            g.DrawLine(symPen, DirSymbolPoints(i)(0), DirSymbolPoints(i)(1),
                                DirSymbolPoints(i + 1)(0), DirSymbolPoints(i + 1)(1))
        Next

        ' Draw measure labels
        For i = 0 To measureLabels.Count - 1
            Dim mesName As String = measureLabels.Keys(i)
            g.DrawString(measureLabels(mesName)(0), New Font("Microsoft Sans Serif", fontSize), Brushes.Black,
                                  New Point(measureLabels(mesName)(1), measureLabels(mesName)(2)))
        Next

        'Stöd measurement linje för sidesquare and middlesquare
        Dim penMes As Pen = New Pen(Color.FromArgb(60, 33, 107, 77), 1)
        For i = 0 To sideSquareMesLine.Count - 1
            Dim mesName As String = sideSquareMesLine.Keys(i)
            g.DrawLine(penMes, sideSquareMesLine(mesName)(0), sideSquareMesLine(mesName)(1),
                                sideSquareMesLine(mesName)(2), sideSquareMesLine(mesName)(3))

            If Data.pointsMeasurements(mesName)(2) = 1 OrElse Data.pointsMeasurements(mesName)(2) = 3 Then
                g.DrawLine(penMes, sideSquareMesLine(mesName)(0), sideSquareMesLine(mesName)(1) + 2,
                                                sideSquareMesLine(mesName)(0), sideSquareMesLine(mesName)(1) - 2)
                g.DrawLine(penMes, sideSquareMesLine(mesName)(2), sideSquareMesLine(mesName)(1) + 2,
                                    sideSquareMesLine(mesName)(2), sideSquareMesLine(mesName)(1) - 2)
            Else
                g.DrawLine(penMes, sideSquareMesLine(mesName)(0) + 2, sideSquareMesLine(mesName)(1),
                                    sideSquareMesLine(mesName)(0) - 2, sideSquareMesLine(mesName)(1))
                g.DrawLine(penMes, sideSquareMesLine(mesName)(0) + 2, sideSquareMesLine(mesName)(3),
                                    sideSquareMesLine(mesName)(0) - 2, sideSquareMesLine(mesName)(3))
            End If
        Next

        ' Draw angle recess help lines
        Dim Pendot As Pen = New Pen(Color.Gray, 1)
        Pendot.DashPattern = {2, 4}

        For i = 0 To Data.angleRecessPoints.Rows.Count - 1
            Dim angleQuadrant As String = Data.angleRecessPoints.Rows(i)("QUADRANT")
            Dim p1XGUI, p1YGUI, p2XGUI, p2YGUI As Integer
            For Each DR As DataRow In Data.gratingPoints.Rows
                If DR("NAME").Split("_")(0) = "CA" & i + 1 Then
                    Dim index As Integer = Data.gratingPoints.Rows.IndexOf(DR)
                    p1XGUI = Data.gratingPoints.Rows(index)("GUI X")
                    p1YGUI = Data.gratingPoints.Rows(index)("GUI Y")
                    p2XGUI = Data.gratingPoints.Rows(index + 1)("GUI X")
                    p2YGUI = Data.gratingPoints.Rows(index + 1)("GUI Y")
                    Exit For
                End If
            Next
            g.DrawLine(Pendot, Data.angleRecessPoints.Rows(i)("GUI X"), Data.angleRecessPoints.Rows(i)("GUI Y"),
                                p1XGUI, p1YGUI)
            g.DrawLine(Pendot, Data.angleRecessPoints.Rows(i)("GUI X"), Data.angleRecessPoints.Rows(i)("GUI Y"),
                                p2XGUI, p2YGUI)
        Next


        ' Draw actual grating (black)
        Dim pen As Pen = New Pen(Color.Black, 2)
        For i = 0 To Data.gratingPoints.Rows.Count - 1
            Dim pTemp1(2) As Integer
            Dim pTemp2(2) As Integer

            pTemp1(0) = Data.gratingPoints.Rows(i)("GUI X")
            pTemp1(1) = Data.gratingPoints.Rows(i)("GUI Y")
            Try
                pTemp2(0) = Data.gratingPoints.Rows(i + 1)("GUI X")
                pTemp2(1) = Data.gratingPoints.Rows(i + 1)("GUI Y")
            Catch ex As Exception
                pTemp2(0) = Data.gratingPoints.Rows(0)("GUI X")
                pTemp2(1) = Data.gratingPoints.Rows(0)("GUI Y")
            End Try

            g.DrawLine(pen, pTemp1(0), pTemp1(1), pTemp2(0), pTemp2(1))
        Next

        For i = 0 To Data.gratingMiddlePoints.Rows.Count - 1
            Dim pTemp1(2) As Integer
            Dim pTemp2(2) As Integer

            pTemp1(0) = Data.gratingMiddlePoints.Rows(i)("GUI X")
            pTemp1(1) = Data.gratingMiddlePoints.Rows(i)("GUI Y")

            If (i + 1) Mod 4 = 0 Then
                pTemp2(0) = Data.gratingMiddlePoints.Rows(i - 3)("GUI X")
                pTemp2(1) = Data.gratingMiddlePoints.Rows(i - 3)("GUI Y")
            Else
                pTemp2(0) = Data.gratingMiddlePoints.Rows(i + 1)("GUI X")
                pTemp2(1) = Data.gratingMiddlePoints.Rows(i + 1)("GUI Y")
            End If

            g.DrawLine(pen, pTemp1(0), pTemp1(1), pTemp2(0), pTemp2(1))
        Next

        ' Draw grating grid for fill area
        If AppForm.fillMode Then
            Dim dashPen As Pen = New Pen(Color.DarkGray, 1)
            dashPen.DashPattern = {6, 4}

            'Vertical lines
            Dim singleLength As Integer = Grating_Fill.minLength / Data.scaleDiff
            For i = 0 To Grating_Fill.numOfHorizontal - 2
                Dim x As Integer
                x = Data.grossAreaPoints.Rows(0)("GUI X") + singleLength * (i + 1)

                Dim y1 As Integer = Data.grossAreaPoints.Rows(0)("GUI Y")
                Dim y2 As Integer = Data.grossAreaPoints.Rows(3)("GUI Y")
                g.DrawLine(dashPen, x, y1, x, y2)
            Next

            'Horizontal lines
            Dim singleWidth As Integer = Grating_Fill.maxSingleWidth / Data.scaleDiff
            For i = 0 To Grating_Fill.numOfVertical - 2
                Dim y As Integer
                If Grating_Fill.widthRevNeeded AndAlso i = Grating_Fill.numOfVertical - 2 Then
                    y = Data.grossAreaPoints.Rows(0)("GUI Y") + singleWidth * i + Grating_Fill.revWidth / Data.scaleDiff
                Else
                    y = Data.grossAreaPoints.Rows(0)("GUI Y") + singleWidth * (i + 1)
                End If
                Dim x1 As Integer = Data.grossAreaPoints.Rows(0)("GUI X")
                Dim x2 As Integer = Data.grossAreaPoints.Rows(1)("GUI X")
                g.DrawLine(dashPen, x1, y, x2, y)
            Next
        End If
    End Sub
End Class
