Option Strict On
Option Explicit On

Namespace Nexamas.UI.Values

    Friend NotInheritable Class MASAcrylicEffectTuningProfiles
        Private Sub New()
        End Sub

#Region "Acrylic Tuning"

        Friend Structure AcrylicTuning
            Friend BaseMixT As Single
            Friend CoolBotT As Single
            Friend BorderA As Byte
            Friend RimA As Byte
            Friend GlossA As Byte
            Friend ShadeBotA As Byte
            Friend GrainA As Byte
        End Structure

        Friend Structure FensterFxTuning
            Friend EdgeFadeAlpha As Byte
            Friend EdgeFadeSizeDip As Single
            Friend EdgeFadeTopBoost As Byte
            Friend GrainTileDip As Single
            Friend StrokeDip As Single
        End Structure

        Friend Shared Function ResolveAcrylic(kind As CommonEnums.ControlKind) As AcrylicTuning
            Return ResolveAcrylic(CommonEnums.MapKindToFamily(kind))
        End Function

        Friend Shared Function ResolveAcrylic(family As CommonEnums.SurfaceFamily) As AcrylicTuning
            Select Case family

                Case CommonEnums.SurfaceFamily.PanelShell
                    Return CreateAcrylicTuning(
                        baseMixT:=0.12F,
                        coolBotT:=0.055F,
                        borderA:=54,
                        rimA:=58,
                        glossA:=14,
                        shadeBotA:=10,
                        grainA:=3)

                Case CommonEnums.SurfaceFamily.Fenster
                    Return CreateAcrylicTuning(
                        baseMixT:=0.11F,
                        coolBotT:=0.09F,
                        borderA:=46,
                        rimA:=46,
                        glossA:=14,
                        shadeBotA:=10,
                        grainA:=8)

                Case CommonEnums.SurfaceFamily.DropDown
                    Return CreateAcrylicTuning(
                        baseMixT:=0.16F,
                        coolBotT:=0.04F,
                        borderA:=68,
                        rimA:=86,
                        glossA:=28,
                        shadeBotA:=8,
                        grainA:=2)

                Case CommonEnums.SurfaceFamily.DropDownMenu,
                     CommonEnums.SurfaceFamily.ContextMenu,
                     CommonEnums.SurfaceFamily.Menu

                    Return CreateAcrylicTuning(
                        baseMixT:=0.24F,
                        coolBotT:=0.03F,
                        borderA:=34,
                        rimA:=96,
                        glossA:=18,
                        shadeBotA:=8,
                        grainA:=2)

                Case CommonEnums.SurfaceFamily.ListBox
                    Return CreateAcrylicTuning(
                        baseMixT:=0.09F,
                        coolBotT:=0.04F,
                        borderA:=46,
                        rimA:=52,
                        glossA:=12,
                        shadeBotA:=6,
                        grainA:=3)

                Case CommonEnums.SurfaceFamily.TopBar
                    Return CreateAcrylicTuning(
                        baseMixT:=0.05F,
                        coolBotT:=0.025F,
                        borderA:=24,
                        rimA:=24,
                        glossA:=8,
                        shadeBotA:=8,
                        grainA:=0)

                Case CommonEnums.SurfaceFamily.ButtonMas
                    Return CreateAcrylicTuning(
                        baseMixT:=0.07F,
                        coolBotT:=0.06F,
                        borderA:=52,
                        rimA:=34,
                        glossA:=10,
                        shadeBotA:=14,
                        grainA:=0)

                Case CommonEnums.SurfaceFamily.ButtonTal
                    Return CreateAcrylicTuning(
                        baseMixT:=0.045F,
                        coolBotT:=0.03F,
                        borderA:=36,
                        rimA:=22,
                        glossA:=7,
                        shadeBotA:=10,
                        grainA:=0)

                Case CommonEnums.SurfaceFamily.Input
                    Return CreateAcrylicTuning(
                        baseMixT:=0.025F,
                        coolBotT:=0.0F,
                        borderA:=56,
                        rimA:=24,
                        glossA:=8,
                        shadeBotA:=0,
                        grainA:=0)

                Case CommonEnums.SurfaceFamily.ComboBox
                    Return CreateAcrylicTuning(
                        baseMixT:=0.035F,
                        coolBotT:=0.0F,
                        borderA:=50,
                        rimA:=24,
                        glossA:=7,
                        shadeBotA:=0,
                        grainA:=0)

                Case CommonEnums.SurfaceFamily.ToggleSwitch
                    Return CreateAcrylicTuning(
                        baseMixT:=0.055F,
                        coolBotT:=0.025F,
                        borderA:=44,
                        rimA:=30,
                        glossA:=8,
                        shadeBotA:=6,
                        grainA:=0)

                Case CommonEnums.SurfaceFamily.Card

                    Return CreateAcrylicTuning(
                        baseMixT:=0.1F,
                        coolBotT:=0.05F,
                        borderA:=36,
                        rimA:=42,
                        glossA:=14,
                        shadeBotA:=14,
                        grainA:=0)

                Case CommonEnums.SurfaceFamily.CheckBox
                    Return CreateAcrylicTuning(
                        baseMixT:=0.045F,
                        coolBotT:=0.02F,
                        borderA:=58,
                        rimA:=38,
                        glossA:=8,
                        shadeBotA:=4,
                        grainA:=0)

                Case CommonEnums.SurfaceFamily.Toast
                    Return CreateAcrylicTuning(
                        baseMixT:=0.13F,
                        coolBotT:=0.05F,
                        borderA:=56,
                        rimA:=64,
                        glossA:=16,
                        shadeBotA:=10,
                        grainA:=3)

                Case CommonEnums.SurfaceFamily.Tooltip
                    Return CreateAcrylicTuning(
                        baseMixT:=0.08F,
                        coolBotT:=0.03F,
                        borderA:=42,
                        rimA:=40,
                        glossA:=10,
                        shadeBotA:=8,
                        grainA:=0)

                Case CommonEnums.SurfaceFamily.TabStrip
                    Return CreateAcrylicTuning(
                        baseMixT:=0.075F,
                        coolBotT:=0.045F,
                        borderA:=36,
                        rimA:=34,
                        glossA:=9,
                        shadeBotA:=8,
                        grainA:=0)

                Case CommonEnums.SurfaceFamily.TabItem
                    Return CreateAcrylicTuning(
                        baseMixT:=0.085F,
                        coolBotT:=0.05F,
                        borderA:=40,
                        rimA:=40,
                        glossA:=12,
                        shadeBotA:=10,
                        grainA:=0)

                Case CommonEnums.SurfaceFamily.GroupBox
                    Return CreateAcrylicTuning(
                        baseMixT:=0.085F,
                        coolBotT:=0.045F,
                        borderA:=42,
                        rimA:=46,
                        glossA:=12,
                        shadeBotA:=10,
                        grainA:=2)

                Case CommonEnums.SurfaceFamily.ColorPicker
                    Return CreateAcrylicTuning(
                        baseMixT:=0.095F,
                        coolBotT:=0.045F,
                        borderA:=42,
                        rimA:=46,
                        glossA:=12,
                        shadeBotA:=10,
                        grainA:=2)

                Case CommonEnums.SurfaceFamily.ListSurface,
                     CommonEnums.SurfaceFamily.DataGrid,
                     CommonEnums.SurfaceFamily.Row,
                     CommonEnums.SurfaceFamily.Chip,
                     CommonEnums.SurfaceFamily.SegmentedControl,
                     CommonEnums.SurfaceFamily.ScrollBar,
                     CommonEnums.SurfaceFamily.Tile,
                     CommonEnums.SurfaceFamily.TileBox,
                     CommonEnums.SurfaceFamily.SelectorItem,
                     CommonEnums.SurfaceFamily.ColorPickerPreview,
                     CommonEnums.SurfaceFamily.ColorPickerSVBox,
                     CommonEnums.SurfaceFamily.ColorPickerHueBar,
                     CommonEnums.SurfaceFamily.ColorPickerSlot,
                     CommonEnums.SurfaceFamily.ColorPickerSwatch,
                     CommonEnums.SurfaceFamily.ColorPickerMarker,
                     CommonEnums.SurfaceFamily.GroupBoxTitlePlate

                    Return CreateAcrylicTuning(
                        baseMixT:=0.09F,
                        coolBotT:=0.065F,
                        borderA:=40,
                        rimA:=38,
                        glossA:=10,
                        shadeBotA:=10,
                        grainA:=4)

                Case Else
                    Return DefaultAcrylic()
            End Select
        End Function

        Friend Shared Function ResolveFensterFx(kind As CommonEnums.ControlKind) As FensterFxTuning
            Return ResolveFensterFx(CommonEnums.MapKindToFamily(kind))
        End Function

        Friend Shared Function ResolveFensterFx(family As CommonEnums.SurfaceFamily) As FensterFxTuning
            Select Case family

                Case CommonEnums.SurfaceFamily.PanelShell
                    Return CreateFensterFxTuning(
                edgeFadeAlpha:=26,
                edgeFadeSizeDip:=11.5F,
                edgeFadeTopBoost:=18,
                grainTileDip:=22.0F,
                strokeDip:=SurfaceTokens.FxRingStroke)

                Case CommonEnums.SurfaceFamily.DropDown
                    Return CreateFensterFxTuning(
                edgeFadeAlpha:=34,
                edgeFadeSizeDip:=13.5F,
                edgeFadeTopBoost:=28,
                grainTileDip:=24.0F,
                strokeDip:=SurfaceTokens.FxRingStroke)

                Case CommonEnums.SurfaceFamily.DropDownMenu,
             CommonEnums.SurfaceFamily.ContextMenu,
             CommonEnums.SurfaceFamily.Menu

                    Return CreateFensterFxTuning(
                edgeFadeAlpha:=38,
                edgeFadeSizeDip:=14.5F,
                edgeFadeTopBoost:=32,
                grainTileDip:=26.0F,
                strokeDip:=SurfaceTokens.FxRingStroke)

                Case CommonEnums.SurfaceFamily.ListBox
                    Return CreateFensterFxTuning(
                edgeFadeAlpha:=22,
                edgeFadeSizeDip:=10.5F,
                edgeFadeTopBoost:=14,
                grainTileDip:=23.0F,
                strokeDip:=SurfaceTokens.FxRingStroke)

                Case CommonEnums.SurfaceFamily.Fenster
                    Return CreateFensterFxTuning(
                edgeFadeAlpha:=30,
                edgeFadeSizeDip:=12.5F,
                edgeFadeTopBoost:=24,
                grainTileDip:=22.0F,
                strokeDip:=SurfaceTokens.FxRingStroke)

                Case CommonEnums.SurfaceFamily.Toast
                    Return CreateFensterFxTuning(
                edgeFadeAlpha:=26,
                edgeFadeSizeDip:=11.0F,
                edgeFadeTopBoost:=18,
                grainTileDip:=22.0F,
                strokeDip:=SurfaceTokens.FxRingStroke)

                Case Else
                    Return DefaultFensterFx()
            End Select
        End Function

