Option Strict On
Option Explicit On

Imports Nexamas.UI.Theming
Imports Nexamas.UI.Values
Imports SkiaSharp

Namespace Nexamas.UI.Components

    Friend NotInheritable Class MASMediaVisualStyleResolver

        Private Sub New()
        End Sub

        Friend Shared Function Resolve(ctx As MASThemeContext,
                                       dpi As Single) As MASMediaVisualStyle
            If ctx IsNot Nothing AndAlso ctx.MediaTheme IsNot Nothing Then
                Dim media As IMASMediaTheme = ctx.MediaTheme
                Return New MASMediaVisualStyle(media.Shell, media.Toolbar, media.Stage, media.Footer, media.Control, media.Text)
            End If

            Dim accent As SKColor = Color.Accent.Accent2
            Dim accentSoft As SKColor = Color.Interaction.HoverSoftFill
            Dim highlight As SKColor = Color.Background.Type.Default.ColdLight1
            Dim silver As SKColor = Color.Background.Type.Default.ColdAccent
            Dim surfaceTop As SKColor = Color.Surfaces.Type.Default.SurfaceTop
            Dim surfaceMid As SKColor = Color.Surfaces.Type.Default.SurfaceMid
            Dim surfaceBottom As SKColor = Color.Surfaces.Type.Default.SurfaceBot
            Dim materialWash As SKColor = Color.Background.Type.Default.WashBase
            Dim coldTint As SKColor = Color.Background.Type.Default.ColdTint
            Dim borderOuter As SKColor = Color.Borders.BorderOuter
            Dim borderInner As SKColor = Color.Borders.BorderInner_Secondary
            Dim shadow As SKColor = Color.Core.ShadowBase
            Dim textPrimary As SKColor = Color.Text.Primary
            Dim textMuted As SKColor = Color.Text.Muted
            Dim textDisabled As SKColor = ColorMath.WithAlpha(textMuted, 150)

            If ctx IsNot Nothing Then
                If ctx.BrandTheme IsNot Nothing Then
                    accent = ctx.BrandTheme.BrandPrimary
                    accentSoft = ctx.BrandTheme.BrandPrimarySoft
                    highlight = ctx.BrandTheme.BrandHighlight
                    silver = ctx.BrandTheme.BrandSilver
                End If

                If ctx.SurfaceTheme IsNot Nothing Then
                    surfaceTop = ctx.SurfaceTheme.SurfaceTop
                    surfaceMid = ctx.SurfaceTheme.SurfaceMid
                    surfaceBottom = ctx.SurfaceTheme.SurfaceBot
                    materialWash = ctx.SurfaceTheme.MaterialWash
                    coldTint = ctx.SurfaceTheme.BackgroundColdTint
                    borderOuter = ctx.SurfaceTheme.BorderOuter
                    borderInner = ctx.SurfaceTheme.BorderInner
                    shadow = ctx.SurfaceTheme.ShadowBase
                End If

                If ctx.TextColorTheme IsNot Nothing Then
                    textPrimary = ctx.TextColorTheme.PrimaryText
                    textMuted = ctx.TextColorTheme.MutedText
                    textDisabled = ctx.TextColorTheme.DisabledText
                End If
            End If

            Dim shell As New MASMediaRegionTheme(
                surfaceTop:=LimitSurface(ColorMath.TowardPerceptualLch(ColorMath.Mix(surfaceTop, silver, 0.16F), coldTint, 0.08F), 0.91F, 0.98F),
                surfaceMid:=LimitSurface(ColorMath.TowardPerceptualLch(ColorMath.Mix(surfaceMid, silver, 0.12F), materialWash, 0.08F), 0.86F, 0.95F),
                surfaceBottom:=LimitSurface(ColorMath.TowardPerceptualLch(ColorMath.Mix(surfaceBottom, accentSoft, 0.055F), silver, 0.06F), 0.82F, 0.92F),
                borderOuter:=ColorMath.WithAlpha(LimitLine(ColorMath.Mix(borderOuter, silver, 0.16F)), 112),
                borderInner:=ColorMath.WithAlpha(LimitLift(ColorMath.Mix(borderInner, highlight, 0.10F)), 64),
                sheen:=ColorMath.WithAlpha(LimitLift(ColorMath.Mix(materialWash, highlight, 0.10F)), 44),
                shadow:=ColorMath.WithAlpha(shadow, 46),
                accent:=accent)

            Dim toolbar As New MASMediaRegionTheme(
                surfaceTop:=LimitSurface(ColorMath.TowardPerceptualLch(ColorMath.Mix(surfaceTop, highlight, 0.12F), silver, 0.08F), 0.93F, 0.985F),
                surfaceMid:=LimitSurface(ColorMath.TowardPerceptualLch(ColorMath.Mix(surfaceMid, silver, 0.22F), materialWash, 0.06F), 0.89F, 0.955F),
                surfaceBottom:=LimitSurface(ColorMath.TowardPerceptualLch(ColorMath.Mix(surfaceBottom, accentSoft, 0.055F), silver, 0.06F), 0.85F, 0.93F),
                borderOuter:=ColorMath.WithAlpha(LimitLine(ColorMath.Mix(borderOuter, accent, 0.08F)), 72),
                borderInner:=ColorMath.WithAlpha(LimitLift(ColorMath.Mix(borderInner, highlight, 0.08F)), 64),
                sheen:=ColorMath.WithAlpha(LimitLift(ColorMath.Mix(materialWash, highlight, 0.14F)), 58),
                shadow:=ColorMath.WithAlpha(shadow, 34),
                accent:=accent)

            Dim stage As New MASMediaRegionTheme(
                surfaceTop:=LimitSurface(ColorMath.TowardPerceptualLch(ColorMath.Mix(surfaceTop, coldTint, 0.32F), silver, 0.06F), 0.88F, 0.955F),
                surfaceMid:=LimitSurface(ColorMath.TowardPerceptualLch(ColorMath.Mix(surfaceMid, silver, 0.14F), coldTint, 0.12F), 0.83F, 0.925F),
                surfaceBottom:=LimitSurface(ColorMath.TowardPerceptualLch(ColorMath.Mix(surfaceBottom, silver, 0.18F), accentSoft, 0.04F), 0.78F, 0.89F),
                borderOuter:=ColorMath.WithAlpha(LimitLine(ColorMath.Mix(borderOuter, silver, 0.14F)), 58),
                borderInner:=ColorMath.WithAlpha(LimitLift(ColorMath.Mix(borderInner, surfaceTop, 0.08F)), 38),
                sheen:=ColorMath.WithAlpha(LimitLift(ColorMath.Mix(materialWash, surfaceTop, 0.16F)), 34),
                shadow:=ColorMath.WithAlpha(shadow, 32),
                accent:=accent)

            Dim footer As New MASMediaRegionTheme(
                surfaceTop:=LimitSurface(ColorMath.TowardPerceptualLch(ColorMath.Mix(surfaceMid, silver, 0.18F), coldTint, 0.08F), 0.86F, 0.94F),
                surfaceMid:=LimitSurface(ColorMath.TowardPerceptualLch(ColorMath.Mix(surfaceBottom, silver, 0.16F), materialWash, 0.06F), 0.82F, 0.91F),
                surfaceBottom:=LimitSurface(ColorMath.TowardPerceptualLch(ColorMath.Mix(surfaceBottom, silver, 0.10F), accentSoft, 0.035F), 0.76F, 0.86F),
                borderOuter:=ColorMath.WithAlpha(LimitLine(ColorMath.Mix(borderOuter, silver, 0.22F)), 88),
                borderInner:=ColorMath.WithAlpha(LimitLift(ColorMath.Mix(borderInner, surfaceTop, 0.08F)), 48),
                sheen:=ColorMath.WithAlpha(LimitLift(ColorMath.Mix(materialWash, silver, 0.12F)), 38),
                shadow:=ColorMath.WithAlpha(shadow, 42),
                accent:=accent)

            Dim controlBase As SKColor = LimitSurface(ColorMath.Mix(surfaceMid, accentSoft, 0.055F), 0.86F, 0.955F)
            Dim control As New MASMediaControlTheme(
                fill:=ColorMath.WithAlpha(controlBase, 72),
                fillSelected:=ColorMath.WithAlpha(ColorMath.Mix(surfaceTop, accent, 0.16F), 132),
                border:=ColorMath.WithAlpha(LimitLine(ColorMath.Mix(borderOuter, accent, 0.12F)), 82),
                icon:=ColorMath.Mix(textPrimary, accent, 0.14F),
                iconMuted:=ColorMath.Mix(textMuted, silver, 0.12F))

            Dim text As New MASMediaTextTheme(textPrimary, ColorMath.Mix(textPrimary, silver, 0.18F), textMuted, textDisabled)
            Return New MASMediaVisualStyle(shell, toolbar, stage, footer, control, text)
        End Function

        Private Shared Function LimitSurface(c As SKColor,
                                             minLightness As Single,
                                             maxLightness As Single) As SKColor
            Return ThemeColorStyling.ConstrainPerceptual(
                c:=c,
                minLightness:=minLightness,
                maxLightness:=maxLightness,
                minChroma:=0.01F,
                maxChroma:=0.034F)
        End Function

        Private Shared Function LimitLine(c As SKColor) As SKColor
            Return ThemeColorStyling.ConstrainPerceptual(
                c:=c,
                minLightness:=0.62F,
                maxLightness:=0.82F,
                minChroma:=0.012F,
                maxChroma:=0.036F)
        End Function

        Private Shared Function LimitLift(c As SKColor) As SKColor
            Return ThemeColorStyling.ConstrainPerceptual(
                c:=c,
                minLightness:=0.9F,
                maxLightness:=0.985F,
                minChroma:=0.006F,
                maxChroma:=0.026F)
        End Function

    End Class

End Namespace
