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 MASContentCarousel. The carousel keeps
    ''' intrinsic measurement in MASSizeResolver while this plan owns internal header,
    ''' stage, side-card, navigation, and indicator posture for current bounds.
    ''' </summary>
    Friend NotInheritable Class MASContentCarouselLayoutPlan
        Friend Shared ReadOnly Thresholds As New MASResponsiveLayoutThresholds(
            fullWidthDip:=ContentCarouselTokens.PreferredWidthDip,
            fullHeightDip:=ContentCarouselTokens.PreferredHeightDip,
            denseWidthDip:=660.0F,
            denseHeightDip:=320.0F,
            compactWidthDip:=430.0F,
            compactHeightDip:=250.0F,
            minimalWidthDip:=240.0F,
            minimalHeightDip:=160.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 StageGapPx As Single
        Friend ReadOnly Property FooterHeightPx As Single
        Friend ReadOnly Property CardRadiusPx As Single
        Friend ReadOnly Property CardPaddingPx As Single
        Friend ReadOnly Property SideCardScale As Single
        Friend ReadOnly Property SideCardEdgeInsetPx As Single
        Friend ReadOnly Property CenterCardMaxWidthPx As Single
        Friend ReadOnly Property CenterCardMinWidthPx As Single
        Friend ReadOnly Property CenterCardMaxHeightPx As Single
        Friend ReadOnly Property NavButtonSizePx As Single
        Friend ReadOnly Property NavButtonRadiusPx As Single
        Friend ReadOnly Property NavButtonInsetPx As Single
        Friend ReadOnly Property IndicatorSizePx As Single
        Friend ReadOnly Property IndicatorSelectedWidthPx As Single
        Friend ReadOnly Property IndicatorGapPx As Single
        Friend ReadOnly Property MaxVisibleIndicators As Integer
        Friend ReadOnly Property ShowHeader As Boolean
        Friend ReadOnly Property ShowHeaderSummary As Boolean
        Friend ReadOnly Property ShowFooter As Boolean
        Friend ReadOnly Property ShowBoundaryText As Boolean
        Friend ReadOnly Property ShowSideCards As Boolean
        Friend ReadOnly Property ShowNavButtons As Boolean
        Friend ReadOnly Property ShowSubtitle As Boolean
        Friend ReadOnly Property ShowDetail As Boolean

        Private Sub New(profile As MASResponsiveLayoutProfile,
                        contentInsetPx As Single,
                        headerHeightPx As Single,
                        stageGapPx As Single,
                        footerHeightPx As Single,
                        cardRadiusPx As Single,
                        cardPaddingPx As Single,
                        sideCardScale As Single,
                        sideCardEdgeInsetPx As Single,
                        centerCardMaxWidthPx As Single,
                        centerCardMinWidthPx As Single,
                        centerCardMaxHeightPx As Single,
                        navButtonSizePx As Single,
                        navButtonRadiusPx As Single,
                        navButtonInsetPx As Single,
                        indicatorSizePx As Single,
                        indicatorSelectedWidthPx As Single,
                        indicatorGapPx As Single,
                        maxVisibleIndicators As Integer,
                        showHeader As Boolean,
                        showHeaderSummary As Boolean,
                        showFooter As Boolean,
                        showBoundaryText As Boolean,
                        showSideCards As Boolean,
                        showNavButtons As Boolean,
                        showSubtitle As Boolean,
                        showDetail 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.ContentInsetPx = PositiveOrZero(contentInsetPx)
            Me.HeaderHeightPx = PositiveOrZero(headerHeightPx)
            Me.StageGapPx = PositiveOrZero(stageGapPx)
            Me.FooterHeightPx = PositiveOrZero(footerHeightPx)
            Me.CardRadiusPx = PositiveOrZero(cardRadiusPx)
            Me.CardPaddingPx = PositiveOrZero(cardPaddingPx)
            Me.SideCardScale = Math.Min(1.0F, Math.Max(0.35F, PositiveOrDefault(sideCardScale, ContentCarouselTokens.SideCardScale)))
            Me.SideCardEdgeInsetPx = PositiveOrZero(sideCardEdgeInsetPx)
            Me.CenterCardMaxWidthPx = PositiveOrZero(centerCardMaxWidthPx)
            Me.CenterCardMinWidthPx = PositiveOrZero(centerCardMinWidthPx)
            Me.CenterCardMaxHeightPx = PositiveOrZero(centerCardMaxHeightPx)
            Me.NavButtonSizePx = PositiveOrZero(navButtonSizePx)
            Me.NavButtonRadiusPx = PositiveOrZero(navButtonRadiusPx)
            Me.NavButtonInsetPx = PositiveOrZero(navButtonInsetPx)
            Me.IndicatorSizePx = PositiveOrZero(indicatorSizePx)
            Me.IndicatorSelectedWidthPx = PositiveOrZero(indicatorSelectedWidthPx)
            Me.IndicatorGapPx = PositiveOrZero(indicatorGapPx)
            Me.MaxVisibleIndicators = Math.Max(1, maxVisibleIndicators)
            Me.ShowHeader = showHeader
            Me.ShowHeaderSummary = showHeaderSummary
            Me.ShowFooter = showFooter
            Me.ShowBoundaryText = showBoundaryText
            Me.ShowSideCards = showSideCards
            Me.ShowNavButtons = showNavButtons
            Me.ShowSubtitle = showSubtitle
            Me.ShowDetail = showDetail
        End Sub

        Friend Shared Function Create(profile As MASResponsiveLayoutProfile) As MASContentCarouselLayoutPlan
            Dim safeProfile As MASResponsiveLayoutProfile = If(profile, MASResponsiveLayoutResolver.FromLogicalSize(MASSizeLayoutIntegrationContext.Empty, SKSize.Empty, MASSize.Default, Thresholds))
            Dim dpi As Single = 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 showSummary As Boolean = safeProfile.Mode = MASResponsiveLayoutMode.Full OrElse safeProfile.Mode = MASResponsiveLayoutMode.Dense
            Dim showFooter As Boolean = safeProfile.Mode <> MASResponsiveLayoutMode.Collapsed
            Dim showBoundary As Boolean = safeProfile.Mode = MASResponsiveLayoutMode.Full OrElse safeProfile.Mode = MASResponsiveLayoutMode.Dense
            Dim showSideCards As Boolean = safeProfile.Mode = MASResponsiveLayoutMode.Full OrElse safeProfile.Mode = MASResponsiveLayoutMode.Dense
            Dim showNav As Boolean = safeProfile.Mode <> MASResponsiveLayoutMode.Collapsed
            Dim showSubtitle As Boolean = safeProfile.Mode <> MASResponsiveLayoutMode.Collapsed
            Dim showDetail As Boolean = safeProfile.Mode = MASResponsiveLayoutMode.Full OrElse safeProfile.Mode = MASResponsiveLayoutMode.Dense OrElse safeProfile.Mode = MASResponsiveLayoutMode.Compact
            Dim indicators As Integer = If(safeProfile.Mode = MASResponsiveLayoutMode.Full OrElse safeProfile.Mode = MASResponsiveLayoutMode.Dense, 8, 5)

            Return New MASContentCarouselLayoutPlan(
                profile:=safeProfile,
                contentInsetPx:=ContentCarouselTokens.PaddingDip * chromeDpi,
                headerHeightPx:=If(showHeader, ContentCarouselTokens.HeaderHeightDip * chromeDpi, 0.0F),
                stageGapPx:=ContentCarouselTokens.StageGapDip * gapDpi,
                footerHeightPx:=If(showFooter, ContentCarouselTokens.FooterHeightDip * chromeDpi, 0.0F),
                cardRadiusPx:=ContentCarouselTokens.CardRadiusDip * chromeDpi,
                cardPaddingPx:=ContentCarouselTokens.CardPaddingDip * chromeDpi,
                sideCardScale:=If(safeProfile.Mode = MASResponsiveLayoutMode.Dense, 0.7F, ContentCarouselTokens.SideCardScale),
                sideCardEdgeInsetPx:=14.0F * gapDpi,
                centerCardMaxWidthPx:=450.0F * contentDpi,
                centerCardMinWidthPx:=If(showSideCards, 230.0F, 140.0F) * contentDpi,
                centerCardMaxHeightPx:=194.0F * contentDpi,
                navButtonSizePx:=ContentCarouselTokens.NavButtonSizeDip * chromeDpi,
                navButtonRadiusPx:=ContentCarouselTokens.NavButtonRadiusDip * chromeDpi,
                navButtonInsetPx:=14.0F * gapDpi,
                indicatorSizePx:=ContentCarouselTokens.IndicatorSizeDip * chromeDpi,
                indicatorSelectedWidthPx:=ContentCarouselTokens.IndicatorSelectedWidthDip * chromeDpi,
                indicatorGapPx:=ContentCarouselTokens.IndicatorGapDip * gapDpi,
                maxVisibleIndicators:=indicators,
                showHeader:=showHeader,
                showHeaderSummary:=showSummary,
                showFooter:=showFooter,
                showBoundaryText:=showBoundary,
                showSideCards:=showSideCards,
                showNavButtons:=showNav,
                showSubtitle:=showSubtitle,
                showDetail:=showDetail)
        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
