Option Strict On
Option Explicit On

Imports System
Imports Nexamas.UI.Architecture
Imports Nexamas.UI.Theming
Imports Nexamas.UI.Values
Imports SkiaSharp

Namespace Nexamas.UI.Rendering

    Friend NotInheritable Class MASAcrylicEffectPaletteResolver
        Private Sub New()
        End Sub

        Friend Structure AcrylicPalette
            Friend Top As SKColor
            Friend Mid As SKColor
            Friend Bot As SKColor
            Friend Wash As SKColor
            Friend BorderOuter As SKColor
            Friend BorderInner As SKColor
        End Structure

        Friend Shared Function TryResolveThemePalette(ctx As MASThemeContext,
                                                      contract As MASResolvedComponentContract,
                                                      ByRef pal As AcrylicPalette) As Boolean

            pal = New AcrylicPalette()

            If ctx Is Nothing Then Return False
            If contract Is Nothing Then Throw New ArgumentNullException(NameOf(contract))

            contract.AssertConsumable()

            Dim appTheme As IMASAppTheme = ctx.Theme
            If appTheme Is Nothing Then Return False

            Dim surfaceTheme As IMASFoundationSurfaceTheme = MASAppThemeContracts.Foundation(appTheme).Surface
            If surfaceTheme Is Nothing Then Return False

            Dim intensity As MASVisualEffectIntensityProfiles.AcrylicSurfaceIntensityProfile =
                MASVisualEffectIntensityProfiles.ResolveAcrylic(contract.SurfaceFamily)

            Dim topCol As SKColor = surfaceTheme.SurfaceTop
            Dim midCol As SKColor = surfaceTheme.SurfaceMid
            Dim botCol As SKColor = surfaceTheme.SurfaceBot
            Dim wash As SKColor = surfaceTheme.MaterialWash
            Dim borderOuter As SKColor = surfaceTheme.BorderOuter
            Dim borderInner As SKColor = surfaceTheme.BorderInner

            If borderOuter.Alpha = 0 Then
                borderOuter = ColorMath.WithAlpha(MASAppThemeContracts.Foundation(appTheme).TextColors.PrimaryText, 52)
            End If

            If borderInner.Alpha = 0 Then
                borderInner = ColorMath.WithAlpha(SKColors.White, 34)
            End If

            If intensity.TopBandEmphasis > 0.0F Then
                topCol = ColorMath.Mix(topCol, SKColors.White, intensity.TopBandEmphasis * 0.1F)
                midCol = ColorMath.Mix(midCol, SKColors.White, intensity.TopBandEmphasis * 0.04F)
                wash = ColorMath.Mix(wash, SKColors.White, intensity.TopBandEmphasis * 0.06F)
            End If

            If intensity.BottomAnchorStrength > 0.0F Then
                botCol = ColorMath.Mix(
                    botCol,
                    ColorMath.TowardBlack(botCol, 0.22F),
                    intensity.BottomAnchorStrength * 0.2F)
            End If

            If intensity.UseTopSheen AndAlso intensity.SheenStrength > 0.0F Then
                wash = ColorMath.Mix(
                    wash,
                    SKColors.White,
                    intensity.SheenStrength * 0.12F)
            End If

            borderOuter = ColorMath.WithAlpha(
                borderOuter,
                CByte(Math.Max(0, Math.Min(255, CInt(Math.Round(borderOuter.Alpha * (0.72F + intensity.OuterBorderStrength * 0.56F)))))))

            borderInner = ColorMath.WithAlpha(
                borderInner,
                CByte(Math.Max(0, Math.Min(255, CInt(Math.Round(borderInner.Alpha * (0.72F + intensity.InnerBorderStrength * 0.56F)))))))

            pal = New AcrylicPalette With {
                .Top = topCol,
                .Mid = midCol,
                .Bot = botCol,
                .Wash = wash,
                .BorderOuter = borderOuter,
                .BorderInner = borderInner
            }

            Return True

        End Function

    End Class

End Namespace
