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 details-row description for Phase 2.5 value templates.
    ''' A details row describes a read-oriented label/value pair with optional supporting description.
    ''' 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 MASDetailsRow

        Friend ReadOnly Property Label As MASControlBase
        Friend ReadOnly Property ValueControl As MASControlBase
        Friend ReadOnly Property Description As MASControlBase
        Friend ReadOnly Property LabelColumnWidth As MASSizePolicy
        Friend ReadOnly Property ValueWidth As MASSizePolicy
        Friend ReadOnly Property ValueHeight 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,
                       valueControl As MASControlBase,
                       Optional description As MASControlBase = Nothing,
                       Optional labelColumnWidth As MASSizePolicy = Nothing,
                       Optional valueWidth As MASSizePolicy = Nothing,
                       Optional valueHeight As MASSizePolicy = Nothing,
                       Optional rowHeight As MASSizePolicy = Nothing,
                       Optional spacing As Single = MASCompositionPageSizeTokens.DetailsRowSpacing,
                       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 valueControl Is Nothing Then Throw New ArgumentNullException(NameOf(valueControl))

            Me.Label = label
            Me.ValueControl = valueControl
            Me.Description = description
            Me.LabelColumnWidth = If(labelColumnWidth, MASCompositionPageSizeTokens.DetailsLabelColumnWidthPolicy())
            Me.ValueWidth = If(valueWidth, MASSizePolicy.Fill(1.0F))
            Me.ValueHeight = If(valueHeight, 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 valueNodeItems As New List(Of MASLayoutItem)()

            valueNodeItems.Add(
                MASComposition.Item(
                    control:=ValueControl,
                    width:=MASSizePolicy.Fill(1.0F),
                    height:=ValueHeight,
                    alignment:=MASLayoutAlignment.Stretch)
            )

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

            Dim valueNode As IMASLayoutNode =
                MASComposition.Vertical(
                    children:=valueNodeItems.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.Item(
                            control:=Label,
                            width:=LabelColumnWidth,
                            height:=MASSizePolicy.Auto(),
                            alignment:=MASLayoutAlignment.Start),
                        MASComposition.NodeItem(
                            node:=valueNode,
                            width:=ValueWidth,
                            height:=MASSizePolicy.Auto(),
                            alignment:=MASLayoutAlignment.Stretch)
                    },
                    spacing:=Spacing,
                    padding:=ResolveRowPadding(Padding, UseDefaultVisualPolish),
                    alignment:=MASLayoutAlignment.Start)

            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
