Option Strict On
Option Explicit On

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

Namespace Nexamas.UI.Rendering

    ' <summary>
    ' Extracted responsibility slice for MASAcrylicEffectPainter.
    ' Kept partial to preserve the binary/public surface while reducing hotspot size.
    ' </summary>
    Partial Friend NotInheritable Class MASAcrylicEffectPainter

#Region "Shared recipe structs"

        Private Structure AcrylicFamilyRecipe
            Friend BodyStops() As Single
            Friend ShineStops() As Single

            Friend TopToWashMix As Single
            Friend TopToMidMix As Single
            Friend MidToBotMix As Single
            Friend BotReturnMix As Single

            Friend TopLiftWhiteMul As Single
            Friend TopLiftMidWhiteMul As Single

            Friend BottomDarkBot2Mul As Single
            Friend BottomDarkBot1Mul As Single

            Friend ShineHiWashMix As Single
            Friend ShineMidWashMix As Single
            Friend ShineHiBaseA As Single
            Friend ShineHiMulA As Single
            Friend ShineMidBaseA As Single
            Friend ShineMidMulA As Single
        End Structure

#End Region

#Region "Tuning resolution"

        Private Shared Function ResolveCoolAcrylicTuning(fam As CommonEnums.SurfaceFamily) As MASAcrylicEffectTuningProfiles.AcrylicTuning

            Dim t As MASAcrylicEffectTuningProfiles.AcrylicTuning =
                MASAcrylicEffectTuningProfiles.ResolveAcrylic(fam)

            Dim intensity As MASVisualEffectIntensityProfiles.AcrylicSurfaceIntensityProfile =
                MASVisualEffectIntensityProfiles.ResolveAcrylic(fam)

            t.BaseMixT = Clamp01(t.BaseMixT + (intensity.TopBandEmphasis - 0.18F) * 0.14F)
            t.CoolBotT = Clamp01(t.CoolBotT + (intensity.BottomAnchorStrength - 0.14F) * 0.1F)

            t.BorderA = ScaleByte(t.BorderA, StrengthToMul(intensity.OuterBorderStrength))
            t.RimA = ScaleByte(t.RimA, StrengthToMul(intensity.InnerBorderStrength))

            If Not intensity.UseTopSheen Then
                t.GlossA = 0
            Else
                t.GlossA = ScaleByte(t.GlossA, 0.58F + intensity.SheenStrength * 0.42F)
            End If

            t.ShadeBotA = ScaleByte(t.ShadeBotA, StrengthToMul(intensity.BottomAnchorStrength))

            Return t

        End Function

        Private Shared Function ResolveCoolAcrylicFxTuning(fam As CommonEnums.SurfaceFamily) As MASAcrylicEffectTuningProfiles.FensterFxTuning
            Return MASAcrylicEffectTuningProfiles.ResolveFensterFx(fam)
        End Function

        Private Shared Function ResolveCoolAcrylicWash(fam As CommonEnums.SurfaceFamily,
                                                       wash As SKColor) As SKColor

            Dim intensity As MASVisualEffectIntensityProfiles.AcrylicSurfaceIntensityProfile =
                MASVisualEffectIntensityProfiles.ResolveAcrylic(fam)

            Select Case fam
                Case CommonEnums.SurfaceFamily.Menu
                    Return ColorMath.Mix(wash, SKColors.Transparent, 0.5F - intensity.TopBandEmphasis * 0.04F)

                Case CommonEnums.SurfaceFamily.DropDown,
                     CommonEnums.SurfaceFamily.ListBox,
                     CommonEnums.SurfaceFamily.Fenster

                    Return ColorMath.Mix(wash, SKColors.Transparent, 0.34F - intensity.TopBandEmphasis * 0.03F)

                Case Else
                    Return wash
            End Select

        End Function

#End Region

