Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports Nexamas.UI.Controls
Imports Nexamas.UI.Host
Imports Nexamas.UI.Layout
Imports Nexamas.UI.Theming
Imports SkiaSharp

Namespace Nexamas.UI.Application



    ''' <summary>
    ''' Advanced explicit-region layout recipe for direct MAS controls hosted by MASApplicationWindow.Controls.
    ''' Prefer LayoutApplicationSurface, LayoutPage, ActionGroup, FilterBar, FormRow, and Gallery vocabulary for normal screens.
    ''' Use explicit regions only when a product owns a precomputed logical region contract that still must flow through MASLayout.
    ''' </summary>
    <Global.System.ComponentModel.EditorBrowsable(Global.System.ComponentModel.EditorBrowsableState.Advanced)>
    Friend NotInheritable Class MASApplicationLayoutRegionsBuilder
        Private ReadOnly _regions As New List(Of MASApplicationLayoutRegionEntry)()

        <Global.System.ComponentModel.EditorBrowsable(Global.System.ComponentModel.EditorBrowsableState.Advanced)>
        Friend Function Region(boundsLogical As SKRect,
                               buildAction As Action(Of MASApplicationLayoutPageBuilder)) As MASApplicationLayoutRegionsBuilder
            If buildAction Is Nothing Then Throw New ArgumentNullException(NameOf(buildAction))

            Dim safeBounds As SKRect = SanitizeRegionBounds(boundsLogical)
            If safeBounds.IsEmpty OrElse safeBounds.Width <= 0.0F OrElse safeBounds.Height <= 0.0F Then Return Me

            Dim page As New MASApplicationLayoutPageBuilder()
            buildAction.Invoke(page)
            _regions.Add(New MASApplicationLayoutRegionEntry(safeBounds, page))
            Return Me
        End Function

        <Global.System.ComponentModel.EditorBrowsable(Global.System.ComponentModel.EditorBrowsableState.Advanced)>
        Friend Function Region(x As Single,
                               y As Single,
                               width As Single,
                               height As Single,
                               buildAction As Action(Of MASApplicationLayoutPageBuilder)) As MASApplicationLayoutRegionsBuilder
            Return Region(New SKRect(x, y, x + width, y + height), buildAction)
        End Function

        Friend ReadOnly Property Entries As IReadOnlyList(Of MASApplicationLayoutRegionEntry)
            Get
                Return _regions
            End Get
        End Property

        Friend Sub CollectControls(target As IList(Of MASControlBase))
            If target Is Nothing Then Return
            For Each entry As MASApplicationLayoutRegionEntry In _regions
                If entry IsNot Nothing Then entry.CollectControls(target)
            Next
        End Sub

        Private Shared Function SanitizeRegionBounds(bounds As SKRect) As SKRect
            If bounds.IsEmpty Then Return SKRect.Empty
            If Single.IsNaN(bounds.Left) OrElse Single.IsNaN(bounds.Top) OrElse Single.IsNaN(bounds.Right) OrElse Single.IsNaN(bounds.Bottom) Then Return SKRect.Empty
            If Single.IsInfinity(bounds.Left) OrElse Single.IsInfinity(bounds.Top) OrElse Single.IsInfinity(bounds.Right) OrElse Single.IsInfinity(bounds.Bottom) Then Return SKRect.Empty

            Dim left As Single = Math.Min(bounds.Left, bounds.Right)
            Dim top As Single = Math.Min(bounds.Top, bounds.Bottom)
            Dim right As Single = Math.Max(bounds.Left, bounds.Right)
            Dim bottom As Single = Math.Max(bounds.Top, bounds.Bottom)
            If right <= left OrElse bottom <= top Then Return SKRect.Empty
            Return New SKRect(left, top, right, bottom)
        End Function
    End Class

End Namespace
