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 ResolveOverlay(ctx As MASThemeContext,
                                               app As IMASAppTheme,
                                               contract As MASResolvedComponentContract,
                                               personality As MASButtonPersonality,
                                               intent As MASButtonIntent,
                                               state As MASInteractionState) As MASVisualInteractionOverlaySpec

            If state = MASInteractionState.None Then Return ButtonPolicyDefaults.EmptyOverlaySpec()
            If app Is Nothing Then Return ButtonPolicyDefaults.EmptyOverlaySpec()
            If contract Is Nothing Then Return ButtonPolicyDefaults.EmptyOverlaySpec()

            contract.AssertConsumable()

            Dim spec As MASVisualInteractionOverlaySpec =
                MASInteractionResolver.Build(
                    contract:=contract,
                    state:=state,
                    theme:=app,
                    intent:=If(intent = MASButtonIntent.Danger,
                               MASVisualInteractionIntent.Danger,
                               MASVisualInteractionIntent.Normal))

            Dim interactionTheme As MASButtonInteractionTheme =
                ResolveInteractionTheme(ctx, personality, intent)

            spec = ApplyThemeOverlayColors(spec, interactionTheme, intent, state)

            If intent = MASButtonIntent.Danger Then
                Return ApplyDangerOverlay(spec, app, state)
            End If

            Select Case personality
                Case MASButtonPersonality.MAS
                    Return ApplyMasOverlay(spec, app, state)

                Case MASButtonPersonality.Tal
                    Return ApplyTalOverlay(spec, app, state)

                Case Else
                    Return spec
            End Select

        End Function




        Private Shared Function ApplyThemeOverlayColors(spec As MASVisualInteractionOverlaySpec,
                                                        interactionTheme As MASButtonInteractionTheme,
                                                        intent As MASButtonIntent,
                                                        state As MASInteractionState) As MASVisualInteractionOverlaySpec

            If interactionTheme Is Nothing Then Return spec

            Select Case state

                Case MASInteractionState.Hovered
                    If intent = MASButtonIntent.Danger Then
                        spec.Fill = RecolorPreserveAlpha(spec.Fill, interactionTheme.DangerHoverFill)
                        spec.Ring = RecolorPreserveAlpha(spec.Ring, interactionTheme.DangerHoverRing)
                    Else
                        spec.Fill = RecolorPreserveAlpha(spec.Fill, interactionTheme.HoverFill)
                        spec.Ring = RecolorPreserveAlpha(spec.Ring, interactionTheme.HoverRing)
                    End If

                Case MASInteractionState.Pressed
                    If intent = MASButtonIntent.Danger Then
                        spec.Fill = RecolorPreserveAlpha(spec.Fill, interactionTheme.DangerPressedFill)
                        spec.Ring = RecolorPreserveAlpha(spec.Ring, interactionTheme.DangerPressedRing)
                    Else
                        spec.Fill = RecolorPreserveAlpha(spec.Fill, interactionTheme.PressedFill)
                        spec.Ring = RecolorPreserveAlpha(spec.Ring, interactionTheme.PressedRing)
                    End If

                Case MASInteractionState.Selected
                    If intent = MASButtonIntent.Danger Then
                        spec.Fill = RecolorPreserveAlpha(spec.Fill, interactionTheme.DangerSelectedFill)
                        spec.Ring = RecolorPreserveAlpha(spec.Ring, interactionTheme.DangerSelectedRing)
                    Else
                        spec.Fill = RecolorPreserveAlpha(spec.Fill, interactionTheme.SelectedFill)
                        spec.Ring = RecolorPreserveAlpha(spec.Ring, interactionTheme.SelectedRing)
                    End If

                Case MASInteractionState.Focused
                    If intent = MASButtonIntent.Danger Then
                        spec.Fill = RecolorPreserveAlpha(spec.Fill, interactionTheme.DangerFocusedFill)
                        spec.Ring = RecolorPreserveAlpha(spec.Ring, interactionTheme.DangerFocusedRing)
                    Else
                        spec.Fill = RecolorPreserveAlpha(spec.Fill, interactionTheme.FocusedFill)
                        spec.Ring = RecolorPreserveAlpha(spec.Ring, interactionTheme.FocusedRing)
                    End If

                Case MASInteractionState.Disabled
                    spec.Fill = RecolorPreserveAlpha(spec.Fill, interactionTheme.DisabledFill)
                    spec.Ring = SKColors.Transparent

            End Select

            Return spec

        End Function




        Private Shared Function ApplyMasOverlay(spec As MASVisualInteractionOverlaySpec,
                                                app As IMASAppTheme,
                                                state As MASInteractionState) As MASVisualInteractionOverlaySpec

            Select Case state

                Case MASInteractionState.Hovered
                    spec.FillEnabled = True
                    spec.Fill = spec.Fill.WithAlpha(42)
                    spec.RingEnabled = True
                    spec.Ring = spec.Ring.WithAlpha(54)
                    spec.FillBlendMode = SKBlendMode.SrcOver

                Case MASInteractionState.Pressed
                    spec.FillEnabled = True
                    spec.Fill = spec.Fill.WithAlpha(42)
                    spec.RingEnabled = True
                    spec.Ring = spec.Ring.WithAlpha(46)
                    spec.FillBlendMode = SKBlendMode.Multiply

                Case MASInteractionState.Selected
                    spec.FillEnabled = True
                    spec.Fill = spec.Fill.WithAlpha(38)
                    spec.RingEnabled = True
                    spec.Ring = spec.Ring.WithAlpha(52)
                    spec.FillBlendMode = SKBlendMode.Screen

                Case MASInteractionState.Focused
                    spec.FillEnabled = False
                    spec.Fill = SKColors.Transparent
                    spec.RingEnabled = True
                    spec.Ring = spec.Ring.WithAlpha(72)
                    spec.FillBlendMode = SKBlendMode.SrcOver

                Case MASInteractionState.Disabled
                    spec.FillEnabled = True
                    spec.Fill = spec.Fill.WithAlpha(14)
                    spec.RingEnabled = False
                    spec.Ring = SKColors.Transparent
                    spec.FillBlendMode = SKBlendMode.SrcOver

            End Select

            Return spec

        End Function




        Private Shared Function ApplyTalOverlay(spec As MASVisualInteractionOverlaySpec,
                                                app As IMASAppTheme,
                                                state As MASInteractionState) As MASVisualInteractionOverlaySpec

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

            Select Case state

                Case MASInteractionState.Hovered
                    spec.FillEnabled = True
                    spec.Fill = MASAppThemeContracts.Foundation(app).TextColors.InverseText.WithAlpha(10)
                    spec.RingEnabled = False
                    spec.Ring = SKColors.Transparent
                    spec.FillBlendMode = SKBlendMode.Screen

                Case MASInteractionState.Focused
                    spec.FillEnabled = False
                    spec.Fill = SKColors.Transparent
                    spec.RingEnabled = True
                    spec.Ring = MASAppThemeContracts.Foundation(app).Semantics.FocusStrong.WithAlpha(62)
                    spec.FillBlendMode = SKBlendMode.SrcOver

            End Select

            Return spec

        End Function




        Private Shared Function ApplyDangerOverlay(spec As MASVisualInteractionOverlaySpec,
                                                   app As IMASAppTheme,
                                                   state As MASInteractionState) As MASVisualInteractionOverlaySpec

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

            Select Case state

                Case MASInteractionState.Hovered
                    spec.FillEnabled = True
                    spec.Fill = MASAppThemeContracts.Foundation(app).TextColors.InverseText.WithAlpha(18)
                    spec.RingEnabled = True
                    spec.Ring = MASAppThemeContracts.Foundation(app).Semantics.Danger.WithAlpha(86)
                    spec.FillBlendMode = SKBlendMode.Screen

                Case MASInteractionState.Pressed
                    spec.FillEnabled = True
                    spec.Fill = MASAppThemeContracts.Foundation(app).TextColors.PrimaryText.WithAlpha(34)
                    spec.RingEnabled = True
                    spec.Ring = MASAppThemeContracts.Foundation(app).TextColors.PrimaryText.WithAlpha(72)
                    spec.FillBlendMode = SKBlendMode.Multiply

                Case MASInteractionState.Selected
                    spec.FillEnabled = True
                    spec.Fill = MASAppThemeContracts.Foundation(app).TextColors.InverseText.WithAlpha(18)
                    spec.RingEnabled = True
                    spec.Ring = MASAppThemeContracts.Foundation(app).Semantics.Danger.WithAlpha(104)
                    spec.FillBlendMode = SKBlendMode.Screen

                Case MASInteractionState.Focused
                    spec.FillEnabled = False
                    spec.Fill = SKColors.Transparent
                    spec.RingEnabled = True
                    spec.Ring = MASAppThemeContracts.Foundation(app).Semantics.FocusStrong.WithAlpha(98)
                    spec.FillBlendMode = SKBlendMode.SrcOver

            End Select

            Return spec

        End Function

    End Class

End Namespace
