Option Strict On
Option Explicit On

Imports System
Imports Nexamas.UI.Theming

Namespace Nexamas.UI.Rendering

    Friend NotInheritable Class MASPanelShellResolvedStyle

        Friend ReadOnly Property SurfaceTheme As MASSurfaceThemeProfile
        Friend ReadOnly Property VisualStyle As MASSurfaceVisualStyle
        Friend ReadOnly Property ResolvedMaterialKey As String
        Friend ReadOnly Property BorderStrengthLevel As Integer
        Friend ReadOnly Property SurfaceStrengthLevel As Integer

        Private Sub New(surfaceTheme As MASSurfaceThemeProfile,
                        visualStyle As MASSurfaceVisualStyle,
                        resolvedMaterialKey As String,
                        borderStrengthLevel As Integer,
                        surfaceStrengthLevel As Integer)

            Me.SurfaceTheme = surfaceTheme
            Me.VisualStyle = visualStyle
            Me.ResolvedMaterialKey = MASSurfaceTreatmentMaterialKeyNormalizer.NormalizeForStorage(resolvedMaterialKey)
            Me.BorderStrengthLevel = ClampStrength(borderStrengthLevel)
            Me.SurfaceStrengthLevel = ClampStrength(surfaceStrengthLevel)
        End Sub

        Friend Shared Function TryCreate(ctx As MASThemeContext,
                                         spec As MASPanelShellSpec,
                                         ByRef style As MASPanelShellResolvedStyle) As Boolean

            style = Nothing

            If ctx Is Nothing OrElse ctx.Theme Is Nothing OrElse spec Is Nothing Then Return False
            If MASAppThemeContracts.Families(ctx.Theme).PanelShell Is Nothing Then Return False

            Dim shellTheme As IMASPanelShellTheme = MASAppThemeContracts.Families(ctx.Theme).PanelShell

            Dim borderValue As Integer =
                If(spec.BorderStrength = MASPanelShellStrength.ThemeDefault,
                   ClampStrength(shellTheme.Chrome.DefaultBorderStrength),
                   CInt(spec.BorderStrength))

            Dim surfaceValue As Integer =
                If(spec.SurfaceStrength = MASPanelShellStrength.ThemeDefault,
                   ClampStrength(shellTheme.Chrome.DefaultSurfaceStrength),
                   CInt(spec.SurfaceStrength))

            Dim visualStyle As MASSurfaceVisualStyle = spec.SurfaceVisualStyle
            If visualStyle Is Nothing Then
                visualStyle = MASSurfaceVisualStyleRegistry.Resolve(spec.SurfaceVisualStyleKey)
            End If

            If visualStyle Is Nothing Then Return False

            Dim resolvedMaterialKey As String = ResolveMaterialKey(spec.SurfaceMaterialKey, visualStyle, borderValue)
            Dim surfaceTheme As MASSurfaceThemeProfile =
                MASSurfaceThemeProfileResolver.Resolve(ctx)

            style = New MASPanelShellResolvedStyle(
                surfaceTheme:=surfaceTheme,
                visualStyle:=visualStyle,
                resolvedMaterialKey:=resolvedMaterialKey,
                borderStrengthLevel:=borderValue,
                surfaceStrengthLevel:=surfaceValue)

            Return True
        End Function

        Private Shared Function ResolveMaterialKey(materialKey As String,
                                                  visualStyle As MASSurfaceVisualStyle,
                                                  borderStrengthLevel As Integer) As String
            Dim key As String = If(materialKey, String.Empty).Trim()
            Dim hasExplicitMaterialOverride As Boolean = key.Length > 0 AndAlso
                                                         Not String.Equals(key, MASSurfaceMaterialIds.Auto, StringComparison.OrdinalIgnoreCase)

            If Not hasExplicitMaterialOverride Then
                If visualStyle IsNot Nothing Then
                    key = visualStyle.SurfaceMaterialKey
                Else
                    key = MASSurfaceMaterialIds.PlatformDefault
                End If
            End If

            Return MASSurfaceMaterialComponentGateway.ResolvePanelShellRuntimeMaterialKey(
                materialKey:=key,
                borderStrengthLevel:=borderStrengthLevel,
                hasExplicitMaterialOverride:=hasExplicitMaterialOverride)
        End Function

        Private Shared Function ToFrameStrength(value As Integer) As MASSurfaceFrameStrength
            Select Case ClampStrength(value)
                Case 1
                    Return MASSurfaceFrameStrength.Level1
                Case 2
                    Return MASSurfaceFrameStrength.Level2
                Case 3
                    Return MASSurfaceFrameStrength.Level3
                Case 4
                    Return MASSurfaceFrameStrength.Level4
                Case 5
                    Return MASSurfaceFrameStrength.Level5
                Case Else
                    Return MASSurfaceFrameStrength.Level6
            End Select
        End Function

        Private Shared Function ClampStrength(value As Integer) As Integer
            If value < 1 Then Return 1
            If value > 6 Then Return 6
            Return value
        End Function

    End Class

End Namespace
