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

    ''' <summary>
    ''' Provides semantic button surface adaptation rules.
    '''
    ''' Architectural Law:
    ''' - Surface policies may adapt semantic interaction states.
    ''' - They must not erase local component material identity.
    ''' - Visual tuning remains the responsibility of renderers.
    ''' </summary>
    Partial Friend NotInheritable Class ButtonSurfacePolicy

        Private Sub New()
        End Sub

        Friend Structure ButtonSurfaceVisualResult
            Friend MASVisualInteractionState As MASInteractionState
            Friend Surface As MASButtonSurfaceTheme
            Friend Overlay As MASVisualInteractionOverlaySpec
            Friend ShadowRect As SKRect
        End Structure

        Friend Shared Function Resolve(ctx As MASThemeContext,
                                       personality As MASButtonPersonality,
                                       intent As MASButtonIntent,
                                       isDefault As Boolean,
                                       state As MASButtonState,
                                       contract As MASResolvedComponentContract,
                                       isSelected As Boolean,
                                       baseRect As SKRect,
                                       dpi As Single) As ButtonSurfaceVisualResult

            Dim result As ButtonSurfaceVisualResult = CreateFallback(baseRect)

            If ctx Is Nothing OrElse contract Is Nothing Then Return result
            contract.AssertConsumable()

            Dim app As IMASAppTheme = ctx.Theme
            If app Is Nothing Then Return result

            Dim rawVisualState As MASInteractionState =
                MASInteractionResolver.NormalizeState(
                    state.ToMASInteractionState(isSelected))

            Dim visualState As MASInteractionState =
                ButtonPolicyDefaults.DominantState(rawVisualState)

            Dim surface As MASButtonSurfaceTheme =
                ResolveBaseSurface(ctx, app, personality, intent, visualState, isDefault)

            surface =
                ApplyStateSurface(surface, app, personality, intent, visualState)

            result.MASVisualInteractionState = visualState
            result.Surface = surface
            result.Overlay =
                ResolveOverlay(ctx, app, contract, personality, intent, visualState)

            result.ShadowRect =
                ResolveShadowRect(baseRect, personality, visualState, dpi)

            Return result

        End Function

        Private Shared Function ResolveBaseSurface(ctx As MASThemeContext,
                                                   app As IMASAppTheme,
                                                   personality As MASButtonPersonality,
                                                   intent As MASButtonIntent,
                                                   state As MASInteractionState,
                                                   isDefault As Boolean) As MASButtonSurfaceTheme

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

            Dim btnTheme As IMASButtonTheme = ctx.ButtonTheme
            Dim surface As MASButtonSurfaceTheme

            If btnTheme IsNot Nothing Then
                surface = btnTheme.Surface(personality, intent)
            Else
                surface = New MASButtonSurfaceTheme(
                    fillTop:=MASAppThemeContracts.Foundation(app).Surface.SurfaceTop,
                    fillBottom:=MASAppThemeContracts.Foundation(app).Surface.SurfaceMid,
                    borderOuter:=MASAppThemeContracts.Foundation(app).Surface.BorderOuter,
                    borderInner:=MASAppThemeContracts.Foundation(app).Surface.BorderInner,
                    innerHighlight:=MASAppThemeContracts.Foundation(app).TextColors.InverseText.WithAlpha(40),
                    innerShade:=MASAppThemeContracts.Foundation(app).TextColors.PrimaryText.WithAlpha(26),
                    materialWash:=MASAppThemeContracts.Foundation(app).Surface.MaterialWash,
                    bodyGlow:=MASAppThemeContracts.Foundation(app).TextColors.InverseText.WithAlpha(12),
                    topSheen:=MASAppThemeContracts.Foundation(app).TextColors.InverseText.WithAlpha(14))
            End If

            If isDefault Then
                surface = ApplyDefaultAccent(surface, app, personality)
            End If

            Return surface

        End Function


    End Class

End Namespace