Option Strict On
Option Explicit On

Imports System
Imports Nexamas.UI.Rendering

Namespace Nexamas.UI.Components

    ''' <summary>
    ''' Single ImageViewer surface policy. The ImageViewer consumes one official slot profile
    ''' and maps semantic regions to independent Surface Material bindings. Rendering code must
    ''' ask this policy instead of hard-coding broad material ids inside the control.
    ''' </summary>
    Friend NotInheritable Class MASImageViewerSurfacePolicy
        Private Sub New()
        End Sub

        Friend Const DefaultProfileId As String = MASSurfaceMaterialProfileIds.MediaSurface

        Friend Shared Function CreateComposition() As MASComponentSurfaceMaterialComposition
            Return CreateComposition(DefaultProfileId)
        End Function

        Friend Shared Function CreateComposition(profileId As String) As MASComponentSurfaceMaterialComposition
            Return MASComponentSurfaceMaterialComposition.Create().
                UseAuthoredMaterial(MASComponentSurfaceRegion.Root, ResolveMaterialKey(profileId, MASComponentSurfaceRegion.Root, ResolveFallbackMaterialKey(MASComponentSurfaceRegion.Root))).
                UseAuthoredMaterial(MASComponentSurfaceRegion.Toolbar, ResolveMaterialKey(profileId, MASComponentSurfaceRegion.Toolbar, ResolveFallbackMaterialKey(MASComponentSurfaceRegion.Toolbar))).
                UseAuthoredMaterial(MASComponentSurfaceRegion.Viewport, ResolveMaterialKey(profileId, MASComponentSurfaceRegion.Viewport, ResolveFallbackMaterialKey(MASComponentSurfaceRegion.Viewport))).
                UseAuthoredMaterial(MASComponentSurfaceRegion.Footer, ResolveMaterialKey(profileId, MASComponentSurfaceRegion.Footer, ResolveFallbackMaterialKey(MASComponentSurfaceRegion.Footer))).
                UseAuthoredMaterial(MASComponentSurfaceRegion.Overlay, ResolveMaterialKey(profileId, MASComponentSurfaceRegion.Overlay, ResolveFallbackMaterialKey(MASComponentSurfaceRegion.Overlay)))
        End Function

        Friend Shared Function ResolveRootMaterialKey() As String
            Return ResolveMaterialKey(DefaultProfileId, MASComponentSurfaceRegion.Root, MASSurfaceMaterialIds.PlatformDefault)
        End Function

        Friend Shared Function ResolveFallbackMaterialKey(region As MASComponentSurfaceRegion) As String
            Select Case NormalizeRegion(region)
                Case MASComponentSurfaceRegion.Toolbar
                    Return MASSurfaceMaterialIds.MediaCommandRail
                Case MASComponentSurfaceRegion.Viewport
                    Return MASSurfaceMaterialIds.FrostedGlass
                Case MASComponentSurfaceRegion.Footer
                    Return MASSurfaceMaterialIds.MediaFooterChrome
                Case MASComponentSurfaceRegion.Overlay, MASComponentSurfaceRegion.Floating
                    Return MASSurfaceMaterialIds.MediaToolbarGlass
                Case Else
                    Return MASSurfaceMaterialIds.PlatformDefault
            End Select
        End Function

        Friend Shared Function ResolveSurfaceStrengthLevel(region As MASComponentSurfaceRegion,
                                                           fallbackLevel As Integer) As Integer
            Dim assignment As MASSurfaceMaterialSlotAssignment = ResolveAssignment(DefaultProfileId, NormalizeRegion(region))
            If assignment IsNot Nothing Then Return assignment.SurfaceStrengthLevel
            Return ClampStrength(fallbackLevel)
        End Function

        Friend Shared Function ResolveFrameStrength(region As MASComponentSurfaceRegion,
                                                     fallbackStrength As MASSurfaceFrameStrength) As MASSurfaceFrameStrength
            Dim assignment As MASSurfaceMaterialSlotAssignment = ResolveAssignment(DefaultProfileId, NormalizeRegion(region))
            If assignment IsNot Nothing Then Return assignment.FrameStrength
            If System.Enum.IsDefined(GetType(MASSurfaceFrameStrength), fallbackStrength) Then Return fallbackStrength
            Return MASSurfaceFrameStrength.Level3
        End Function

        Friend Shared Function ResolveBorderStrengthLevel(region As MASComponentSurfaceRegion,
                                                          fallbackLevel As Integer) As Integer
            Return ClampStrength(fallbackLevel)
        End Function

        Private Shared Function ResolveMaterialKey(profileId As String,
                                                   region As MASComponentSurfaceRegion,
                                                   fallbackMaterialKey As String) As String
            Dim assignment As MASSurfaceMaterialSlotAssignment = ResolveAssignment(profileId, NormalizeRegion(region))
            If assignment IsNot Nothing AndAlso Not String.IsNullOrWhiteSpace(assignment.MaterialKey) Then
                Return assignment.MaterialKey
            End If

            Dim fallbackKey As String = If(fallbackMaterialKey, String.Empty).Trim()
            If fallbackKey.Length = 0 Then Return MASSurfaceMaterialIds.PlatformDefault
            Return fallbackKey
        End Function

        Private Shared Function ResolveAssignment(profileId As String,
                                                  region As MASComponentSurfaceRegion) As MASSurfaceMaterialSlotAssignment
            Dim profile As MASSurfaceMaterialSlotProfile = MASSurfaceMaterialSlotProfileRegistry.Resolve(profileId)
            If profile Is Nothing Then Return Nothing

            Dim slot As MASSurfaceSlot = ToSurfaceSlot(region)
            For Each assignment As MASSurfaceMaterialSlotAssignment In profile.Assignments()
                If assignment IsNot Nothing AndAlso assignment.Slot = slot Then Return assignment
            Next

            Return Nothing
        End Function

        Private Shared Function ToSurfaceSlot(region As MASComponentSurfaceRegion) As MASSurfaceSlot
            Select Case NormalizeRegion(region)
                Case MASComponentSurfaceRegion.Toolbar
                    Return MASSurfaceSlot.Toolbar
                Case MASComponentSurfaceRegion.Viewport
                    Return MASSurfaceSlot.Viewport
                Case MASComponentSurfaceRegion.Footer
                    Return MASSurfaceSlot.Footer
                Case MASComponentSurfaceRegion.Overlay
                    Return MASSurfaceSlot.Overlay
                Case MASComponentSurfaceRegion.Floating
                    Return MASSurfaceSlot.Floating
                Case Else
                    Return MASSurfaceSlot.Root
            End Select
        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

        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
