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 MASChartLegend. The legend keeps its
    ''' public size contract in MASSizeResolver; this plan owns internal header, rows,
    ''' footer, value column, and value-bar decisions.
    ''' </summary>
    Friend NotInheritable Class MASChartLegendLayoutPlan
        Friend Shared ReadOnly Thresholds As New MASResponsiveLayoutThresholds(
            fullWidthDip:=ChartLegendTokens.PreferredWidthDip,
            fullHeightDip:=ChartLegendTokens.PreferredHeightDip,
            denseWidthDip:=330.0F,
            denseHeightDip:=230.0F,
            compactWidthDip:=240.0F,
            compactHeightDip:=160.0F,
            minimalWidthDip:=150.0F,
            minimalHeightDip:=96.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 RowHeightPx As Single
        Friend ReadOnly Property RowGapPx As Single
        Friend ReadOnly Property RowPaddingPx As Single
        Friend ReadOnly Property RowRadiusPx As Single
        Friend ReadOnly Property SwatchSizePx As Single
        Friend ReadOnly Property SwatchRadiusPx As Single
        Friend ReadOnly Property ValueWidthPx As Single
        Friend ReadOnly Property MaxVisibleItems As Integer
        Friend ReadOnly Property ShowHeader As Boolean
        Friend ReadOnly Property ShowSummary As Boolean
        Friend ReadOnly Property ShowFooter As Boolean
        Friend ReadOnly Property ShowValues As Boolean
        Friend ReadOnly Property ShowValueBars As Boolean

        Private Sub New(profile As MASResponsiveLayoutProfile,
                        paddingPx As Single,
                        headerHeightPx As Single,
                        footerHeightPx As Single,
                        rowHeightPx As Single,
                        rowGapPx As Single,
                        rowPaddingPx As Single,
                        rowRadiusPx As Single,
                        swatchSizePx As Single,
                        swatchRadiusPx As Single,
                        valueWidthPx As Single,
                        maxVisibleItems As Integer,
                        showHeader As Boolean,
                        showSummary As Boolean,
                        showFooter As Boolean,
                        showValues As Boolean,
                        showValueBars 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.RowHeightPx = Math.Max(24.0F, PositiveOrDefault(rowHeightPx, 24.0F))
            Me.RowGapPx = PositiveOrZero(rowGapPx)
            Me.RowPaddingPx = PositiveOrZero(rowPaddingPx)
            Me.RowRadiusPx = PositiveOrZero(rowRadiusPx)
            Me.SwatchSizePx = Math.Max(8.0F, PositiveOrDefault(swatchSizePx, 8.0F))
            Me.SwatchRadiusPx = PositiveOrZero(swatchRadiusPx)
            Me.ValueWidthPx = PositiveOrZero(valueWidthPx)
            Me.MaxVisibleItems = Math.Max(1, maxVisibleItems)
            Me.ShowHeader = showHeader
            Me.ShowSummary = showSummary
            Me.ShowFooter = showFooter
            Me.ShowValues = showValues
            Me.ShowValueBars = showValueBars
        End Sub

        Friend Shared Function Create(profile As MASResponsiveLayoutProfile) As MASChartLegendLayoutPlan
            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 showHeader As Boolean = safeProfile.Mode <> MASResponsiveLayoutMode.Collapsed
            Dim showFooter As Boolean = safeProfile.Mode = MASResponsiveLayoutMode.Full OrElse safeProfile.Mode = MASResponsiveLayoutMode.Dense
            Dim showSummary As Boolean = safeProfile.Mode = MASResponsiveLayoutMode.Full AndAlso safeProfile.AvailableSizeDip.Width >= 300.0F
            Dim showValues As Boolean = Not safeProfile.IsMinimalOrSmaller AndAlso safeProfile.AvailableSizeDip.Width >= 230.0F
            Dim maxVisible As Integer
            Select Case safeProfile.Mode
                Case MASResponsiveLayoutMode.Full
                    maxVisible = ChartLegendTokens.MaxVisibleItems
                Case MASResponsiveLayoutMode.Dense
                    maxVisible = Math.Min(5, ChartLegendTokens.MaxVisibleItems)
                Case MASResponsiveLayoutMode.Compact
                    maxVisible = 4
                Case Else
                    maxVisible = 3
            End Select

            Return New MASChartLegendLayoutPlan(
                profile:=safeProfile,
                paddingPx:=ChartLegendTokens.PaddingDip * gapDpi,
                headerHeightPx:=If(showHeader, ChartLegendTokens.HeaderHeightDip * chromeDpi, 0.0F),
                footerHeightPx:=If(showFooter, ChartLegendTokens.FooterHeightDip * chromeDpi, 0.0F),
                rowHeightPx:=ChartLegendTokens.RowHeightDip * contentDpi,
                rowGapPx:=ChartLegendTokens.RowGapDip * gapDpi,
                rowPaddingPx:=ChartLegendTokens.RowPaddingDip * gapDpi,
                rowRadiusPx:=ChartLegendTokens.RowRadiusDip * chromeDpi,
                swatchSizePx:=ChartLegendTokens.SwatchSizeDip * chromeDpi,
                swatchRadiusPx:=ChartLegendTokens.SwatchRadiusDip * chromeDpi,
                valueWidthPx:=If(showValues, ChartLegendTokens.ValueWidthDip * contentDpi, 0.0F),
                maxVisibleItems:=maxVisible,
                showHeader:=showHeader,
                showSummary:=showSummary,
                showFooter:=showFooter,
                showValues:=showValues,
                showValueBars:=showValues AndAlso Not safeProfile.IsCompactOrSmaller)
        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
