Option Strict On
Option Explicit On

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

Namespace Nexamas.UI.Components


    Partial Friend NotInheritable Class ButtonSurfacePolicy
        Private Shared Function ApplyStateSurface(surface As MASButtonSurfaceTheme,
                                                  app As IMASAppTheme,
                                                  personality As MASButtonPersonality,
                                                  intent As MASButtonIntent,
                                                  state As MASInteractionState) As MASButtonSurfaceTheme

            If app Is Nothing Then Return surface
            If state = MASInteractionState.None Then Return surface

            If intent = MASButtonIntent.Danger Then
                Return ApplyDangerStateSurface(surface, app, personality, state)
            End If

            Select Case personality
                Case MASButtonPersonality.Tal
                    Return ApplyTalStateSurface(surface, app, state)

                Case MASButtonPersonality.MAS
                    Return ApplyMasStateSurface(surface, app, state)

                Case Else
                    Return surface
            End Select

        End Function




        Private Shared Function ApplyMasStateSurface(surface As MASButtonSurfaceTheme,
                                                     app As IMASAppTheme,
                                                     state As MASInteractionState) As MASButtonSurfaceTheme

            If MASAppThemeContracts.Foundation(app).TextColors Is Nothing OrElse MASAppThemeContracts.Foundation(app).Semantics Is Nothing OrElse MASAppThemeContracts.Foundation(app).Neutrals Is Nothing Then
                Return surface
            End If

            Dim light As SKColor = MASAppThemeContracts.Foundation(app).TextColors.InverseText
            Dim dark As SKColor = MASAppThemeContracts.Foundation(app).TextColors.PrimaryText
            Dim accent As SKColor = MASAppThemeContracts.Foundation(app).Semantics.Info

            Dim top As SKColor = surface.FillTop
            Dim bottom As SKColor = surface.FillBottom
            Dim outer As SKColor = surface.BorderOuter
            Dim inner As SKColor = surface.BorderInner
            Dim highlight As SKColor = surface.InnerHighlight
            Dim shade As SKColor = surface.InnerShade
            Dim wash As SKColor = surface.MaterialWash
            Dim glow As SKColor = surface.BodyGlow
            Dim sheen As SKColor = surface.TopSheen

            Select Case state

                Case MASInteractionState.Hovered
                    top = ColorMath.Mix(top, light, 0.035F)
                    bottom = ColorMath.Mix(bottom, light, 0.018F)
                    outer = ColorMath.Mix(outer, light, 0.055F).WithAlpha(MaxAlpha(outer.Alpha, 150))
                    inner = ColorMath.Mix(inner, light, 0.04F).WithAlpha(MaxAlpha(inner.Alpha, 120))
                    highlight = ColorMath.Mix(highlight, light, 0.1F).WithAlpha(MaxAlpha(highlight.Alpha, 82))
                    shade = shade.WithAlpha(ScaleAlpha(shade.Alpha, 0.88F))
                    wash = ColorMath.Mix(wash, light, 0.16F).WithAlpha(MaxAlpha(wash.Alpha, 44))
                    glow = ColorMath.Mix(glow, light, 0.28F).WithAlpha(MaxAlpha(glow.Alpha, 46))
                    sheen = ColorMath.Mix(sheen, light, 0.18F).WithAlpha(MaxAlpha(sheen.Alpha, 52))

                Case MASInteractionState.Pressed
                    top = ColorMath.Mix(top, dark, 0.08F)
                    bottom = ColorMath.Mix(bottom, dark, 0.14F)
                    outer = ColorMath.Mix(outer, dark, 0.11F).WithAlpha(MaxAlpha(outer.Alpha, 170))
                    inner = ColorMath.Mix(inner, dark, 0.06F).WithAlpha(MaxAlpha(inner.Alpha, 118))
                    highlight = highlight.WithAlpha(ScaleAlpha(highlight.Alpha, 0.72F))
                    shade = ColorMath.Mix(shade, dark, 0.2F).WithAlpha(MaxAlpha(shade.Alpha, 82))
                    wash = ColorMath.Mix(wash, dark, 0.12F).WithAlpha(MaxAlpha(wash.Alpha, 36))
                    glow = glow.WithAlpha(ScaleAlpha(glow.Alpha, 0.7F))
                    sheen = sheen.WithAlpha(ScaleAlpha(sheen.Alpha, 0.62F))

                Case MASInteractionState.Selected
                    top = ColorMath.Mix(top, accent, 0.055F)
                    bottom = ColorMath.Mix(bottom, accent, 0.08F)
                    outer = ColorMath.Mix(outer, accent, 0.16F).WithAlpha(MaxAlpha(outer.Alpha, 176))
                    inner = ColorMath.Mix(inner, light, 0.07F).WithAlpha(MaxAlpha(inner.Alpha, 128))
                    highlight = highlight.WithAlpha(MaxAlpha(highlight.Alpha, 86))
                    wash = ColorMath.Mix(wash, accent, 0.18F).WithAlpha(MaxAlpha(wash.Alpha, 52))
                    glow = ColorMath.Mix(glow, light, 0.16F).WithAlpha(MaxAlpha(glow.Alpha, 42))
                    sheen = sheen.WithAlpha(MaxAlpha(sheen.Alpha, 48))

                Case MASInteractionState.Focused
                    outer = ColorMath.Mix(outer, MASAppThemeContracts.Foundation(app).Semantics.FocusStrong, 0.18F).WithAlpha(MaxAlpha(outer.Alpha, 174))
                    inner = ColorMath.Mix(inner, light, 0.045F).WithAlpha(MaxAlpha(inner.Alpha, 118))
                    glow = ColorMath.Mix(glow, MASAppThemeContracts.Foundation(app).Semantics.FocusStrong, 0.12F).WithAlpha(MaxAlpha(glow.Alpha, 34))
                    sheen = sheen.WithAlpha(MaxAlpha(sheen.Alpha, 34))

                Case MASInteractionState.Disabled
                    top = ColorMath.Mix(top, MASAppThemeContracts.Foundation(app).Neutrals.Surface2, 0.28F)
                    bottom = ColorMath.Mix(bottom, MASAppThemeContracts.Foundation(app).Neutrals.Surface2, 0.34F)
                    outer = ColorMath.Mix(outer, MASAppThemeContracts.Foundation(app).Semantics.Disabled, 0.32F).WithAlpha(118)
                    inner = inner.WithAlpha(105)
                    highlight = highlight.WithAlpha(52)
                    shade = shade.WithAlpha(34)
                    wash = wash.WithAlpha(28)
                    glow = glow.WithAlpha(18)
                    sheen = sheen.WithAlpha(24)

            End Select

            Return New MASButtonSurfaceTheme(
                fillTop:=top,
                fillBottom:=bottom,
                borderOuter:=outer,
                borderInner:=inner,
                innerHighlight:=highlight,
                innerShade:=shade,
                materialWash:=wash,
                bodyGlow:=glow,
                topSheen:=sheen)

        End Function




        Private Shared Function ApplyTalStateSurface(surface As MASButtonSurfaceTheme,
                                                     app As IMASAppTheme,
                                                     state As MASInteractionState) As MASButtonSurfaceTheme

            If MASAppThemeContracts.Foundation(app).TextColors Is Nothing OrElse MASAppThemeContracts.Foundation(app).Semantics Is Nothing OrElse MASAppThemeContracts.Foundation(app).Neutrals Is Nothing Then
                Return surface
            End If

            Dim light As SKColor = MASAppThemeContracts.Foundation(app).TextColors.InverseText
            Dim dark As SKColor = MASAppThemeContracts.Foundation(app).TextColors.PrimaryText
            Dim accent As SKColor = MASAppThemeContracts.Foundation(app).Semantics.Info

            Dim top As SKColor = surface.FillTop
            Dim bottom As SKColor = surface.FillBottom
            Dim outer As SKColor = surface.BorderOuter
            Dim inner As SKColor = surface.BorderInner
            Dim highlight As SKColor = surface.InnerHighlight
            Dim shade As SKColor = surface.InnerShade
            Dim wash As SKColor = surface.MaterialWash
            Dim glow As SKColor = surface.BodyGlow
            Dim sheen As SKColor = surface.TopSheen

            Select Case state

                Case MASInteractionState.Hovered
                    top = ColorMath.Mix(top, light, 0.16F)
                    bottom = ColorMath.Mix(bottom, light, 0.05F)
                    outer = outer.WithAlpha(212)
                    inner = ColorMath.Mix(inner, light, 0.16F).WithAlpha(218)
                    highlight = ColorMath.Mix(highlight, light, 0.18F).WithAlpha(150)
                    shade = ColorMath.Mix(shade, dark, 0.02F).WithAlpha(54)
                    wash = ColorMath.Mix(wash, accent, 0.18F).WithAlpha(42)
                    glow = ColorMath.Mix(glow, light, 0.24F).WithAlpha(52)
                    sheen = ColorMath.Mix(sheen, light, 0.2F).WithAlpha(72)

                Case MASInteractionState.Pressed
                    top = ColorMath.Mix(top, dark, 0.16F)
                    bottom = ColorMath.Mix(bottom, dark, 0.28F)
                    outer = ColorMath.Mix(outer, dark, 0.26F).WithAlpha(245)
                    inner = ColorMath.Mix(inner, dark, 0.1F).WithAlpha(145)
                    highlight = highlight.WithAlpha(64)
                    shade = ColorMath.Mix(shade, dark, 0.32F).WithAlpha(128)
                    wash = ColorMath.Mix(wash, dark, 0.18F).WithAlpha(34)
                    glow = glow.WithAlpha(12)
                    sheen = sheen.WithAlpha(18)

                Case MASInteractionState.Selected
                    top = ColorMath.Mix(top, accent, 0.16F)
                    bottom = ColorMath.Mix(bottom, accent, 0.22F)
                    outer = ColorMath.Mix(outer, accent, 0.34F).WithAlpha(242)
                    inner = ColorMath.Mix(inner, light, 0.2F).WithAlpha(215)
                    highlight = highlight.WithAlpha(142)
                    wash = ColorMath.Mix(wash, accent, 0.32F).WithAlpha(68)
                    glow = ColorMath.Mix(glow, light, 0.26F).WithAlpha(60)
                    sheen = sheen.WithAlpha(74)

                Case MASInteractionState.Focused
                    top = ColorMath.Mix(top, light, 0.025F)
                    bottom = ColorMath.Mix(bottom, light, 0.01F)
                    outer = ColorMath.Mix(outer, MASAppThemeContracts.Foundation(app).Semantics.FocusStrong, 0.14F).WithAlpha(190)
                    inner = ColorMath.Mix(inner, light, 0.06F).WithAlpha(155)
                    highlight = highlight.WithAlpha(92)
                    glow = ColorMath.Mix(glow, MASAppThemeContracts.Foundation(app).Semantics.FocusStrong, 0.06F).WithAlpha(28)
                    sheen = sheen.WithAlpha(30)

                Case MASInteractionState.Disabled
                    top = ColorMath.Mix(top, MASAppThemeContracts.Foundation(app).Neutrals.Surface2, 0.28F)
                    bottom = ColorMath.Mix(bottom, MASAppThemeContracts.Foundation(app).Neutrals.Surface2, 0.34F)
                    outer = ColorMath.Mix(outer, MASAppThemeContracts.Foundation(app).Semantics.Disabled, 0.32F).WithAlpha(118)
                    inner = inner.WithAlpha(105)
                    highlight = highlight.WithAlpha(52)
                    shade = shade.WithAlpha(34)
                    wash = wash.WithAlpha(28)
                    glow = glow.WithAlpha(18)
                    sheen = sheen.WithAlpha(24)

            End Select

            Return New MASButtonSurfaceTheme(
                fillTop:=top,
                fillBottom:=bottom,
                borderOuter:=outer,
                borderInner:=inner,
                innerHighlight:=highlight,
                innerShade:=shade,
                materialWash:=wash,
                bodyGlow:=glow,
                topSheen:=sheen)

        End Function



        Private Shared Function ApplyDefaultAccent(surface As MASButtonSurfaceTheme,
                                                   app As IMASAppTheme,
                                                   personality As MASButtonPersonality) As MASButtonSurfaceTheme

            If MASAppThemeContracts.Foundation(app).Semantics Is Nothing Then Return surface

            Dim accent As SKColor = MASAppThemeContracts.Foundation(app).Semantics.Info
            If accent.Alpha = 0 Then Return surface

            Dim outerMix As Single = If(personality = MASButtonPersonality.Tal, 0.08F, 0.12F)
            Dim innerMix As Single = If(personality = MASButtonPersonality.Tal, 0.05F, 0.08F)
            Dim washMix As Single = If(personality = MASButtonPersonality.Tal, 0.015F, 0.02F)

            Return New MASButtonSurfaceTheme(
                fillTop:=surface.FillTop,
                fillBottom:=surface.FillBottom,
                borderOuter:=ColorMath.Mix(surface.BorderOuter, accent, outerMix),
                borderInner:=ColorMath.Mix(surface.BorderInner, accent, innerMix),
                innerHighlight:=surface.InnerHighlight,
                innerShade:=surface.InnerShade,
                materialWash:=ColorMath.Mix(surface.MaterialWash, accent, washMix),
                bodyGlow:=surface.BodyGlow,
                topSheen:=surface.TopSheen)

        End Function

    End Class

End Namespace
