Option Strict On
Option Explicit On

Imports System
Imports Nexamas.UI.Layout

Namespace Nexamas.UI.Application

    ''' <summary>
    ''' Platform-owned page layout presets for application surfaces that reserve the
    ''' standard MAS TopBar and then arrange content through MASSize/MASLayout.
    ''' External projects choose intent; Nexamas UI owns the actual padding, spacing,
    ''' content width, and active-size-profile scaling.
    ''' </summary>
    Public Enum MASApplicationPageLayoutKind
        Standard = 0
        Dashboard = 1
        DenseData = 2
        Editor = 3
        Surface = 4
    End Enum

    ''' <summary>
    ''' Semantic surface-size presets for application and presentation areas that need
    ''' more vertical room than a single button or input without consumers applying raw
    ''' MASSize.OffsetHeight values locally. Consumers choose semantic intent through
    ''' builders; Nexamas UI owns the numeric metrics through internal policy.
    ''' </summary>
    Friend Enum MASApplicationControlSurfaceSizeKind
        Standard = 0
        SelectionList = 1
        CollectionPair = 2
        TreeSurface = 3
        TileGallery = 4
        DataGrid = 6
        Document = 7
        Inspector = 8
        VisualProof = 9
    End Enum

    ''' <summary>
    ''' Resolved application page layout profile. Values are already resolved for the
    ''' current runtime size profile and may be consumed by lower-level composition code
    ''' that cannot use MASApplicationLayoutPageBuilder directly. This is not public SDK
    ''' state; consumers select page intent through MASApplicationLayoutPageBuilder and
    ''' MASPresentationPage instead of reading resolved padding/width numbers.
    ''' </summary>
    Friend NotInheritable Class MASApplicationPageLayoutProfile
        Friend Sub New(padding As MASLayoutInset,
                       spacing As Single,
                       maxContentWidth As Single,
                       hasMaxContentWidth As Boolean)
            Me.Padding = padding
            Me.Spacing = Math.Max(0.0F, spacing)
            Me.MaxContentWidth = Math.Max(0.0F, maxContentWidth)
            Me.HasMaxContentWidth = hasMaxContentWidth AndAlso Me.MaxContentWidth > 0.0F
        End Sub

        Friend ReadOnly Property Padding As MASLayoutInset
        Friend ReadOnly Property Spacing As Single
        Friend ReadOnly Property MaxContentWidth As Single
        Friend ReadOnly Property HasMaxContentWidth As Boolean
    End Class

    ''' <summary>
    ''' Internal Application layout policy. This is not a second layout system; it
    ''' resolves official MASApplication page presets into MASLayout values so product
    ''' surfaces do not carry local TopBar heights, page padding numbers, or content
    ''' width formulas. External projects use MASApplicationLayoutPageBuilder,
    ''' MASPresentationPage, and MASApplicationWindowShell instead of this resolver.
    ''' </summary>
    Friend NotInheritable Class MASApplicationLayoutPolicy
        Private Sub New()
        End Sub

        Friend Shared Function ResolveStandardTopBarContentTop(shell As MASApplicationWindowShell) As Single
            If shell Is Nothing Then Throw New ArgumentNullException(NameOf(shell))
            Return ResolveStandardTopBarContentTop(MASRuntimeSizeProfileService.Current)
        End Function

        Friend Shared Function ResolveStandardTopBarContentTop(profile As MASSizeProfile) As Single
            Dim safeProfile As MASSizeProfile = MASSizeProfile.Normalize(profile)
            Return MASComponentSizeContractTokens.ResolveApplicationTopBarHeight(safeProfile) + ResolveStandardTopBarContentGap(safeProfile)
        End Function

        Friend Shared Function ResolveStandardApplicationChromeContentTop(shell As MASApplicationWindowShell) As Single
            If shell Is Nothing Then Throw New ArgumentNullException(NameOf(shell))
            Return ResolveStandardApplicationChromeContentTop(MASRuntimeSizeProfileService.Current, shell.HasStandardMenuBar)
        End Function

        Friend Shared Function ResolveStandardApplicationChromeContentTop(profile As MASSizeProfile,
                                                                          hasStandardMenuBar As Boolean) As Single
            Dim safeProfile As MASSizeProfile = MASSizeProfile.Normalize(profile)
            Dim chromeHeight As Single = MASComponentSizeContractTokens.ResolveApplicationTopBarHeight(safeProfile)

            If hasStandardMenuBar Then
                chromeHeight += MASComponentSizeContractTokens.ResolveApplicationMenuBarHeight(safeProfile)
            End If

            Return chromeHeight + ResolveStandardTopBarContentGap(safeProfile)
        End Function

        Friend Shared Function ResolveStandardTopBarContentGap(profile As MASSizeProfile) As Single
            Dim safeProfile As MASSizeProfile = MASSizeProfile.Normalize(profile)
            Return MASLayoutSpacingResolver.Resolve(MASLayoutSpacing.Spacious, safeProfile) + _
                   MASLayoutSpacingResolver.Resolve(MASLayoutSpacing.Tight, safeProfile)
        End Function

        Friend Shared Function ResolveControlSurfaceSize(kind As MASApplicationControlSurfaceSizeKind) As MASSize
            Select Case NormalizeControlSurfaceSizeKind(kind)
                Case MASApplicationControlSurfaceSizeKind.SelectionList
                    Return MASSize.FillWidth.OffsetHeight(MASApplicationLayoutSizeTokens.ControlSurfaceSelectionListHeightOffsetDip)
                Case MASApplicationControlSurfaceSizeKind.CollectionPair
                    Return MASSize.FillWidth.OffsetHeight(MASApplicationLayoutSizeTokens.ControlSurfaceCollectionPairHeightOffsetDip)
                Case MASApplicationControlSurfaceSizeKind.TreeSurface
                    Return MASSize.FillWidth.OffsetHeight(MASApplicationLayoutSizeTokens.ControlSurfaceTreeHeightOffsetDip)
                Case MASApplicationControlSurfaceSizeKind.TileGallery
                    Return MASSize.FillWidth.OffsetHeight(MASApplicationLayoutSizeTokens.ControlSurfaceTileGalleryHeightOffsetDip)
                Case MASApplicationControlSurfaceSizeKind.Document
                    Return MASSize.FillWidth.OffsetHeight(MASApplicationLayoutSizeTokens.ControlSurfaceDocumentHeightOffsetDip)
                Case MASApplicationControlSurfaceSizeKind.Inspector
                    Return MASSize.FillWidth.OffsetHeight(MASApplicationLayoutSizeTokens.ControlSurfaceInspectorHeightOffsetDip)
                Case MASApplicationControlSurfaceSizeKind.VisualProof
                    Return MASSize.FillWidth.OffsetHeight(MASApplicationLayoutSizeTokens.ControlSurfaceVisualProofHeightOffsetDip)
                Case MASApplicationControlSurfaceSizeKind.DataGrid
                    Return MASSize.FillWidth.OffsetHeight(MASApplicationLayoutSizeTokens.ControlSurfaceDataGridHeightOffsetDip)
                Case Else
                    Return MASSize.FillWidth
            End Select
        End Function

        Friend Shared Function ResolvePage(kind As MASApplicationPageLayoutKind,
                                           shell As MASApplicationWindowShell) As MASApplicationPageLayoutProfile
            If shell Is Nothing Then Throw New ArgumentNullException(NameOf(shell))
            Return ResolvePage(kind, ResolveStandardApplicationChromeContentTop(shell), MASRuntimeSizeProfileService.Current)
        End Function

        Friend Shared Function ResolvePage(kind As MASApplicationPageLayoutKind,
                                           contentTopLogical As Single,
                                           profile As MASSizeProfile) As MASApplicationPageLayoutProfile
            Dim safeProfile As MASSizeProfile = MASSizeProfile.Normalize(profile)
            Dim normalizedKind As MASApplicationPageLayoutKind = NormalizeKind(kind)

            Dim horizontal As MASLayoutSpacing = MASLayoutSpacing.Spacious
            Dim topExtra As MASLayoutSpacing = MASLayoutSpacing.Large
            Dim bottom As MASLayoutSpacing = MASLayoutSpacing.Spacious
            Dim spacing As MASLayoutSpacing = MASLayoutSpacing.Large
            Dim maxWidth As Single = 780.0F
            Dim hasMaxWidth As Boolean = True

            Select Case normalizedKind
                Case MASApplicationPageLayoutKind.Dashboard
                    maxWidth = 936.0F
                    topExtra = MASLayoutSpacing.Large
                Case MASApplicationPageLayoutKind.DenseData
                    horizontal = MASLayoutSpacing.Spacious
                    topExtra = MASLayoutSpacing.Medium
                    maxWidth = 1080.0F
                Case MASApplicationPageLayoutKind.Editor
                    horizontal = MASLayoutSpacing.Spacious
                    topExtra = MASLayoutSpacing.Medium
                    maxWidth = 980.0F
                Case MASApplicationPageLayoutKind.Surface
                    horizontal = MASLayoutSpacing.Large
                    topExtra = MASLayoutSpacing.Medium
                    bottom = MASLayoutSpacing.Large
                    spacing = MASLayoutSpacing.Medium
                    maxWidth = 0.0F
                    hasMaxWidth = False
                Case Else
                    maxWidth = 780.0F
            End Select

            Dim leftRight As Single = MASLayoutSpacingResolver.Resolve(horizontal, safeProfile)
            Dim paddingTop As Single = Math.Max(0.0F, contentTopLogical) + MASLayoutSpacingResolver.Resolve(topExtra, safeProfile)
            Dim paddingBottom As Single = MASLayoutSpacingResolver.Resolve(bottom, safeProfile)
            Dim resolvedSpacing As Single = MASLayoutSpacingResolver.Resolve(spacing, safeProfile)
            Dim resolvedMaxWidth As Single = 0.0F
            If hasMaxWidth Then resolvedMaxWidth = MASLayoutSpacingResolver.ScaleWidth(maxWidth, safeProfile)

            Return New MASApplicationPageLayoutProfile(
                padding:=New MASLayoutInset(leftRight, paddingTop, leftRight, paddingBottom),
                spacing:=resolvedSpacing,
                maxContentWidth:=resolvedMaxWidth,
                hasMaxContentWidth:=hasMaxWidth)
        End Function

        Private Shared Function NormalizeControlSurfaceSizeKind(kind As MASApplicationControlSurfaceSizeKind) As MASApplicationControlSurfaceSizeKind
            If [Enum].IsDefined(GetType(MASApplicationControlSurfaceSizeKind), kind) Then Return kind
            Return MASApplicationControlSurfaceSizeKind.Standard
        End Function

        Private Shared Function NormalizeKind(kind As MASApplicationPageLayoutKind) As MASApplicationPageLayoutKind
            If [Enum].IsDefined(GetType(MASApplicationPageLayoutKind), kind) Then Return kind
            Return MASApplicationPageLayoutKind.Standard
        End Function
    End Class

End Namespace
