Option Strict On
Option Explicit On

Imports System
Imports Nexamas.UI.Layout
Imports Nexamas.UI.Values
Imports SkiaSharp

Namespace Nexamas.UI.Components

    ''' <summary>
    ''' Render-only responsive layout facts for MASNavigationRail. It keeps the public
    ''' size contract in MASSizeResolver while adapting rail chrome, label/badge
    ''' visibility, row density, and item hit rectangles to runtime size profile.
    ''' </summary>
    Friend NotInheritable Class MASNavigationRailLayoutPlan
        Friend Shared ReadOnly Thresholds As New MASResponsiveLayoutThresholds(
            fullWidthDip:=NavigationRailTokens.PreferredWidthDip,
            fullHeightDip:=NavigationRailTokens.PreferredHeightDip,
            denseWidthDip:=210.0F,
            denseHeightDip:=420.0F,
            compactWidthDip:=120.0F,
            compactHeightDip:=260.0F,
            minimalWidthDip:=72.0F,
            minimalHeightDip:=150.0F)

        Friend ReadOnly Property ResponsiveProfile As MASResponsiveLayoutProfile
        Friend ReadOnly Property Mode As MASResponsiveLayoutMode
        Friend ReadOnly Property Dpi As Single
        Friend ReadOnly Property PaddingPx As Single
        Friend ReadOnly Property HeaderHeightPx As Single
        Friend ReadOnly Property FooterHeightPx As Single
        Friend ReadOnly Property ItemHeightPx As Single
        Friend ReadOnly Property ItemGapPx As Single
        Friend ReadOnly Property ItemRadiusPx As Single
        Friend ReadOnly Property ItemPaddingPx As Single
        Friend ReadOnly Property GlyphBoxSizePx As Single
        Friend ReadOnly Property GlyphRadiusPx As Single
        Friend ReadOnly Property BadgeMinWidthPx As Single
        Friend ReadOnly Property BadgeHeightPx As Single
        Friend ReadOnly Property BadgeRadiusPx As Single
        Friend ReadOnly Property SelectedRailWidthPx As Single
        Friend ReadOnly Property MaxVisibleItems As Integer
        Friend ReadOnly Property ShowHeader As Boolean
        Friend ReadOnly Property ShowFooter As Boolean
        Friend ReadOnly Property ShowLabels As Boolean
        Friend ReadOnly Property ShowBadges As Boolean
        Friend ReadOnly Property ShowBoundaryText As Boolean

        Private Sub New(profile As MASResponsiveLayoutProfile,
                        paddingPx As Single,
                        headerHeightPx As Single,
                        footerHeightPx As Single,
                        itemHeightPx As Single,
                        itemGapPx As Single,
                        itemRadiusPx As Single,
                        itemPaddingPx As Single,
                        glyphBoxSizePx As Single,
                        glyphRadiusPx As Single,
                        badgeMinWidthPx As Single,
                        badgeHeightPx As Single,
                        badgeRadiusPx As Single,
                        selectedRailWidthPx As Single,
                        maxVisibleItems As Integer,
                        showHeader As Boolean,
                        showFooter As Boolean,
                        showLabels As Boolean,
                        showBadges As Boolean,
                        showBoundaryText As Boolean)
            Dim safeProfile As MASResponsiveLayoutProfile = If(profile, MASResponsiveLayoutResolver.FromLogicalSize(MASSizeLayoutIntegrationContext.Empty, SKSize.Empty, MASSize.Default, Thresholds))
            Me.ResponsiveProfile = safeProfile
            Me.Mode = safeProfile.Mode
            Me.Dpi = Math.Max(0.64F, PositiveOrDefault(safeProfile.DpiScale, 1.0F))
            Me.PaddingPx = PositiveOrZero(paddingPx)
            Me.HeaderHeightPx = PositiveOrZero(headerHeightPx)
            Me.FooterHeightPx = PositiveOrZero(footerHeightPx)
            Me.ItemHeightPx = Math.Max(28.0F, PositiveOrDefault(itemHeightPx, 28.0F))
            Me.ItemGapPx = PositiveOrZero(itemGapPx)
            Me.ItemRadiusPx = PositiveOrZero(itemRadiusPx)
            Me.ItemPaddingPx = PositiveOrZero(itemPaddingPx)
            Me.GlyphBoxSizePx = Math.Max(20.0F, PositiveOrDefault(glyphBoxSizePx, 20.0F))
            Me.GlyphRadiusPx = PositiveOrZero(glyphRadiusPx)
            Me.BadgeMinWidthPx = PositiveOrZero(badgeMinWidthPx)
            Me.BadgeHeightPx = PositiveOrZero(badgeHeightPx)
            Me.BadgeRadiusPx = PositiveOrZero(badgeRadiusPx)
            Me.SelectedRailWidthPx = PositiveOrZero(selectedRailWidthPx)
            Me.MaxVisibleItems = Math.Max(1, maxVisibleItems)
            Me.ShowHeader = showHeader
            Me.ShowFooter = showFooter
            Me.ShowLabels = showLabels
            Me.ShowBadges = showBadges
            Me.ShowBoundaryText = showBoundaryText
        End Sub

        Friend Shared Function Create(profile As MASResponsiveLayoutProfile,
                                      isExplicitCompact As Boolean) As MASNavigationRailLayoutPlan
            Dim safeProfile As MASResponsiveLayoutProfile = If(profile, MASResponsiveLayoutResolver.FromLogicalSize(MASSizeLayoutIntegrationContext.Empty, SKSize.Empty, MASSize.Default, Thresholds))
            Dim dpi As Single = Math.Max(0.64F, safeProfile.DpiScale)
            Dim chromeDpi As Single = Math.Max(0.64F, dpi * safeProfile.ChromeScale)
            Dim gapDpi As Single = Math.Max(0.64F, dpi * safeProfile.GapScale)
            Dim contentDpi As Single = Math.Max(0.64F, dpi * safeProfile.ContentScale)
            Dim compact As Boolean = isExplicitCompact OrElse safeProfile.AvailableSizeDip.Width <= NavigationRailTokens.CompactWidthDip OrElse safeProfile.IsCompactOrSmaller
            Dim showHeader As Boolean = Not compact AndAlso safeProfile.Mode <> MASResponsiveLayoutMode.Collapsed
            Dim showFooter As Boolean = Not compact AndAlso (safeProfile.Mode = MASResponsiveLayoutMode.Full OrElse safeProfile.Mode = MASResponsiveLayoutMode.Dense)

            Return New MASNavigationRailLayoutPlan(
                profile:=safeProfile,
                paddingPx:=NavigationRailTokens.PaddingDip * gapDpi,
                headerHeightPx:=If(showHeader, NavigationRailTokens.HeaderHeightDip * chromeDpi, 0.0F),
                footerHeightPx:=If(showFooter, NavigationRailTokens.FooterHeightDip * chromeDpi, 0.0F),
                itemHeightPx:=NavigationRailTokens.ItemHeightDip * contentDpi,
                itemGapPx:=NavigationRailTokens.ItemGapDip * gapDpi,
                itemRadiusPx:=NavigationRailTokens.ItemRadiusDip * chromeDpi,
                itemPaddingPx:=NavigationRailTokens.ItemPaddingDip * gapDpi,
                glyphBoxSizePx:=NavigationRailTokens.GlyphBoxSizeDip * chromeDpi,
                glyphRadiusPx:=NavigationRailTokens.GlyphRadiusDip * chromeDpi,
                badgeMinWidthPx:=NavigationRailTokens.BadgeMinWidthDip * chromeDpi,
                badgeHeightPx:=NavigationRailTokens.BadgeHeightDip * chromeDpi,
                badgeRadiusPx:=NavigationRailTokens.BadgeRadiusDip * chromeDpi,
                selectedRailWidthPx:=NavigationRailTokens.SelectedRailWidthDip * chromeDpi,
                maxVisibleItems:=If(safeProfile.IsCompactOrSmaller, Math.Min(7, NavigationRailTokens.MaxVisibleItems), NavigationRailTokens.MaxVisibleItems),
                showHeader:=showHeader,
                showFooter:=showFooter,
                showLabels:=Not compact AndAlso safeProfile.AvailableSizeDip.Width >= 150.0F,
                showBadges:=Not compact AndAlso safeProfile.AvailableSizeDip.Width >= 190.0F,
                showBoundaryText:=showHeader AndAlso safeProfile.Mode = MASResponsiveLayoutMode.Full)
        End Function

        Private Shared Function PositiveOrDefault(value As Single, fallback As Single) As Single
            If Single.IsNaN(value) OrElse Single.IsInfinity(value) OrElse value <= 0.0F Then Return fallback
            Return value
        End Function

        Private Shared Function PositiveOrZero(value As Single) As Single
            If Single.IsNaN(value) OrElse Single.IsInfinity(value) OrElse value < 0.0F Then Return 0.0F
            Return value
        End Function
    End Class

End Namespace
