Option Strict On
Option Explicit On

Imports System
Imports Nexamas.UI.Architecture
Imports Nexamas.UI.Controls
Imports Nexamas.UI.General
Imports Nexamas.UI.Rendering
Imports Nexamas.UI.Theming
Imports Nexamas.UI.TextRendering
Imports Nexamas.UI.Values
Imports SkiaSharp

Namespace Nexamas.UI.Components


    Partial Friend NotInheritable Class MASTabRenderer
        Private Sub DrawNavButton(canvas As SKCanvas,
                          ctx As MASThemeContext,
                          lay As MASTabLayout.Metrics,
                          buttonR As SKRect,
                          kind As MASTabNavButtonKind,
                          owner As MASTabControl,
                          env As MASTabRenderEnv)

            If canvas Is Nothing OrElse ctx Is Nothing Then Return
            If buttonR.Width <= 1.0F OrElse buttonR.Height <= 1.0F Then Return

            Dim hovered As Boolean = (owner.HoverNavButton = kind)
            Dim pressed As Boolean = (owner.PressedNavButton = kind)

            Dim enabled As Boolean
            Select Case kind
                Case MASTabNavButtonKind.LeftButton
                    enabled = lay.ShowLeftNav

                Case MASTabNavButtonKind.RightButton
                    enabled = lay.ShowRightNav

                Case Else
                    enabled = False
            End Select

            Dim st As MASVisualInteractionState = MASVisualInteractionState.Normal
            If Not enabled Then
                st = MASVisualInteractionState.Disabled
            ElseIf pressed Then
                st = MASVisualInteractionState.Pressed
            ElseIf hovered Then
                st = MASVisualInteractionState.Hover
            End If

            Dim pocketR As SKRect = MASTabPremiumVisualPolicy.ResolveNavPocketRect(buttonR, kind, env.Dpi)
            If pocketR.Width <= 1.0F OrElse pocketR.Height <= 1.0F Then Return

            DrawNavPocketSurface(canvas, lay, pocketR, kind, st, env)
            DrawNavPocketGlyph(canvas, pocketR, kind, st, enabled, env)
        End Sub




        Private Sub DrawNavPocketSurface(canvas As SKCanvas,
                                 lay As MASTabLayout.Metrics,
                                 pocketR As SKRect,
                                 kind As MASTabNavButtonKind,
                                 st As MASVisualInteractionState,
                                 env As MASTabRenderEnv)

            If pocketR.Width <= 1.0F OrElse pocketR.Height <= 1.0F Then Return

            Dim r As SKRect = PixelSnap.SnapRectHalf(pocketR)
            Dim radiusPx As Single = MASTabPremiumVisualPolicy.ResolveNavPocketRadiusPx(r, env.Dpi)

            Dim fillCol As SKColor = SKColors.Transparent
            Dim glowCol As SKColor = SKColors.Transparent
            Dim glossTopCol As SKColor = SKColors.Transparent
            Dim strokeCol As SKColor = SKColors.Transparent
            Dim fillAlpha As Byte = 0
            Dim glowAlpha As Byte = 0
            Dim glossAlpha As Byte = 0
            Dim strokeAlpha As Byte = 0

            Select Case st
                Case MASVisualInteractionState.Normal
                    fillCol = ColorMath.Mix(env.Tabs.Strip.FillTop, env.Surface.SurfaceTop, 0.16F)
                    glowCol = ColorMath.Mix(env.Foundation.Brand.BrandSilverSoft, env.Tabs.Strip.WashColor, 0.18F)
                    glossTopCol = SKColors.White
                    strokeCol = ColorMath.Mix(env.Tabs.Strip.RimColor, env.Tabs.Item.BaseRim, 0.18F)

                    fillAlpha = 16
                    glowAlpha = 8
                    glossAlpha = 8
                    strokeAlpha = 12

                Case MASVisualInteractionState.Hover
                    fillCol = ColorMath.Mix(env.Foundation.Brand.BrandHighlight, env.Tabs.Strip.WashColor, 0.34F)
                    glowCol = ColorMath.Mix(env.Foundation.Brand.BrandSilverSoft, env.Foundation.Brand.BrandHighlight, 0.28F)
                    glossTopCol = SKColors.White
                    strokeCol = ColorMath.Mix(env.Tabs.Strip.RimColor, env.Foundation.Brand.BrandHighlight, 0.18F)

                    fillAlpha = 34
                    glowAlpha = 26
                    glossAlpha = 18
                    strokeAlpha = 24

                Case MASVisualInteractionState.Pressed
                    fillCol = ColorMath.Mix(env.Foundation.Brand.BrandPrimaryStrong, env.Surface.SurfaceBot, 0.24F)
                    glowCol = ColorMath.Mix(env.Foundation.Brand.BrandHighlight, env.Foundation.Brand.BrandPrimaryStrong, 0.36F)
                    glossTopCol = SKColors.White
                    strokeCol = ColorMath.Mix(env.Tabs.Strip.RimColor, env.Foundation.Brand.BrandPrimaryStrong, 0.24F)

                    fillAlpha = 48
                    glowAlpha = 34
                    glossAlpha = 12
                    strokeAlpha = 30

                Case MASVisualInteractionState.Disabled
                    fillCol = env.Foundation.Semantics.Disabled
                    strokeCol = env.Foundation.Semantics.Disabled

                    fillAlpha = 12
                    glowAlpha = 0
                    glossAlpha = 0
                    strokeAlpha = 12
            End Select

            FillNavPocketPath(_navPocketPath, r, radiusPx, kind)

            If fillAlpha > 0 Then
                ResetNavFillPaint()
                _navFillPaint.Color = New SKColor(fillCol.Red, fillCol.Green, fillCol.Blue, fillAlpha)
                canvas.DrawPath(_navPocketPath, _navFillPaint)
            End If

            If glowAlpha > 0 Then
                Using glowShader As SKShader =
                    SKShader.CreateLinearGradient(
                        New SKPoint(r.Left, r.Top),
                        New SKPoint(r.Left, r.Bottom),
                        New SKColor() {
                            New SKColor(glowCol.Red, glowCol.Green, glowCol.Blue, CByte(Math.Min(255, glowAlpha + 8))),
                            New SKColor(glowCol.Red, glowCol.Green, glowCol.Blue, glowAlpha),
                            New SKColor(glowCol.Red, glowCol.Green, glowCol.Blue, CByte(Math.Max(0, glowAlpha - 14)))
                        },
                        New Single() {0.0F, 0.5F, 1.0F},
                        SKShaderTileMode.Clamp)

                    ResetNavFxPaint()
                    _navFxPaint.Shader = glowShader
                    canvas.DrawPath(_navPocketPath, _navFxPaint)
                    _navFxPaint.Shader = Nothing
                End Using
            End If

            If glossAlpha > 0 Then
                Dim glossR As SKRect = r
                glossR.Bottom = r.Top + r.Height * 0.58F

                FillNavPocketPath(
                    _navPocketGlossPath,
                    glossR,
                    Math.Max(1.0F, radiusPx * 0.9F),
                    kind)

                Using glossShader As SKShader =
                    SKShader.CreateLinearGradient(
                        New SKPoint(glossR.Left, glossR.Top),
                        New SKPoint(glossR.Left, glossR.Bottom),
                        New SKColor() {
                            New SKColor(glossTopCol.Red, glossTopCol.Green, glossTopCol.Blue, glossAlpha),
                            New SKColor(glossTopCol.Red, glossTopCol.Green, glossTopCol.Blue, 0)
                        },
                        New Single() {0.0F, 1.0F},
                        SKShaderTileMode.Clamp)

                    ResetNavFxPaint()
                    _navFxPaint.Shader = glossShader
                    canvas.DrawPath(_navPocketGlossPath, _navFxPaint)
                    _navFxPaint.Shader = Nothing
                End Using
            End If

            If strokeAlpha > 0 Then
                ResetNavStrokePaint()
                _navStrokePaint.StrokeWidth = Math.Max(1.0F, lay.HairW)
                _navStrokePaint.Color = New SKColor(strokeCol.Red, strokeCol.Green, strokeCol.Blue, strokeAlpha)
                canvas.DrawPath(_navPocketPath, _navStrokePaint)
            End If

            If st = MASVisualInteractionState.Pressed Then
                Dim innerInset As Single = Math.Max(1.0F, 1.05F * env.Dpi)

                FillNavPocketPath(
                    _navPocketInnerPath,
                    InsetRect(r, innerInset),
                    Math.Max(1.0F, radiusPx - innerInset),
                    kind)

                ResetNavStrokePaint()
                _navStrokePaint.StrokeWidth = Math.Max(1.0F, lay.HairW * 0.9F)
                _navStrokePaint.Color = New SKColor(255, 255, 255, 12)
                canvas.DrawPath(_navPocketInnerPath, _navStrokePaint)
            End If
        End Sub




        Private Shared Sub FillNavPocketPath(path As SKPath,
                                             r As SKRect,
                                             radiusPx As Single,
                                             kind As MASTabNavButtonKind)

            If path Is Nothing Then Return

            Dim rr As Single = Math.Min(radiusPx, Math.Min(r.Width, r.Height) * 0.5F)
            path.Reset()
            path.AddRoundRect(r, rr, rr)
        End Sub




        Private Sub DrawNavPocketGlyph(canvas As SKCanvas,
                                       pocketR As SKRect,
                                       kind As MASTabNavButtonKind,
                                       st As MASVisualInteractionState,
                                       isEnabled As Boolean,
                                       env As MASTabRenderEnv)

            Dim iconCol As SKColor = env.Tabs.Nav.IconColor
            Dim glowAlpha As Byte = 18

            If Not isEnabled Then
                iconCol = ColorMath.Mix(iconCol, env.Foundation.Semantics.Disabled, 0.46F)
                glowAlpha = 8
            Else
                Select Case st
                    Case MASVisualInteractionState.Hover
                        iconCol = ColorMath.Mix(iconCol, env.Foundation.Brand.BrandHighlight, 0.14F)
                        glowAlpha = 24

                    Case MASVisualInteractionState.Pressed
                        iconCol = ColorMath.Mix(iconCol, env.Foundation.Brand.BrandPrimaryStrong, 0.2F)
                        glowAlpha = 30
                End Select
            End If

            Dim glyphR As SKRect = pocketR
            glyphR.Inflate(-MASTabPremiumVisualPolicy.ResolveNavGlyphInsetX(env.Dpi), -MASTabPremiumVisualPolicy.ResolveNavGlyphInsetY(env.Dpi))
            glyphR = PixelSnap.SnapRectHalf(glyphR)

            DrawChevronGlyph(canvas, glyphR, kind, iconCol, st, isEnabled, glowAlpha, env)
        End Sub




        Private Sub DrawChevronGlyph(canvas As SKCanvas,
                                     r As SKRect,
                                     kind As MASTabNavButtonKind,
                                     iconCol As SKColor,
                                     st As MASVisualInteractionState,
                                     isEnabled As Boolean,
                                     glowAlpha As Byte,
                                     env As MASTabRenderEnv)

            If r.Width <= 1.0F OrElse r.Height <= 1.0F Then Return

            Dim strokeW As Single = PixelSnap.SnapHalf(Math.Max(1.55F, 1.75F * env.Dpi))

            Dim cx As Single = (r.Left + r.Right) * 0.5F
            Dim cy As Single = (r.Top + r.Bottom) * 0.5F
            Dim size As Single = Math.Min(r.Width, r.Height)

            Dim halfW As Single = size * 0.15F
            Dim halfH As Single = size * 0.2F
            Dim belly As Single = size * 0.18F

            If st = MASVisualInteractionState.Pressed Then
                Dim nudge As Single = Math.Max(0.35F, 0.5F * env.Dpi)
                If kind = MASTabNavButtonKind.LeftButton Then
                    cx -= nudge
                ElseIf kind = MASTabNavButtonKind.RightButton Then
                    cx += nudge
                End If
            End If

            Dim startPt As SKPoint
            Dim midPt As SKPoint
            Dim endPt As SKPoint
            Dim c1 As SKPoint
            Dim c2 As SKPoint
            Dim c3 As SKPoint
            Dim c4 As SKPoint

            If kind = MASTabNavButtonKind.LeftButton Then
                startPt = New SKPoint(cx + halfW, cy - halfH)
                midPt = New SKPoint(cx - halfW, cy)
                endPt = New SKPoint(cx + halfW, cy + halfH)

                c1 = New SKPoint(cx + halfW * 0.35F, cy - halfH * 0.72F)
                c2 = New SKPoint(cx - halfW + belly, cy - belly)

                c3 = New SKPoint(cx - halfW + belly, cy + belly)
                c4 = New SKPoint(cx + halfW * 0.35F, cy + halfH * 0.72F)
            Else
                startPt = New SKPoint(cx - halfW, cy - halfH)
                midPt = New SKPoint(cx + halfW, cy)
                endPt = New SKPoint(cx - halfW, cy + halfH)

                c1 = New SKPoint(cx - halfW * 0.35F, cy - halfH * 0.72F)
                c2 = New SKPoint(cx + halfW - belly, cy - belly)

                c3 = New SKPoint(cx + halfW - belly, cy + belly)
                c4 = New SKPoint(cx - halfW * 0.35F, cy + halfH * 0.72F)
            End If

            _navGlyphPath.Reset()
            _navGlyphPath.MoveTo(startPt)
            _navGlyphPath.CubicTo(c1, c2, midPt)
            _navGlyphPath.CubicTo(c3, c4, endPt)

            ResetNavStrokePaint()
            _navStrokePaint.StrokeCap = SKStrokeCap.Round
            _navStrokePaint.StrokeJoin = SKStrokeJoin.Round
            _navStrokePaint.StrokeWidth = strokeW + Math.Max(0.55F, 0.7F * env.Dpi)
            _navStrokePaint.Color = New SKColor(255, 255, 255, glowAlpha)
            canvas.DrawPath(_navGlyphPath, _navStrokePaint)

            ResetNavStrokePaint()
            _navStrokePaint.StrokeCap = SKStrokeCap.Round
            _navStrokePaint.StrokeJoin = SKStrokeJoin.Round
            _navStrokePaint.StrokeWidth = strokeW
            _navStrokePaint.Color = iconCol
            canvas.DrawPath(_navGlyphPath, _navStrokePaint)
        End Sub

    End Class

End Namespace
