Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports Nexamas.UI.Controls
Imports Nexamas.UI.Layout

Namespace Nexamas.UI.Composition

    ''' <summary>
    ''' Public form-section description for Page.Form recipes.
    ''' A section groups a title, optional description, and official form fields into one layout item.
    ''' It owns no rendering, validation, data binding, input routing, overlay lifecycle, scroll runtime, Theme state, or Host lifecycle.
    ''' </summary>
    <Global.System.ComponentModel.EditorBrowsable(Global.System.ComponentModel.EditorBrowsableState.Advanced)>
    Friend NotInheritable Class MASFormSection

        Friend ReadOnly Property Title As MASControlBase
        Friend ReadOnly Property Description As MASControlBase
        Friend ReadOnly Property Fields As IReadOnlyList(Of MASFormField)
        Friend ReadOnly Property Spacing As Single
        Friend ReadOnly Property Padding As MASLayoutThickness
        Friend ReadOnly Property Margin As MASLayoutThickness
        Friend ReadOnly Property Key As String
        Friend ReadOnly Property UseDefaultVisualPolish As Boolean

        Friend Sub New(title As MASControlBase,
                       fields As IEnumerable(Of MASFormField),
                       Optional description As MASControlBase = Nothing,
                       Optional spacing As Single = MASCompositionSectionSizeTokens.FormSpacing,
                       Optional padding As MASLayoutThickness = Nothing,
                       Optional margin As MASLayoutThickness = Nothing,
                       Optional key As String = "",
                       Optional useDefaultVisualPolish As Boolean = True)

            If title Is Nothing Then Throw New ArgumentNullException(NameOf(title))

            Me.Title = title
            Me.Description = description
            Me.Fields = NormalizeFields(fields)
            Me.Spacing = SafeSpacing(spacing)
            Me.Padding = padding
            Me.Margin = margin
            Me.Key = If(key, String.Empty)
            Me.UseDefaultVisualPolish = useDefaultVisualPolish
        End Sub

        Friend Function ToLayoutItem() As MASLayoutItem
            Dim items As New List(Of MASLayoutItem)()

            items.Add(
                MASComposition.Item(
                    control:=Title,
                    width:=MASSizePolicy.Fill(1.0F),
                    height:=MASSizePolicy.Auto(),
                    alignment:=MASLayoutAlignment.Stretch)
            )

            If Description IsNot Nothing Then
                items.Add(
                    MASComposition.Item(
                        control:=Description,
                        width:=MASSizePolicy.Fill(1.0F),
                        height:=MASSizePolicy.Auto(),
                        alignment:=MASLayoutAlignment.Stretch)
                )
            End If

            For Each field As MASFormField In Fields
                If field IsNot Nothing Then
                    items.Add(field.ToLayoutItem())
                End If
            Next

            Dim sectionNode As IMASLayoutNode =
                MASComposition.Vertical(
                    children:=items.ToArray(),
                    spacing:=Spacing,
                    padding:=ResolveSectionPadding(Padding, UseDefaultVisualPolish),
                    alignment:=MASLayoutAlignment.Stretch)

            Return MASComposition.NodeItem(
                node:=sectionNode,
                width:=MASSizePolicy.Fill(1.0F),
                height:=MASSizePolicy.Auto(),
                alignment:=MASLayoutAlignment.Stretch,
                margin:=ResolveSectionMargin(Margin, UseDefaultVisualPolish),
                key:=Key)
        End Function

        Private Shared Function NormalizeFields(fields As IEnumerable(Of MASFormField)) As IReadOnlyList(Of MASFormField)
            Dim result As New List(Of MASFormField)()

            If fields IsNot Nothing Then
                For Each field As MASFormField In fields
                    If field IsNot Nothing Then
                        result.Add(field)
                    End If
                Next
            End If

            Return result.AsReadOnly()
        End Function


        Private Shared Function ResolveSectionPadding(value As MASLayoutThickness, useDefaultVisualPolish As Boolean) As MASLayoutThickness
            If useDefaultVisualPolish AndAlso MASCompositionSectionSizeTokens.IsEmptyThickness(value) Then
                Return MASCompositionSectionSizeTokens.FormPadding()
            End If

            Return value
        End Function

        Private Shared Function ResolveSectionMargin(value As MASLayoutThickness, useDefaultVisualPolish As Boolean) As MASLayoutThickness
            If useDefaultVisualPolish AndAlso MASCompositionSectionSizeTokens.IsEmptyThickness(value) Then
                Return MASCompositionSectionSizeTokens.FormMargin()
            End If

            Return value
        End Function

        Private Shared Function SafeSpacing(value As Single) As Single
            Return MASCompositionSectionSizeTokens.SafeSpacing(value)
        End Function

    End Class

End Namespace
