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>
    ' Form and editor page recipe family for the MASPage public facade.
    ' </summary>
    Partial Friend NotInheritable Class MASPage

        ''' <summary>
        ''' Creates a simple form page from explicit field items.
        ''' Phase 1 treats a form as a vertical layout recipe; it is not a designer, validator, or data-binding engine.
        ''' </summary>
        Public Shared Function Form(fields As IEnumerable(Of MASLayoutItem),
                                    Optional title As MASControlBase = Nothing,
                                    Optional description As MASControlBase = Nothing,
                                    Optional submitArea As MASControlBase = Nothing,
                                    Optional spacing As Single = DEFAULT_FORM_SPACING,
                                    Optional padding As MASLayoutThickness = Nothing,
                                    Optional titleHeight As MASSizePolicy = Nothing,
                                    Optional descriptionHeight As MASSizePolicy = Nothing,
                                    Optional submitAreaWidth As MASSizePolicy = Nothing,
                                    Optional submitAreaHeight As MASSizePolicy = Nothing,
                                    Optional maxContentWidth As Single = MASCompositionPageSizeTokens.FormMaxContentWidth,
                                    Optional scrollEnabled As Boolean = False,
                                    Optional scrollKey As String = "",
                                    Optional useDefaultVisualPolish As Boolean = True) As IMASLayoutNode

            Dim formItems As New List(Of MASLayoutItem)()

            If title IsNot Nothing Then
                formItems.Add(
                    MASComposition.Item(
                        control:=title,
                        width:=MASSizePolicy.Fill(1.0F),
                        height:=If(titleHeight, MASSizePolicy.Auto()),
                        alignment:=MASLayoutAlignment.Stretch,
                        margin:=ResolveFormTitleMargin(useDefaultVisualPolish)
                    )
                )
            End If

            If description IsNot Nothing Then
                formItems.Add(
                    MASComposition.Item(
                        control:=description,
                        width:=MASSizePolicy.Fill(1.0F),
                        height:=If(descriptionHeight, MASSizePolicy.Auto()),
                        alignment:=MASLayoutAlignment.Stretch,
                        margin:=ResolveFormDescriptionMargin(useDefaultVisualPolish)
                    )
                )
            End If

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

            If submitArea IsNot Nothing Then
                formItems.Add(
                    MASComposition.Item(
                        control:=submitArea,
                        width:=If(submitAreaWidth, MASSizePolicy.Auto()),
                        height:=If(submitAreaHeight, MASSizePolicy.Auto()),
                        alignment:=MASLayoutAlignment.End,
                        margin:=ResolveFormActionsMargin(useDefaultVisualPolish)
                    )
                )
            End If

            Dim formNode As IMASLayoutNode =
                MASComposition.Vertical(
                    children:=formItems.ToArray(),
                    spacing:=SafeSpacing(spacing),
                    padding:=ResolveFormPadding(padding, useDefaultVisualPolish),
                    alignment:=MASLayoutAlignment.Stretch)

            If scrollEnabled Then
                Return New MASVerticalScrollLayoutNode(
                    content:=formNode,
                    scrollKey:=If(scrollKey, String.Empty),
                    maxContentWidth:=maxContentWidth)
            End If

            Return WrapMaxContentWidth(formNode, maxContentWidth)
        End Function

        ''' <summary>
        ''' Creates a form page from official form field rows.
        ''' This recipe builds Label + Field rows using Horizontal layout; TextInput remains owned by its own control system.
        ''' </summary>
        Public Shared Function Form(fields As IEnumerable(Of MASFormField),
                                    Optional title As MASControlBase = Nothing,
                                    Optional description As MASControlBase = Nothing,
                                    Optional submitArea As MASControlBase = Nothing,
                                    Optional spacing As Single = DEFAULT_FORM_SPACING,
                                    Optional padding As MASLayoutThickness = Nothing,
                                    Optional titleHeight As MASSizePolicy = Nothing,
                                    Optional descriptionHeight As MASSizePolicy = Nothing,
                                    Optional submitAreaWidth As MASSizePolicy = Nothing,
                                    Optional submitAreaHeight As MASSizePolicy = Nothing,
                                    Optional maxContentWidth As Single = MASCompositionPageSizeTokens.FormMaxContentWidth,
                                    Optional scrollEnabled As Boolean = False,
                                    Optional scrollKey As String = "",
                                    Optional useDefaultVisualPolish As Boolean = True) As IMASLayoutNode

            Dim items As New List(Of MASLayoutItem)()

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

            Return Form(
                fields:=items.ToArray(),
                title:=title,
                description:=description,
                submitArea:=submitArea,
                spacing:=spacing,
                padding:=padding,
                titleHeight:=titleHeight,
                descriptionHeight:=descriptionHeight,
                submitAreaWidth:=submitAreaWidth,
                submitAreaHeight:=submitAreaHeight,
                maxContentWidth:=maxContentWidth,
                scrollEnabled:=scrollEnabled,
                scrollKey:=scrollKey,
                useDefaultVisualPolish:=useDefaultVisualPolish)
        End Function

        ''' <summary>
        ''' Creates a form page from official form sections and an optional composed actions row.
        ''' This is a Page/Form recipe only; it does not render, validate, bind data, or own input/overlay/scroll systems.
        ''' </summary>
        Public Shared Function Form(sections As IEnumerable(Of MASFormSection),
                                    Optional title As MASControlBase = Nothing,
                                    Optional description As MASControlBase = Nothing,
                                    Optional actions As IMASLayoutNode = Nothing,
                                    Optional spacing As Single = DEFAULT_FORM_SPACING,
                                    Optional padding As MASLayoutThickness = Nothing,
                                    Optional titleHeight As MASSizePolicy = Nothing,
                                    Optional descriptionHeight As MASSizePolicy = Nothing,
                                    Optional actionsWidth As MASSizePolicy = Nothing,
                                    Optional actionsHeight As MASSizePolicy = Nothing,
                                    Optional maxContentWidth As Single = MASCompositionPageSizeTokens.FormMaxContentWidth,
                                    Optional scrollEnabled As Boolean = False,
                                    Optional scrollKey As String = "",
                                    Optional useDefaultVisualPolish As Boolean = True) As IMASLayoutNode

            Return BuildSectionTemplatePage(Of MASFormSection)(
                sections:=sections,
                sectionToItem:=Function(section As MASFormSection) section.ToLayoutItem(),
                title:=title,
                description:=description,
                actions:=actions,
                spacing:=spacing,
                padding:=padding,
                titleHeight:=titleHeight,
                descriptionHeight:=descriptionHeight,
                actionsWidth:=actionsWidth,
                actionsHeight:=actionsHeight,
                maxContentWidth:=maxContentWidth,
                scrollEnabled:=scrollEnabled,
                scrollKey:=scrollKey,
                useDefaultVisualPolish:=useDefaultVisualPolish,
                paddingResolver:=AddressOf ResolveFormPadding)
        End Function

        ''' <summary>
        ''' Creates an official form section from existing label controls and fields.
        ''' </summary>
        Public Shared Function Section(title As MASControlBase,
                                       fields As IEnumerable(Of MASFormField),
                                       Optional description As MASControlBase = Nothing,
                                       Optional spacing As Single = DEFAULT_FORM_SECTION_SPACING,
                                       Optional padding As MASLayoutThickness = Nothing,
                                       Optional margin As MASLayoutThickness = Nothing,
                                       Optional key As String = "",
                                       Optional useDefaultVisualPolish As Boolean = True) As MASFormSection

            Return New MASFormSection(
                title:=title,
                fields:=fields,
                description:=description,
                spacing:=spacing,
                padding:=padding,
                margin:=margin,
                key:=key,
                useDefaultVisualPolish:=useDefaultVisualPolish)
        End Function

        ''' <summary>
        ''' Creates an official form section from title/description text.
        ''' The generated labels are normal MASLabel controls and keep rendering responsibility inside Core controls.
        ''' </summary>
        Public Shared Function Section(titleText As String,
                                       fields As IEnumerable(Of MASFormField),
                                       Optional descriptionText As String = "",
                                       Optional spacing As Single = DEFAULT_FORM_SECTION_SPACING,
                                       Optional padding As MASLayoutThickness = Nothing,
                                       Optional margin As MASLayoutThickness = Nothing,
                                       Optional key As String = "",
                                       Optional useDefaultVisualPolish As Boolean = True) As MASFormSection

            Dim titleLabel As MASLabel = MASPageLabelRecipeFactory.CreateSectionTitle(titleText)
            Dim descriptionLabel As MASLabel = Nothing

            If Not String.IsNullOrWhiteSpace(descriptionText) Then
                descriptionLabel = MASPageLabelRecipeFactory.CreateSectionDescription(descriptionText)
            End If

            Return Section(
                title:=titleLabel,
                fields:=fields,
                description:=descriptionLabel,
                spacing:=spacing,
                padding:=padding,
                margin:=margin,
                key:=key,
                useDefaultVisualPolish:=useDefaultVisualPolish)
        End Function

        ''' <summary>
        ''' Creates an official Label + Field row specification for Page.Form.
        ''' Phase 2 defaults to Auto height through the central control measurer unless an explicit policy is passed.
        ''' </summary>
        Public Shared Function Field(labelControl As MASControlBase,
                             fieldControl As MASControlBase,
                             Optional labelWidth As MASSizePolicy = Nothing,
                             Optional fieldWidth As MASSizePolicy = Nothing,
                             Optional fieldHeight As MASSizePolicy = Nothing,
                             Optional rowHeight As MASSizePolicy = Nothing,
                             Optional spacing As Single = DEFAULT_FORM_FIELD_SPACING,
                             Optional margin As MASLayoutThickness = Nothing,
                             Optional key As String = "") As MASFormField

            Return New MASFormField(
        label:=labelControl,
        field:=fieldControl,
        labelWidth:=labelWidth,
        fieldWidth:=fieldWidth,
        fieldHeight:=fieldHeight,
        rowHeight:=rowHeight,
        spacing:=spacing,
        margin:=margin,
        key:=key)

        End Function

        ''' <summary>
        ''' Creates an official Label + Field row specification from label text.
        ''' Prefer the MASControlBase overload when the label instance must be reused across rebuilds.
        ''' </summary>
        Public Shared Function Field(labelText As String,
                             fieldControl As MASControlBase,
                             Optional labelWidth As MASSizePolicy = Nothing,
                             Optional fieldWidth As MASSizePolicy = Nothing,
                             Optional fieldHeight As MASSizePolicy = Nothing,
                             Optional rowHeight As MASSizePolicy = Nothing,
                             Optional spacing As Single = DEFAULT_FORM_FIELD_SPACING,
                             Optional margin As MASLayoutThickness = Nothing,
                             Optional key As String = "") As MASFormField

            Dim labelControl As MASLabel = MASPageLabelRecipeFactory.CreateFormFieldLabel(labelText)

            Return Field(
        labelControl:=labelControl,
        fieldControl:=fieldControl,
        labelWidth:=labelWidth,
        fieldWidth:=fieldWidth,
        fieldHeight:=fieldHeight,
        rowHeight:=rowHeight,
        spacing:=spacing,
        margin:=margin,
        key:=key)

        End Function

        Public Shared Function Item(control As MASControlBase,
                            Optional height As MASSizePolicy = Nothing,
                            Optional width As MASSizePolicy = Nothing,
                            Optional margin As MASLayoutThickness = Nothing,
                            Optional key As String = "") As MASLayoutItem

            Return MASComposition.Item(
        control:=control,
        width:=If(width, MASSizePolicy.Fill(1.0F)),
        height:=If(height, MASSizePolicy.Auto()),
        alignment:=MASLayoutAlignment.Stretch,
        margin:=margin,
        key:=key
    )

        End Function
        ''' <summary>
        ''' Creates a horizontal actions row for form/page actions such as Cancel + Save.
        ''' It returns a composed layout node, not a control, so it can contain multiple buttons without giving Layout rendering ownership.
        ''' </summary>
        Public Shared Function ActionsRow(primary As MASControlBase,
                                          Optional secondary As MASControlBase = Nothing,
                                          Optional spacing As Single = DEFAULT_FORM_ACTIONS_SPACING,
                                          Optional padding As MASLayoutThickness = Nothing,
                                          Optional key As String = "",
                                          Optional useDefaultVisualPolish As Boolean = True) As IMASLayoutNode

            Dim controls As New List(Of MASControlBase)()

            If secondary IsNot Nothing Then
                controls.Add(secondary)
            End If

            If primary IsNot Nothing Then
                controls.Add(primary)
            End If

            Return ActionsRow(
                controls:=controls.ToArray(),
                spacing:=spacing,
                padding:=padding,
                key:=key,
                useDefaultVisualPolish:=useDefaultVisualPolish)
        End Function

        ''' <summary>
        ''' Creates a horizontal actions row from an ordered list of action controls.
        ''' </summary>
        Public Shared Function ActionsRow(controls As IEnumerable(Of MASControlBase),
                                          Optional spacing As Single = DEFAULT_FORM_ACTIONS_SPACING,
                                          Optional padding As MASLayoutThickness = Nothing,
                                          Optional key As String = "",
                                          Optional useDefaultVisualPolish As Boolean = True) As IMASLayoutNode

            Dim items As New List(Of MASLayoutItem)()

            If controls IsNot Nothing Then
                Dim index As Integer = 0

                For Each control As MASControlBase In controls
                    If control IsNot Nothing Then
                        Dim itemKey As String = If(String.IsNullOrEmpty(key), String.Empty, key & "." & index.ToString(System.Globalization.CultureInfo.InvariantCulture))

                        items.Add(
                            MASComposition.Item(
                                control:=control,
                                width:=MASSizePolicy.Auto(),
                                height:=MASSizePolicy.Auto(),
                                alignment:=MASLayoutAlignment.Center,
                                key:=itemKey)
                        )

                        index += 1
                    End If
                Next
            End If

            Return MASComposition.Horizontal(
                children:=items.ToArray(),
                spacing:=SafeSpacing(spacing),
                padding:=ResolveActionsPadding(padding, useDefaultVisualPolish),
                alignment:=MASLayoutAlignment.Center)
        End Function

        ''' <summary>
        ''' Creates a simple action item aligned to the end of a vertical page/form.
        ''' </summary>
        Public Shared Function Actions(control As MASControlBase,
                                       Optional width As MASSizePolicy = Nothing,
                                       Optional height As MASSizePolicy = Nothing,
                                       Optional margin As MASLayoutThickness = Nothing,
                                       Optional key As String = "") As MASLayoutItem

            Return MASComposition.Item(
                control:=control,
                width:=If(width, MASSizePolicy.Auto()),
                height:=If(height, MASSizePolicy.Auto()),
                alignment:=MASLayoutAlignment.End,
                margin:=margin,
                key:=key
            )
        End Function

        ''' <summary>
        ''' Creates a neutral editor page template from form sections.
        ''' EditorPage is a semantic Page/Form recipe for editing an existing entity; it does not validate,
        ''' bind data, track dirty state, navigate, open overlays, own input routing, own scroll runtime, own Theme state, or own Host lifecycle.
        ''' </summary>
        Public Shared Function EditorPage(sections As IEnumerable(Of MASFormSection),
                                          Optional title As MASControlBase = Nothing,
                                          Optional description As MASControlBase = Nothing,
                                          Optional actions As IMASLayoutNode = Nothing,
                                          Optional spacing As Single = MASCompositionPageSizeTokens.FormSpacing,
                                          Optional padding As MASLayoutThickness = Nothing,
                                          Optional titleHeight As MASSizePolicy = Nothing,
                                          Optional descriptionHeight As MASSizePolicy = Nothing,
                                          Optional actionsWidth As MASSizePolicy = Nothing,
                                          Optional actionsHeight As MASSizePolicy = Nothing,
                                          Optional maxContentWidth As Single = MASCompositionPageSizeTokens.SettingsDetailsMaxContentWidth,
                                          Optional scrollEnabled As Boolean = True,
                                          Optional scrollKey As String = "",
                                          Optional useDefaultVisualPolish As Boolean = True) As IMASLayoutNode

            Return Form(
                sections:=sections,
                title:=title,
                description:=description,
                actions:=actions,
                spacing:=spacing,
                padding:=padding,
                titleHeight:=titleHeight,
                descriptionHeight:=descriptionHeight,
                actionsWidth:=actionsWidth,
                actionsHeight:=actionsHeight,
                maxContentWidth:=maxContentWidth,
                scrollEnabled:=scrollEnabled,
                scrollKey:=scrollKey,
                useDefaultVisualPolish:=useDefaultVisualPolish)
        End Function

        ''' <summary>
        ''' Creates a neutral editor page template from direct form fields.
        ''' This overload keeps EditorPage useful for small edit screens without forcing a section model.
        ''' </summary>
        Public Shared Function EditorPage(fields As IEnumerable(Of MASFormField),
                                          Optional title As MASControlBase = Nothing,
                                          Optional description As MASControlBase = Nothing,
                                          Optional submitArea As MASControlBase = Nothing,
                                          Optional spacing As Single = MASCompositionPageSizeTokens.FormSpacing,
                                          Optional padding As MASLayoutThickness = Nothing,
                                          Optional titleHeight As MASSizePolicy = Nothing,
                                          Optional descriptionHeight As MASSizePolicy = Nothing,
                                          Optional submitAreaWidth As MASSizePolicy = Nothing,
                                          Optional submitAreaHeight As MASSizePolicy = Nothing,
                                          Optional maxContentWidth As Single = MASCompositionPageSizeTokens.SettingsDetailsMaxContentWidth,
                                          Optional scrollEnabled As Boolean = True,
                                          Optional scrollKey As String = "",
                                          Optional useDefaultVisualPolish As Boolean = True) As IMASLayoutNode

            Return Form(
                fields:=fields,
                title:=title,
                description:=description,
                submitArea:=submitArea,
                spacing:=spacing,
                padding:=padding,
                titleHeight:=titleHeight,
                descriptionHeight:=descriptionHeight,
                submitAreaWidth:=submitAreaWidth,
                submitAreaHeight:=submitAreaHeight,
                maxContentWidth:=maxContentWidth,
                scrollEnabled:=scrollEnabled,
                scrollKey:=scrollKey,
                useDefaultVisualPolish:=useDefaultVisualPolish)
        End Function

    End Class

End Namespace
