Option Strict On
Option Explicit On

Imports System
Imports SkiaSharp

Namespace Nexamas.UI.Branding

    Friend NotInheritable Class MasFalconLogoPainter
        Implements IDisposable

        Private Const ViewW As Single = 111.73F
        Private Const ViewH As Single = 66.5F

        Private Shared ReadOnly GoldStops As Single() = {
            0.0F, 0.09F, 0.24F, 0.33F, 0.37F, 0.42F,
            0.47F, 0.53F, 0.65F, 0.79F, 0.91F, 1.0F
        }

        Private Shared ReadOnly GoldColors As SKColor() = {
            New SKColor(&HEB, &HCF, &H87),
            New SKColor(&HE4, &HC1, &H74),
            New SKColor(&HDB, &HAF, &H5A),
            New SKColor(&HD8, &HA8, &H51),
            New SKColor(&HE7, &HBE, &H65),
            New SKColor(&HF5, &HD1, &H76),
            New SKColor(&HFC, &HDC, &H81),
            New SKColor(&HFF, &HE0, &H84),
            New SKColor(&HE9, &HC0, &H67),
            New SKColor(&HD5, &HA4, &H4D),
            New SKColor(&HC9, &H93, &H3D),
            New SKColor(&HC5, &H8D, &H37)
        }

        Private ReadOnly _paths As SKPath()
        Private ReadOnly _disposed As Boolean = False

        Friend Sub New()
            _paths = BuildPaths()
        End Sub

        Friend Sub Draw(canvas As SKCanvas, dst As SKRect)
            If canvas Is Nothing Then Return
            If dst.Width <= 1.0F OrElse dst.Height <= 1.0F Then Return

            Dim scale As Single = Math.Min(dst.Width / ViewW, dst.Height / ViewH)
            If scale <= 0.0F Then Return

            Dim drawW As Single = ViewW * scale
            Dim drawH As Single = ViewH * scale
            Dim drawX As Single = dst.MidX - (drawW * 0.5F)
            Dim drawY As Single = dst.MidY - (drawH * 0.5F)

            canvas.Save()

            canvas.Translate(drawX, drawY)
            canvas.Scale(scale, scale)

            ' SVG source uses path transform="translate(-11.4 -40.46)"
            ' We mirror that by shifting the whole local drawing space.
            canvas.Translate(-11.4F, -40.46F)

            DrawAllPaths(canvas)

            canvas.Restore()
        End Sub

        Private Sub DrawAllPaths(canvas As SKCanvas)

            DrawPath(canvas, _paths(0), CreateGoldGradient(40.43F, 149.36F, 40.43F, 3.94F))
            DrawPath(canvas, _paths(1), CreateGoldGradient(52.56F, 149.36F, 52.56F, 3.94F))
            DrawPath(canvas, _paths(2), CreateGoldGradient(46.42F, 149.36F, 46.42F, 3.94F))
            DrawPath(canvas, _paths(3), CreateGoldGradient(29.72F, 149.36F, 29.72F, 3.94F))
            DrawPath(canvas, _paths(4), CreateGoldGradient(58.36F, 149.36F, 58.36F, 3.94F))
            DrawPath(canvas, _paths(5), CreateGoldGradient(35.0F, 149.36F, 35.0F, 3.94F))
            DrawPath(canvas, _paths(6), CreateGoldGradient(67.26F, 149.36F, 67.26F, 3.94F))
            DrawPath(canvas, _paths(7), CreateGoldGradient(94.09F, 149.36F, 94.09F, 3.94F))
            DrawPath(canvas, _paths(8), CreateGoldGradient(81.97F, 149.36F, 81.97F, 3.94F))
            DrawPath(canvas, _paths(9), CreateGoldGradient(88.11F, 149.36F, 88.11F, 3.94F))
            DrawPath(canvas, _paths(10), CreateGoldGradient(104.81F, 149.36F, 104.81F, 3.94F))
            DrawPath(canvas, _paths(11), CreateGoldGradient(76.17F, 149.36F, 76.17F, 3.94F))
            DrawPath(canvas, _paths(12), CreateGoldGradient(99.52F, 149.36F, 99.52F, 3.94F))
            DrawPath(canvas, _paths(13), CreateGoldGradient(73.15F, 67.9F, 68.3F, 47.49F))
            DrawPath(canvas, _paths(14), CreateGoldGradient(101.05F, 66.41F, 113.43F, 36.69F))
            DrawPath(canvas, _paths(15), CreateGoldGradient(-386.31F, 66.41F, -373.92F, 36.69F, SKMatrix.CreateScaleTranslation(-1.0F, 1.0F, -352.83F, 0.0F)))
        End Sub

        Private Shared Sub DrawPath(canvas As SKCanvas, path As SKPath, shader As SKShader)
            If canvas Is Nothing OrElse path Is Nothing Then Return

            Using p As New SKPaint()
                p.IsAntialias = True
                p.IsDither = True
                p.Style = SKPaintStyle.Fill
                p.Shader = shader
                canvas.DrawPath(path, p)
            End Using

            If shader IsNot Nothing Then shader.Dispose()
        End Sub

        Private Shared Function CreateGoldGradient(x1 As Single,
                                                   y1 As Single,
                                                   x2 As Single,
                                                   y2 As Single,
                                                   Optional localMatrix As SKMatrix? = Nothing) As SKShader

            If localMatrix.HasValue Then
                Return SKShader.CreateLinearGradient(
                    New SKPoint(x1, y1),
                    New SKPoint(x2, y2),
                    GoldColors,
                    GoldStops,
                    SKShaderTileMode.Clamp,
                    localMatrix.Value
                )
            End If

            Return SKShader.CreateLinearGradient(
                New SKPoint(x1, y1),
                New SKPoint(x2, y2),
                GoldColors,
                GoldStops,
                SKShaderTileMode.Clamp
            )
        End Function

        Private Shared Function BuildPaths() As SKPath()
            Return New SKPath() {
                SKPath.ParseSvgPathData("M48.14,71c-.84-.8-1.61-1.61-2.31-2.42a49.49,49.49,0,0,1-13.1,3.58q1.94,1.78,3.83,3.27a4.62,4.62,0,0,0,5.23.47A29.86,29.86,0,0,0,48.14,71Z"),
                SKPath.ParseSvgPathData("M53.53,75a32.75,32.75,0,0,1-5.89,7.22c1.55.72,3,1.29,4.34,1.76a2.37,2.37,0,0,0,2.82-1.23,36,36,0,0,0,2.68-5.84A26.76,26.76,0,0,1,53.53,75Z"),
                SKPath.ParseSvgPathData("M52.42,74.34a31.09,31.09,0,0,1-3.26-2.44,28.62,28.62,0,0,1-8.74,6.29c1.26.84,2.5,1.59,3.7,2.26a3.32,3.32,0,0,0,4.11-.72A32.78,32.78,0,0,0,52.42,74.34Z"),
                SKPath.ParseSvgPathData("M41.79,62.86a26.62,26.62,0,0,1-1.62-3.24L17.65,52.67c1.36,2.43,2.77,4.68,4.2,6.77a6.93,6.93,0,0,0,5,3.14A130.27,130.27,0,0,0,41.79,62.86Z"),
                SKPath.ParseSvgPathData("M60.34,84.52l1.36-6.35a27.56,27.56,0,0,1-3-.82A35.61,35.61,0,0,1,55,84.93a35.64,35.64,0,0,0,3.89.82A1.38,1.38,0,0,0,60.34,84.52Z"),
                SKPath.ParseSvgPathData("M33.66,70.49a50.28,50.28,0,0,0,11.18-3.12c-.84-1.06-1.55-2.08-2.16-3-.63,0-2.88.14-6,.14-3.25,0-7.42-.12-11.55-.54q2.1,2.66,4.22,4.89A4.92,4.92,0,0,0,33.66,70.49Z"),
                SKPath.ParseSvgPathData("M93.45,51.84a7.22,7.22,0,0,0-4,4.33C87.9,60.3,84.5,67,78.73,66.51a10.47,10.47,0,0,1-2.9-.64c-1.73-.86-3.28-3.13-4.06-7.12-1-5-1.91-8.69-5.47-9.44a8.2,8.2,0,0,0-6.25,1.3s3.66-.6,3.73,5.86c.08,7-4.43,9.14-5.29,9.47a10.32,10.32,0,0,1-2.69.57C50,67,46.63,60.3,45.09,56.17a7.24,7.24,0,0,0-4-4.33L11.4,40.46,15,47a9.58,9.58,0,0,0,5.48,4.74L41.08,58c7.29,17.74,22,19.21,22,19.21L58.92,99.71l5.1,4.5,1.54-11.34v12.65l1.7,1.44,1.7-1.44V92.87l1.55,11.34,5.09-4.5L71.44,77.25s14.71-1.47,22-19.21l20.62-6.27A9.55,9.55,0,0,0,119.54,47l3.59-6.57Z"),
                SKPath.ParseSvgPathData("M86.39,71a30,30,0,0,0,6.34,4.9A4.62,4.62,0,0,0,98,75.41q1.91-1.48,3.84-3.27a49.36,49.36,0,0,1-13.1-3.58C88,69.37,87.23,70.18,86.39,71Z"),
                SKPath.ParseSvgPathData("M81,75a27.25,27.25,0,0,1-4,1.91,35.76,35.76,0,0,0,2.67,5.84A2.37,2.37,0,0,0,82.55,84c1.32-.47,2.78-1,4.34-1.76A32.75,32.75,0,0,1,81,75Z"),
                SKPath.ParseSvgPathData("M82.11,74.34a32.58,32.58,0,0,0,4.18,5.39,3.33,3.33,0,0,0,4.12.72c1.2-.67,2.43-1.42,3.69-2.26a28.75,28.75,0,0,1-8.74-6.29A30.94,30.94,0,0,1,82.11,74.34Z"),
                SKPath.ParseSvgPathData("M92.74,62.86a130.29,130.29,0,0,0,14.89-.28,6.94,6.94,0,0,0,5.05-3.14c1.42-2.09,2.83-4.34,4.2-6.77L94.35,59.62A27.3,27.3,0,0,1,92.74,62.86Z"),
                SKPath.ParseSvgPathData("M72.82,78.17l1.36,6.35a1.39,1.39,0,0,0,1.45,1.23,35.08,35.08,0,0,0,3.88-.82,35.44,35.44,0,0,1-3.64-7.58A27.74,27.74,0,0,1,72.82,78.17Z"),
                SKPath.ParseSvgPathData("M91.84,64.34a35,35,0,0,1-2.16,3,50.62,50.62,0,0,0,11.18,3.12,4.9,4.9,0,0,0,4.27-1.66q2.13-2.23,4.23-4.89c-4.13.42-8.3.54-11.56.54C94.73,64.48,92.48,64.38,91.84,64.34Z"),
                SKPath.ParseSvgPathData("M81.7,66.08c-2.26,2.08-5.31,3.88-8.31,2.48-5.83-2.7-3.54-11.34-6.39-15.89-2.64-4.21-6.35-2.39-6.88-2.09,0,0,0,0,0,0h0a8.22,8.22,0,0,1,6.23-1.3c3.56.77,4.47,4.4,5.46,9.45.79,4,2.34,6.26,4.07,7.12a10.47,10.47,0,0,0,2.9.64A6.77,6.77,0,0,0,81.7,66.08Z"),
                SKPath.ParseSvgPathData("M123.13,40.46,119.54,47a9.55,9.55,0,0,1-5.48,4.74L93.44,58a5.5,5.5,0,0,1,3.48-4.44L112,48.83a13.52,13.52,0,0,0,5-2.89Z"),
                SKPath.ParseSvgPathData("M11.4,40.46,15,47a9.58,9.58,0,0,0,5.48,4.74L41.08,58a5.51,5.51,0,0,0-3.47-4.44l-15.1-4.77a13.48,13.48,0,0,1-5-2.89Z")
            }
        End Function

        Public Sub Dispose() Implements IDisposable.Dispose
            For Each p In _paths
                If p IsNot Nothing Then p.Dispose()
            Next
        End Sub

    End Class

End Namespace