Option Strict On
Option Explicit On

Imports System
Imports Nexamas.UI.Controls
Imports Nexamas.UI.Layout

Namespace Nexamas.UI.Composition

    ''' <summary>
    ''' Public settings-row description for Phase 2.5 value templates.
    ''' A settings row describes a label/description area and a value/editor control. It owns no rendering,
    ''' validation, 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 MASSettingsRow

        Friend ReadOnly Property Label As MASControlBase
        Friend ReadOnly Property Description As MASControlBase
        Friend ReadOnly Property Editor As MASControlBase
        Friend ReadOnly Property LabelColumnWidth As MASSizePolicy
        Friend ReadOnly Property EditorWidth As MASSizePolicy
        Friend ReadOnly Property EditorHeight As MASSizePolicy
        Friend ReadOnly Property RowHeight As MASSizePolicy
        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(label As MASControlBase,
                       editor As MASControlBase,
                       Optional description As MASControlBase = Nothing,
                       Optional labelColumnWidth As MASSizePolicy = Nothing,
                       Optional editorWidth As MASSizePolicy = Nothing,
                       Optional editorHeight As MASSizePolicy = Nothing,
                       Optional rowHeight As MASSizePolicy = Nothing,
                       Optional spacing As Single = MASCompositionPageSizeTokens.SettingsRowSpacing,
                       Optional padding As MASLayoutThickness = Nothing,
                       Optional margin As MASLayoutThickness = Nothing,
                       Optional key As String = "",
                       Optional useDefaultVisualPolish As Boolean = True)

            If label Is Nothing Then Throw New ArgumentNullException(NameOf(label))
            If editor Is Nothing Then Throw New ArgumentNullException(NameOf(editor))

            Me.Label = label
            Me.Description = description
            Me.Editor = editor
            Me.LabelColumnWidth = If(labelColumnWidth, MASSizePolicy.Fill(1.0F))
            Me.EditorWidth = If(editorWidth, MASCompositionPageSizeTokens.SettingsEditorWidthPolicy())
            Me.EditorHeight = If(editorHeight, MASSizePolicy.Auto())
            Me.RowHeight = If(rowHeight, MASSizePolicy.Auto())
            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 labelNodeItems As New System.Collections.Generic.List(Of MASLayoutItem)()

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

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

            Dim labelNode As IMASLayoutNode =
                MASComposition.Vertical(
                    children:=labelNodeItems.ToArray(),
                    spacing:=If(Description Is Nothing, 0.0F, MASCompositionPageSizeTokens.RowDescriptionSpacing),
                    padding:=MASLayoutThickness.None(),
                    alignment:=MASLayoutAlignment.Stretch)

            Dim rowNode As IMASLayoutNode =
                MASComposition.Horizontal(
                    children:=New MASLayoutItem() {
                        MASComposition.NodeItem(
                            node:=labelNode,
                            width:=LabelColumnWidth,
                            height:=MASSizePolicy.Auto(),
                            alignment:=MASLayoutAlignment.Stretch),
                        MASComposition.Item(
                            control:=Editor,
                            width:=EditorWidth,
                            height:=EditorHeight,
                            alignment:=MASLayoutAlignment.Center)
                    },
                    spacing:=Spacing,
                    padding:=ResolveRowPadding(Padding, UseDefaultVisualPolish),
                    alignment:=MASLayoutAlignment.Center)

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

        Private Shared Function ResolveRowPadding(value As MASLayoutThickness, useDefaultVisualPolish As Boolean) As MASLayoutThickness
            If useDefaultVisualPolish AndAlso IsEmptyThickness(value) Then
                Return MASCompositionPageSizeTokens.RowPadding()
            End If

            Return value
        End Function

        Private Shared Function ResolveRowMargin(value As MASLayoutThickness, useDefaultVisualPolish As Boolean) As MASLayoutThickness
            If useDefaultVisualPolish AndAlso IsEmptyThickness(value) Then
                Return MASCompositionPageSizeTokens.RowMargin()
            End If

            Return value
        End Function

        Private Shared Function IsEmptyThickness(value As MASLayoutThickness) As Boolean
            Return MASCompositionPageSizeTokens.IsEmptyThickness(value)
        End Function

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

    End Class

End Namespace
