Public Class GUI_Drawing_Panel
    Public Shared pCon1(3) As Decimal 'pCon(0) = pixel X, pCon(2) = SW X, etc.
    Public Shared pCon2(3) As Decimal
    Public Shared pCon3(3) As Decimal
    Public Shared pCon4(3) As Decimal

    Public Shared containerL, containerW, containerMidX, containerMidY As Integer
    Private Shared drawL As Integer = 1
    Private Shared drawW As Integer = 1

    Private Shared DirSymbolPoints As New Dictionary(Of String, Decimal())
    Private Shared ArrowSymbolPoints As New Dictionary(Of String, Decimal())

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

    Private Shared drawAspect, gratingAspect As Decimal
    Public Shared scaleDiff As Decimal = 1

    Public Shared pointsOrder As New List(Of String)
    Public Shared points As New Dictionary(Of String, Decimal())

    Public Shared anglePoints As New Dictionary(Of String, Integer())
    Public Shared anglePointsComp As New Dictionary(Of String, String())

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


    Public Shared Sub Load_DrawingPanel()
        Get_DrawboxParameters()
        Set_ContainerPointsX()
        Set_ContainerPointsY()

        Create_DirSymbolPoints()
        Create_ArrowSymbolPoints()
        Update_GratingPoints()
        Create_StartPoints()
    End Sub

    ' --- Retrive parameters for the drawing box ---
    Private Shared Sub Get_DrawboxParameters()
        containerL = GUI.DrawingPanel.Size.Width
        containerW = GUI.DrawingPanel.Size.Height

        containerMidX = containerL / 2
        containerMidY = containerW / 2

        drawL = containerL - 80
        drawW = containerW - 80

        drawAspect = drawL / drawW
    End Sub

    ' --- Set containers points X-values ---
    Private Shared Sub Set_ContainerPointsX()
        pCon1(0) = containerMidX - drawL / 2
        pCon2(0) = containerMidX + drawL / 2
        pCon3(0) = containerMidX + drawL / 2
        pCon4(0) = containerMidX - drawL / 2
    End Sub

    ' --- Set containers points Y-values ---
    Private Shared Sub Set_ContainerPointsY()
        pCon1(1) = containerMidY - drawW / 2
        pCon2(1) = containerMidY - drawW / 2
        pCon3(1) = containerMidY + drawW / 2
        pCon4(1) = containerMidY + drawW / 2
    End Sub


    ' --- Create points for grating direction symbol ---
    Private Shared Sub Create_DirSymbolPoints()
        DirSymbolPoints.Add("p1", {-30 + containerMidX, -2 + containerMidY})
        DirSymbolPoints.Add("p2", {20 + containerMidX, -2 + containerMidY})
        DirSymbolPoints.Add("p3", {12 + containerMidX, -10 + containerMidY})
        DirSymbolPoints.Add("p4", {15 + containerMidX, -13 + containerMidY})
        DirSymbolPoints.Add("p5", {30 + containerMidX, 2 + containerMidY})
        DirSymbolPoints.Add("p6", {-20 + containerMidX, 2 + containerMidY})
        DirSymbolPoints.Add("p7", {-12 + containerMidX, 10 + containerMidY})
        DirSymbolPoints.Add("p8", {-15 + containerMidX, 13 + containerMidY})
        DirSymbolPoints.Add("p9", {-30 + containerMidX, -2 + containerMidY})
    End Sub

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

    ' --- Updates all the gratings points ---
    Public Shared Sub Update_GratingPoints()
        gratingAspect = GUI_Gratings_Data.gratingMaxL / GUI_Gratings_Data.gratingMaxW

        If gratingAspect > drawAspect Then
            'Change draw height
            scaleDiff = GUI_Gratings_Data.gratingMaxL / drawL

            pCon1(1) = containerMidY - GUI_Gratings_Data.gratingMaxW / (scaleDiff * 2)
            pCon2(1) = containerMidY - GUI_Gratings_Data.gratingMaxW / (scaleDiff * 2)
            pCon3(1) = containerMidY + GUI_Gratings_Data.gratingMaxW / (scaleDiff * 2)
            pCon4(1) = containerMidY + GUI_Gratings_Data.gratingMaxW / (scaleDiff * 2)

            Set_ContainerPointsX()
        Else
            'Change draw width
            scaleDiff = GUI_Gratings_Data.gratingMaxW / drawW

            pCon1(0) = containerMidX - GUI_Gratings_Data.gratingMaxL / (scaleDiff * 2)
            pCon2(0) = containerMidX + GUI_Gratings_Data.gratingMaxL / (scaleDiff * 2)
            pCon3(0) = containerMidX + GUI_Gratings_Data.gratingMaxL / (scaleDiff * 2)
            pCon4(0) = containerMidX - GUI_Gratings_Data.gratingMaxL / (scaleDiff * 2)

            Set_ContainerPointsY()
        End If

        'Redraw grating
        GUI.DrawingPanel.Refresh()

        'SW X-values
        pCon1(2) = (-GUI_Gratings_Data.gratingMaxL / 2) / 1000
        pCon2(2) = (GUI_Gratings_Data.gratingMaxL / 2) / 1000
        pCon3(2) = (GUI_Gratings_Data.gratingMaxL / 2) / 1000
        pCon4(2) = (-GUI_Gratings_Data.gratingMaxL / 2) / 1000

        'SW Y-values
        pCon1(3) = (GUI_Gratings_Data.gratingMaxW / 2) / 1000
        pCon2(3) = (GUI_Gratings_Data.gratingMaxW / 2) / 1000
        pCon3(3) = (-GUI_Gratings_Data.gratingMaxW / 2) / 1000
        pCon4(3) = (-GUI_Gratings_Data.gratingMaxW / 2) / 1000
    End Sub

    ' --- Sets the start points for the grating ---
    Private Shared Sub Create_StartPoints()
        points.Add("p1", pCon1)
        GUI_Functions.pointsFunc.Add("p1", True)
        pointsOrder.Add("p1")

        points.Add("p2", pCon2)
        GUI_Functions.pointsFunc.Add("p2", True)
        pointsOrder.Add("p2")

        points.Add("p3", pCon3)
        GUI_Functions.pointsFunc.Add("p3", True)
        pointsOrder.Add("p3")

        points.Add("p4", pCon4)
        GUI_Functions.pointsFunc.Add("p4", True)
        pointsOrder.Add("p4")
    End Sub

    ' --- Draw all the lines for the container and grating ---
    Public Shared Sub DrawingPanel_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs)
        ' Draw outer grating (red)
        Dim penCon As Pen = New Pen(Color.Red, 2)
        penCon.DashPattern = {4, 6}
        e.Graphics.DrawLine(penCon, CInt(pCon1(0)), CInt(pCon1(1)), CInt(pCon2(0)), CInt(pCon2(1)))
        e.Graphics.DrawLine(penCon, CInt(pCon2(0)), CInt(pCon2(1)), CInt(pCon3(0)), CInt(pCon3(1)))
        e.Graphics.DrawLine(penCon, CInt(pCon3(0)), CInt(pCon3(1)), CInt(pCon4(0)), CInt(pCon4(1)))
        e.Graphics.DrawLine(penCon, CInt(pCon4(0)), CInt(pCon4(1)), CInt(pCon1(0)), CInt(pCon1(1)))

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

        ' Draw arrow symbol
        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

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

        'Stöd measurement linje för sidesquare
        Dim penMes As Pen = New Pen(Color.Gray, 1)
        For i = 0 To sideSquareMesLine.Count - 1
            Dim mesName As String = sideSquareMesLine.Keys(i)
            e.Graphics.DrawLine(penMes, sideSquareMesLine(mesName)(0), sideSquareMesLine(mesName)(1),
                                sideSquareMesLine(mesName)(2), sideSquareMesLine(mesName)(3))

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


        Dim Pendot As Pen = New Pen(Color.Gray, 1)
        Pendot.DashPattern = {2, 4}

        For i = 0 To anglePoints.Count - 1
            Dim angleName As String = anglePoints.Keys(i)
            e.Graphics.DrawLine(Pendot, anglePoints(angleName)(0), anglePoints(angleName)(1),
                                points(anglePointsComp(angleName)(0))(0), points(anglePointsComp(angleName)(0))(1))
            e.Graphics.DrawLine(Pendot, anglePoints(angleName)(0), anglePoints(angleName)(1),
                                points(anglePointsComp(angleName)(1))(0), points(anglePointsComp(angleName)(1))(1))
        Next


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

            pTemp1 = points(pointsOrder(i))
            Try
                pTemp2 = points(pointsOrder(i + 1))
            Catch ex As Exception
                pTemp2 = points(pointsOrder(0))
            End Try

            e.Graphics.DrawLine(pen, CInt(pTemp1(0)), CInt(pTemp1(1)), CInt(pTemp2(0)), CInt(pTemp2(1)))
        Next
    End Sub
End Class