#Region "Acrylic family recipe"

        Private Shared Function ResolveAcrylicFamilyRecipe(fam As CommonEnums.SurfaceFamily) As AcrylicFamilyRecipe

            Select Case fam

                Case CommonEnums.SurfaceFamily.Fenster,
                     CommonEnums.SurfaceFamily.DropDown,
                     CommonEnums.SurfaceFamily.Menu,
                     CommonEnums.SurfaceFamily.ListBox

                    Return New AcrylicFamilyRecipe With {
                        .BodyStops = New Single() {0.0F, 0.12F, 0.46F, 0.8F, 1.0F},
                        .ShineStops = New Single() {0.0F, 0.26F, 1.0F},
                        .TopToWashMix = 0.18F,
                        .TopToMidMix = 0.22F,
                        .MidToBotMix = 0.52F,
                        .BotReturnMix = 0.14F,
                        .TopLiftWhiteMul = 0.095F,
                        .TopLiftMidWhiteMul = 0.045F,
                        .BottomDarkBot2Mul = 0.2F,
                        .BottomDarkBot1Mul = 0.28F,
                        .ShineHiWashMix = 0.38F,
                        .ShineMidWashMix = 0.24F,
                        .ShineHiBaseA = 18.0F,
                        .ShineHiMulA = 20.0F,
                        .ShineMidBaseA = 7.0F,
                        .ShineMidMulA = 11.0F
                    }

                Case CommonEnums.SurfaceFamily.ListSurface,
                     CommonEnums.SurfaceFamily.DataGrid,
                     CommonEnums.SurfaceFamily.Row

                    Return New AcrylicFamilyRecipe With {
                        .BodyStops = New Single() {0.0F, 0.14F, 0.48F, 0.82F, 1.0F},
                        .ShineStops = New Single() {0.0F, 0.3F, 1.0F},
                        .TopToWashMix = 0.12F,
                        .TopToMidMix = 0.26F,
                        .MidToBotMix = 0.46F,
                        .BotReturnMix = 0.22F,
                        .TopLiftWhiteMul = 0.09F,
                        .TopLiftMidWhiteMul = 0.045F,
                        .BottomDarkBot2Mul = 0.2F,
                        .BottomDarkBot1Mul = 0.28F,
                        .ShineHiWashMix = 0.38F,
                        .ShineMidWashMix = 0.24F,
                        .ShineHiBaseA = 18.0F,
                        .ShineHiMulA = 20.0F,
                        .ShineMidBaseA = 7.0F,
                        .ShineMidMulA = 11.0F
                    }

                Case CommonEnums.SurfaceFamily.Button

                    Return New AcrylicFamilyRecipe With {
                        .BodyStops = New Single() {0.0F, 0.16F, 0.5F, 0.84F, 1.0F},
                        .ShineStops = New Single() {0.0F, 0.36F, 1.0F},
                        .TopToWashMix = -1.0F,
                        .TopToMidMix = 0.22F,
                        .MidToBotMix = 0.42F,
                        .BotReturnMix = -1.0F,
                        .TopLiftWhiteMul = 0.1F,
                        .TopLiftMidWhiteMul = 0.05F,
                        .BottomDarkBot2Mul = 0.2F,
                        .BottomDarkBot1Mul = 0.28F,
                        .ShineHiWashMix = 0.38F,
                        .ShineMidWashMix = 0.24F,
                        .ShineHiBaseA = 18.0F,
                        .ShineHiMulA = 20.0F,
                        .ShineMidBaseA = 7.0F,
                        .ShineMidMulA = 11.0F
                    }

                Case CommonEnums.SurfaceFamily.Input,
                     CommonEnums.SurfaceFamily.ComboBox

                    Return New AcrylicFamilyRecipe With {
                        .BodyStops = New Single() {0.0F, 0.2F, 0.56F, 0.86F, 1.0F},
                        .ShineStops = New Single() {0.0F, 0.42F, 1.0F},
                        .TopToWashMix = -1.0F,
                        .TopToMidMix = 0.34F,
                        .MidToBotMix = 0.34F,
                        .BotReturnMix = 0.16F,
                        .TopLiftWhiteMul = 0.085F,
                        .TopLiftMidWhiteMul = 0.042F,
                        .BottomDarkBot2Mul = 0.2F,
                        .BottomDarkBot1Mul = 0.28F,
                        .ShineHiWashMix = 0.38F,
                        .ShineMidWashMix = 0.24F,
                        .ShineHiBaseA = 18.0F,
                        .ShineHiMulA = 20.0F,
                        .ShineMidBaseA = 7.0F,
                        .ShineMidMulA = 11.0F
                    }

                Case CommonEnums.SurfaceFamily.Chip

                    Return New AcrylicFamilyRecipe With {
                        .BodyStops = New Single() {0.0F, 0.18F, 0.52F, 0.84F, 1.0F},
                        .ShineStops = New Single() {0.0F, 0.4F, 1.0F},
                        .TopToWashMix = -1.0F,
                        .TopToMidMix = 0.28F,
                        .MidToBotMix = 0.3F,
                        .BotReturnMix = 0.14F,
                        .TopLiftWhiteMul = 0.09F,
                        .TopLiftMidWhiteMul = 0.045F,
                        .BottomDarkBot2Mul = 0.2F,
                        .BottomDarkBot1Mul = 0.28F,
                        .ShineHiWashMix = 0.38F,
                        .ShineMidWashMix = 0.24F,
                        .ShineHiBaseA = 18.0F,
                        .ShineHiMulA = 20.0F,
                        .ShineMidBaseA = 7.0F,
                        .ShineMidMulA = 11.0F
                    }

                Case Else

                    Return New AcrylicFamilyRecipe With {
                        .BodyStops = New Single() {0.0F, 0.14F, 0.48F, 0.82F, 1.0F},
                        .ShineStops = New Single() {0.0F, 0.3F, 1.0F},
                        .TopToWashMix = 0.12F,
                        .TopToMidMix = 0.26F,
                        .MidToBotMix = 0.46F,
                        .BotReturnMix = 0.22F,
                        .TopLiftWhiteMul = 0.09F,
                        .TopLiftMidWhiteMul = 0.045F,
                        .BottomDarkBot2Mul = 0.2F,
                        .BottomDarkBot1Mul = 0.28F,
                        .ShineHiWashMix = 0.38F,
                        .ShineMidWashMix = 0.24F,
                        .ShineHiBaseA = 18.0F,
                        .ShineHiMulA = 20.0F,
                        .ShineMidBaseA = 7.0F,
                        .ShineMidMulA = 11.0F
                    }

            End Select

        End Function

        Private Shared Function ResolveTop1Color(topCol As SKColor,
                                                 midCol As SKColor,
                                                 wash As SKColor,
                                                 intensity As MASVisualEffectIntensityProfiles.AcrylicSurfaceIntensityProfile,
                                                 recipe As AcrylicFamilyRecipe) As SKColor

            Dim c As SKColor

            If recipe.TopToWashMix >= 0.0F Then
                c = ColorMath.Mix(topCol, wash, recipe.TopToWashMix + intensity.TopBandEmphasis * 0.04F)
            Else
                c = ColorMath.Mix(topCol, SKColors.White, 0.06F + intensity.TopBandEmphasis * 0.05F)
            End If

            If intensity.TopBandEmphasis > 0.0F Then
                c = ColorMath.Mix(c, SKColors.White, intensity.TopBandEmphasis * recipe.TopLiftWhiteMul)
            End If

            Return c

        End Function

        Private Shared Function ResolveTop2Color(topCol As SKColor,
                                                 midCol As SKColor,
                                                 intensity As MASVisualEffectIntensityProfiles.AcrylicSurfaceIntensityProfile,
                                                 recipe As AcrylicFamilyRecipe) As SKColor

            Dim c As SKColor =
                ColorMath.Mix(topCol, midCol, recipe.TopToMidMix + intensity.TopBandEmphasis * 0.04F)

            If intensity.TopBandEmphasis > 0.0F Then
                c = ColorMath.Mix(c, SKColors.White, intensity.TopBandEmphasis * recipe.TopLiftMidWhiteMul)
            End If

            Return c

        End Function

        Private Shared Function ResolveBot2Color(midCol As SKColor,
                                                 botCol As SKColor,
                                                 intensity As MASVisualEffectIntensityProfiles.AcrylicSurfaceIntensityProfile,
                                                 recipe As AcrylicFamilyRecipe) As SKColor

            Dim c As SKColor =
                ColorMath.Mix(midCol, botCol, recipe.MidToBotMix + intensity.BottomAnchorStrength * 0.04F)

            If intensity.BottomAnchorStrength > 0.0F Then
                c = ColorMath.Mix(c, ColorMath.TowardBlack(c, 0.16F), intensity.BottomAnchorStrength * recipe.BottomDarkBot2Mul)
            End If

            Return c

        End Function

        Private Shared Function ResolveBot1Color(botCol As SKColor,
                                                 midCol As SKColor,
                                                 intensity As MASVisualEffectIntensityProfiles.AcrylicSurfaceIntensityProfile,
                                                 recipe As AcrylicFamilyRecipe) As SKColor

            Dim c As SKColor

            If recipe.BotReturnMix >= 0.0F Then
                c = ColorMath.Mix(botCol, midCol, recipe.BotReturnMix)
            Else
                c = ColorMath.Mix(botCol, SKColors.Black, 0.06F + intensity.BottomAnchorStrength * 0.04F)
            End If

            If intensity.BottomAnchorStrength > 0.0F Then
                c = ColorMath.Mix(c, ColorMath.TowardBlack(c, 0.2F), intensity.BottomAnchorStrength * recipe.BottomDarkBot1Mul)
            End If

            Return c

        End Function

#End Region

    End Class

End Namespace
