Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic

Namespace Nexamas.UI.Rendering

    ''' <summary>
    ''' Friend-only authoring map used by complex Nexamas UI components to compose one visual
    ''' control from multiple official Surface Materials. This is not public customization API:
    ''' it is for Nexamas UI element authors to route Root/Header/Footer/Toolbar/Viewport
    ''' through the single official Surface Material gateway without hard-coding paints.
    ''' </summary>
    Friend NotInheritable Class MASComponentSurfaceMaterialComposition
        Private ReadOnly _bindings As Dictionary(Of MASComponentSurfaceRegion, MASComponentSurfaceMaterialBinding)

        Private Sub New()
            _bindings = New Dictionary(Of MASComponentSurfaceRegion, MASComponentSurfaceMaterialBinding)()
        End Sub

        Friend Shared Function Create() As MASComponentSurfaceMaterialComposition
            Return New MASComponentSurfaceMaterialComposition()
        End Function

        Friend Function InheritApplication(region As MASComponentSurfaceRegion) As MASComponentSurfaceMaterialComposition
            Dim normalizedRegion As MASComponentSurfaceRegion = NormalizeRegion(region)
            _bindings(normalizedRegion) = MASComponentSurfaceMaterialBinding.InheritApplication(normalizedRegion)
            Return Me
        End Function

        Friend Function UseAuthoredMaterial(region As MASComponentSurfaceRegion,
                                            materialKey As String) As MASComponentSurfaceMaterialComposition
            Dim normalizedRegion As MASComponentSurfaceRegion = NormalizeRegion(region)
            Dim normalizedMaterialKey As String = NormalizeAuthoredMaterialKey(materialKey)

            If normalizedMaterialKey.Length = 0 Then
                _bindings(normalizedRegion) = MASComponentSurfaceMaterialBinding.InheritApplication(normalizedRegion)
            Else
                _bindings(normalizedRegion) = MASComponentSurfaceMaterialBinding.Authored(normalizedRegion, normalizedMaterialKey)
            End If

            Return Me
        End Function

        Friend Function Resolve(region As MASComponentSurfaceRegion,
                                fallbackMaterialKey As String) As MASComponentSurfaceMaterialBinding
            Dim normalizedRegion As MASComponentSurfaceRegion = NormalizeRegion(region)
            Dim binding As MASComponentSurfaceMaterialBinding = Nothing

            If _bindings.TryGetValue(normalizedRegion, binding) AndAlso binding IsNot Nothing Then
                Return binding
            End If

            Return ResolveFallbackBinding(normalizedRegion, fallbackMaterialKey)
        End Function

        Friend Function HasAuthoredMaterial(region As MASComponentSurfaceRegion) As Boolean
            Dim binding As MASComponentSurfaceMaterialBinding = Nothing
            If Not _bindings.TryGetValue(NormalizeRegion(region), binding) OrElse binding Is Nothing Then Return False
            Return binding.IsAuthored
        End Function

        Friend Function HasAnyAuthoredMaterial() As Boolean
            For Each binding As MASComponentSurfaceMaterialBinding In _bindings.Values
                If binding IsNot Nothing AndAlso binding.IsAuthored Then Return True
            Next
            Return False
        End Function


        Private Shared Function NormalizeAuthoredMaterialKey(value As String) As String
            Dim normalized As String = MASSurfaceMaterialRegistry.Canonicalize(
                MASSurfaceTreatmentMaterialKeyNormalizer.NormalizeForStorage(value))

            If MASSurfaceMaterialRuntimeSwitch.IsSwitchableDefaultMaterialKey(normalized) Then Return String.Empty
            If Not MASSurfaceMaterialRegistry.Contains(normalized) Then Return String.Empty

            Return normalized
        End Function

        Private Shared Function ResolveFallbackBinding(region As MASComponentSurfaceRegion,
                                                       fallbackMaterialKey As String) As MASComponentSurfaceMaterialBinding
            Dim normalized As String = MASSurfaceMaterialRegistry.Canonicalize(
                MASSurfaceTreatmentMaterialKeyNormalizer.NormalizeForStorage(fallbackMaterialKey))

            If MASSurfaceMaterialRuntimeSwitch.IsSwitchableDefaultMaterialKey(normalized) OrElse
               Not MASSurfaceMaterialRegistry.Contains(normalized) Then
                Return MASComponentSurfaceMaterialBinding.InheritApplication(region)
            End If

            Return MASComponentSurfaceMaterialBinding.Authored(region, normalized)
        End Function

        Private Shared Function NormalizeRegion(value As MASComponentSurfaceRegion) As MASComponentSurfaceRegion
            If System.Enum.IsDefined(GetType(MASComponentSurfaceRegion), value) Then Return value
            Return MASComponentSurfaceRegion.Root
        End Function

    End Class

End Namespace