#End Region

#Region "Factories / Defaults"

        Private Shared Function CreateAcrylicTuning(baseMixT As Single,
                                                    coolBotT As Single,
                                                    borderA As Integer,
                                                    rimA As Integer,
                                                    glossA As Integer,
                                                    shadeBotA As Integer,
                                                    grainA As Integer) As AcrylicTuning

            Return New AcrylicTuning With {
                .BaseMixT = Clamp01(baseMixT),
                .CoolBotT = Clamp01(coolBotT),
                .BorderA = ClampByte(borderA),
                .RimA = ClampByte(rimA),
                .GlossA = ClampByte(glossA),
                .ShadeBotA = ClampByte(shadeBotA),
                .GrainA = ClampByte(grainA)
            }
        End Function

        Private Shared Function CreateFensterFxTuning(edgeFadeAlpha As Integer,
                                                      edgeFadeSizeDip As Single,
                                                      edgeFadeTopBoost As Integer,
                                                      grainTileDip As Single,
                                                      strokeDip As Single) As FensterFxTuning

            Return New FensterFxTuning With {
                .EdgeFadeAlpha = ClampByte(edgeFadeAlpha),
                .EdgeFadeSizeDip = SafeNonNegative(edgeFadeSizeDip),
                .EdgeFadeTopBoost = ClampByte(edgeFadeTopBoost),
                .GrainTileDip = SafeNonNegative(grainTileDip),
               .StrokeDip = SafePositive(strokeDip,
                          SurfaceTokens.FxRingStroke)
}
        End Function

        Private Shared Function DefaultAcrylic() As AcrylicTuning
            Return CreateAcrylicTuning(
                baseMixT:=0.11F,
                coolBotT:=0.09F,
                borderA:=46,
                rimA:=46,
                glossA:=14,
                shadeBotA:=10,
                grainA:=8)
        End Function

        Private Shared Function DefaultFensterFx() As FensterFxTuning
            Return CreateFensterFxTuning(
                edgeFadeAlpha:=30,
                edgeFadeSizeDip:=12.5F,
                edgeFadeTopBoost:=24,
                grainTileDip:=22.0F,
          strokeDip:=SurfaceTokens.FxRingStroke)
        End Function

        Private Shared Function Clamp01(v As Single) As Single
            If Single.IsNaN(v) OrElse Single.IsInfinity(v) Then Return 0.0F
            If v < 0.0F Then Return 0.0F
            If v > 1.0F Then Return 1.0F
            Return v
        End Function

        Private Shared Function ClampByte(v As Integer) As Byte
            If v < 0 Then Return 0
            If v > 255 Then Return 255
            Return CByte(v)
        End Function

        Private Shared Function SafeNonNegative(v As Single) As Single
            If Single.IsNaN(v) OrElse Single.IsInfinity(v) OrElse v < 0.0F Then
                Return 0.0F
            End If

            Return v
        End Function

        Private Shared Function SafePositive(v As Single,
                                             fallback As Single) As Single
            If Single.IsNaN(v) OrElse Single.IsInfinity(v) OrElse v <= 0.0F Then
                Return fallback
            End If

            Return v
        End Function

#End Region

    End Class

End Namespace