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 MASTreeGrid. The public intrinsic
    ''' size contract remains in MASSizeResolver; this plan translates the current
    ''' runtime size profile and available bounds into inner grid chrome decisions.
    ''' </summary>
    Friend NotInheritable Class MASTreeGridLayoutPlan
        Friend Shared ReadOnly Thresholds As New MASResponsiveLayoutThresholds(
            fullWidthDip:=TreeGridTokens.PreferredWidthDip,
            fullHeightDip:=TreeGridTokens.PreferredHeightDip,
            denseWidthDip:=720.0F,
            denseHeightDip:=380.0F,
            compactWidthDip:=460.0F,
            compactHeightDip:=260.0F,
            minimalWidthDip:=260.0F,
            minimalHeightDip:=170.0F)

        Friend ReadOnly Property ResponsiveProfile As MASResponsiveLayoutProfile
        Friend ReadOnly Property Mode As MASResponsiveLayoutMode
        Friend ReadOnly Property Dpi As Single
        Friend ReadOnly Property ContentInsetPx As Single
        Friend ReadOnly Property HeaderHeightPx As Single
        Friend ReadOnly Property HeaderGapPx As Single
        Friend ReadOnly Property FooterHeightPx As Single
        Friend ReadOnly Property FooterGapPx As Single
        Friend ReadOnly Property GridHeaderHeightPx As Single
        Friend ReadOnly Property GridInnerInsetPx As Single
        Friend ReadOnly Property RowHeightPx As Single
        Friend ReadOnly Property RowGapPx As Single
        Friend ReadOnly Property SummaryWidthPx As Single
        Friend ReadOnly Property MaxVisibleRows As Integer
        Friend ReadOnly Property MaxVisibleValueColumns As Integer
        Friend ReadOnly Property ShowHeader As Boolean
        Friend ReadOnly Property ShowHeaderSummary As Boolean
        Friend ReadOnly Property ShowFooter As Boolean

        Private Sub New(profile As MASResponsiveLayoutProfile,
                        dpi As Single,
                        contentInsetPx As Single,
                        headerHeightPx As Single,
                        headerGapPx As Single,
                        footerHeightPx As Single,
                        footerGapPx As Single,
                        gridHeaderHeightPx As Single,
                        gridInnerInsetPx As Single,
                        rowHeightPx As Single,
                        rowGapPx As Single,
                        summaryWidthPx As Single,
                        maxVisibleRows As Integer,
                        maxVisibleValueColumns As Integer,
                        showHeader As Boolean,
                        showHeaderSummary As Boolean,
                        showFooter 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(dpi, safeProfile.DpiScale))
            Me.ContentInsetPx = PositiveOrZero(contentInsetPx)
            Me.HeaderHeightPx = PositiveOrZero(headerHeightPx)
            Me.HeaderGapPx = PositiveOrZero(headerGapPx)
            Me.FooterHeightPx = PositiveOrZero(footerHeightPx)
            Me.FooterGapPx = PositiveOrZero(footerGapPx)
            Me.GridHeaderHeightPx = PositiveOrZero(gridHeaderHeightPx)
            Me.GridInnerInsetPx = PositiveOrZero(gridInnerInsetPx)
            Me.RowHeightPx = Math.Max(12.0F, PositiveOrDefault(rowHeightPx, 12.0F))
            Me.RowGapPx = PositiveOrZero(rowGapPx)
            Me.SummaryWidthPx = PositiveOrZero(summaryWidthPx)
            Me.MaxVisibleRows = Math.Max(1, maxVisibleRows)
            Me.MaxVisibleValueColumns = Math.Max(1, maxVisibleValueColumns)
            Me.ShowHeader = showHeader
            Me.ShowHeaderSummary = showHeaderSummary
            Me.ShowFooter = showFooter
        End Sub

        Friend Shared Function Create(profile As MASResponsiveLayoutProfile) As MASTreeGridLayoutPlan
            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 * safeProfile.ChromeScale)
            Dim gapDpi As Single = Math.Max(0.64F, safeProfile.DpiScale * safeProfile.GapScale)
            Dim contentDpi As Single = Math.Max(0.64F, safeProfile.DpiScale * safeProfile.ContentScale)

            Dim showHeader As Boolean = safeProfile.Mode <> MASResponsiveLayoutMode.Collapsed
            Dim showFooter As Boolean = safeProfile.Mode = MASResponsiveLayoutMode.Full OrElse safeProfile.Mode = MASResponsiveLayoutMode.Dense OrElse safeProfile.Mode = MASResponsiveLayoutMode.Compact
            Dim showSummary As Boolean = safeProfile.Mode = MASResponsiveLayoutMode.Full OrElse safeProfile.Mode = MASResponsiveLayoutMode.Dense

            Dim maxRows As Integer
            Dim maxColumns As Integer
            Select Case safeProfile.Mode
                Case MASResponsiveLayoutMode.Full
                    maxRows = TreeGridTokens.MaxVisibleRows
                    maxColumns = TreeGridTokens.MaxVisibleValueColumns
                Case MASResponsiveLayoutMode.Dense
                    maxRows = Math.Min(8, TreeGridTokens.MaxVisibleRows)
                    maxColumns = Math.Min(3, TreeGridTokens.MaxVisibleValueColumns)
                Case MASResponsiveLayoutMode.Compact
                    maxRows = Math.Min(6, TreeGridTokens.MaxVisibleRows)
                    maxColumns = Math.Min(2, TreeGridTokens.MaxVisibleValueColumns)
                Case Else
                    maxRows = Math.Min(4, TreeGridTokens.MaxVisibleRows)
                    maxColumns = 1
            End Select

            Return New MASTreeGridLayoutPlan(
                profile:=safeProfile,
                dpi:=dpi,
                contentInsetPx:=TreeGridTokens.PaddingDip * dpi,
                headerHeightPx:=If(showHeader, TreeGridTokens.HeaderHeightDip * dpi, 0.0F),
                headerGapPx:=If(showHeader, 10.0F * gapDpi, 0.0F),
                footerHeightPx:=If(showFooter, TreeGridTokens.FooterHeightDip * dpi, 0.0F),
                footerGapPx:=If(showFooter, 8.0F * gapDpi, 0.0F),
                gridHeaderHeightPx:=TreeGridTokens.GridHeaderHeightDip * dpi,
                gridInnerInsetPx:=6.0F * gapDpi,
                rowHeightPx:=TreeGridTokens.RowHeightDip * contentDpi,
                rowGapPx:=TreeGridTokens.RowGapDip * gapDpi,
                summaryWidthPx:=280.0F * dpi,
                maxVisibleRows:=maxRows,
                maxVisibleValueColumns:=maxColumns,
                showHeader:=showHeader,
                showHeaderSummary:=showSummary,
                showFooter:=showFooter)
        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
