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>
    ''' Public grid builder used only through MASApplicationLayoutPageBuilder.Grid(...).
    ''' It describes intent and never exposes slots, measure passes, or arrange details.
    ''' </summary>
    Public NotInheritable Class MASApplicationLayoutGridBuilder
        Private ReadOnly _children As New List(Of MASApplicationLayoutControlEntry)()
        Private ReadOnly _columns As Integer
        Private _gap As Single = MASApplicationLayoutSizeTokens.GridGap
        Private _padding As MASLayoutInset = MASLayoutInset.Empty
        Private _groupSizingMode As MASLayoutGroupSizingMode = MASLayoutGroupSizingMode.Intrinsic

        Friend Sub New(columns As Integer)
            _columns = Math.Max(1, columns)
        End Sub

        <Global.System.ComponentModel.EditorBrowsable(Global.System.ComponentModel.EditorBrowsableState.Advanced)>
        Friend Function Gap(value As Single) As MASApplicationLayoutGridBuilder
            _gap = MASApplicationLayoutPageBuilder.SafeNonNegative(value)
            Return Me
        End Function

        Public Function Gap(value As MASLayoutSpacing) As MASApplicationLayoutGridBuilder
            _gap = MASLayoutSpacingResolver.ResolveBase(value)
            Return Me
        End Function

        <Global.System.ComponentModel.EditorBrowsable(Global.System.ComponentModel.EditorBrowsableState.Advanced)>
        Friend Function Spacing(value As Single) As MASApplicationLayoutGridBuilder
            Return Gap(value)
        End Function

        Public Function Spacing(value As MASLayoutSpacing) As MASApplicationLayoutGridBuilder
            Return Gap(value)
        End Function

        <Global.System.ComponentModel.EditorBrowsable(Global.System.ComponentModel.EditorBrowsableState.Advanced)>
        Friend Function Padding(all As Single) As MASApplicationLayoutGridBuilder
            _padding = New MASLayoutInset(all)
            Return Me
        End Function

        Public Function Padding(value As MASLayoutSpacing) As MASApplicationLayoutGridBuilder
            _padding = MASLayoutSpacingResolver.ResolveInsetBase(value)
            Return Me
        End Function

        <Global.System.ComponentModel.EditorBrowsable(Global.System.ComponentModel.EditorBrowsableState.Advanced)>
        Friend Function Padding(left As Single,
                                top As Single,
                                right As Single,
                                bottom As Single) As MASApplicationLayoutGridBuilder
            _padding = New MASLayoutInset(left, top, right, bottom)
            Return Me
        End Function

        ''' <summary>
        ''' Makes every item in this grid use the largest measured item width, without hard-coded pixel widths.
        ''' </summary>
        Public Function EqualItemWidth() As MASApplicationLayoutGridBuilder
            _groupSizingMode = MASLayoutGroupSizingMode.EqualWidth
            Return Me
        End Function

        ''' <summary>
        ''' Makes every item in this grid use the largest measured width and height from the group.
        ''' </summary>
        Public Function EqualItemSize() As MASApplicationLayoutGridBuilder
            _groupSizingMode = MASLayoutGroupSizingMode.EqualSize
            Return Me
        End Function

        ''' <summary>
        ''' Restores per-control intrinsic item sizing for this grid.
        ''' </summary>
        Public Function IntrinsicItemSize() As MASApplicationLayoutGridBuilder
            _groupSizingMode = MASLayoutGroupSizingMode.Intrinsic
            Return Me
        End Function

        Public Function Add(control As MASControlBase,
                            Optional sizeIntent As MASSize = Nothing) As MASApplicationLayoutGridBuilder
            If control IsNot Nothing Then
                _children.Add(New MASApplicationLayoutControlEntry(control, sizeIntent, MASLayoutCrossAlignment.Stretch))
            End If

            Return Me
        End Function

        Friend Function BuildNode(Optional sizeProfile As MASSizeProfile = Nothing) As MASLayoutNode
            Dim profile As MASSizeProfile = MASSizeProfile.Normalize(sizeProfile)
            Dim nodes As New List(Of MASLayoutNode)()
            For Each child As MASApplicationLayoutControlEntry In _children
                nodes.Add(child.BuildNode())
            Next
            Return MASLayoutBuilder.Grid(nodes,
                                         _columns,
                                         MASLayoutSpacingResolver.ScaleLength(_gap, profile),
                                         MASLayoutSpacingResolver.ScaleInset(_padding, profile),
                                         MASLayoutCrossAlignment.Stretch,
                                         _groupSizingMode)
        End Function

        Friend Sub CollectControls(target As IList(Of MASControlBase))
            If target Is Nothing Then Return
            For Each child As MASApplicationLayoutControlEntry In _children
                child.CollectControls(target)
            Next
        End Sub
    End Class

End Namespace
