Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports Nexamas.UI.Values

Namespace Nexamas.UI.Components

    ''' <summary>
    ''' Public lightweight authoring helper for MASDataForm. It collects display field definitions
    ''' only and deliberately does not own binding, reflection, validation rules, persistence,
    ''' or editor creation.
    ''' </summary>
    Public NotInheritable Class MASFormBuilder

        Friend NotInheritable Class FieldDraft
            Friend Sub New(label As String,
                           valueText As String,
                           kind As MASDataFormFieldKind,
                           state As MASDataFormFieldState,
                           helperText As String,
                           required As Boolean)
                Dim normalizedKind As MASDataFormFieldKind = MASFormBuilderFieldPolicy.NormalizeKind(kind)
                Dim normalizedState As MASDataFormFieldState = MASFormBuilderFieldPolicy.NormalizeState(state, required)
                Me.Label = MASFormBuilderFieldPolicy.NormalizeLabel(label)
                Me.ValueText = MASFormBuilderFieldPolicy.NormalizeValueText(valueText, normalizedKind)
                Me.Kind = normalizedKind
                Me.State = normalizedState
                Me.HelperText = MASFormBuilderFieldPolicy.NormalizeHelperText(helperText)
                Me.Required = MASFormBuilderFieldPolicy.NormalizeRequired(required, normalizedState)
            End Sub

            Friend ReadOnly Property Label As String
            Friend ReadOnly Property ValueText As String
            Friend ReadOnly Property Kind As MASDataFormFieldKind
            Friend ReadOnly Property State As MASDataFormFieldState
            Friend ReadOnly Property HelperText As String
            Friend ReadOnly Property Required As Boolean
        End Class

        Private ReadOnly _fields As New List(Of FieldDraft)()

        Public Sub New()
        End Sub

        Public ReadOnly Property FieldCount As Integer
            Get
                Return _fields.Count
            End Get
        End Property

        Friend ReadOnly Property RequiredFieldCount As Integer
            Get
                Dim count As Integer = 0
                For Each field As FieldDraft In _fields
                    If field.Required Then count += 1
                Next
                Return count
            End Get
        End Property

        Friend ReadOnly Property IssueFieldCount As Integer
            Get
                Dim count As Integer = 0
                For Each field As FieldDraft In _fields
                    If MASFormBuilderFieldPolicy.IsIssueState(field.State) Then count += 1
                Next
                Return count
            End Get
        End Property

        Public Function AddField(label As String,
                                 valueText As String,
                                 Optional kind As MASDataFormFieldKind = MASDataFormFieldKind.Text,
                                 Optional state As MASDataFormFieldState = MASDataFormFieldState.Normal,
                                 Optional helperText As String = "",
                                 Optional required As Boolean = False) As MASFormBuilder
            If _fields.Count >= DataFormTokens.MaxFields Then Return Me
            _fields.Add(New FieldDraft(label, valueText, kind, state, helperText, required))
            Return Me
        End Function

        Public Function AddText(label As String,
                                valueText As String,
                                Optional required As Boolean = False,
                                Optional helperText As String = "") As MASFormBuilder
            Return AddField(label, valueText, MASDataFormFieldKind.Text, If(required, MASDataFormFieldState.Required, MASDataFormFieldState.Normal), helperText, required)
        End Function

        Public Function AddSelection(label As String,
                                     valueText As String,
                                     Optional helperText As String = "") As MASFormBuilder
            Return AddField(label, valueText, MASDataFormFieldKind.Selection, MASDataFormFieldState.Normal, helperText, False)
        End Function

        Public Function AddToggle(label As String,
                                  checked As Boolean,
                                  Optional helperText As String = "") As MASFormBuilder
            Return AddField(label, MASFormBuilderFieldPolicy.FormatToggleValue(checked), MASDataFormFieldKind.Toggle, MASDataFormFieldState.Normal, helperText, False)
        End Function

        Public Function AddDate(label As String,
                                valueText As String,
                                Optional helperText As String = "") As MASFormBuilder
            Return AddField(label, valueText, MASDataFormFieldKind.[Date], MASDataFormFieldState.Normal, helperText, False)
        End Function

        Public Function AddTags(label As String,
                                valueText As String,
                                Optional helperText As String = "") As MASFormBuilder
            Return AddField(label, valueText, MASDataFormFieldKind.Tags, MASDataFormFieldState.Normal, helperText, False)
        End Function

        Public Function Clear() As MASFormBuilder
            _fields.Clear()
            Return Me
        End Function

        Public Function ApplyTo(form As MASDataForm) As MASDataForm
            If form Is Nothing Then Throw New ArgumentNullException(NameOf(form))
            Return form.SetFields(Me)
        End Function

        Friend Function Snapshot() As List(Of FieldDraft)
            Return New List(Of FieldDraft)(_fields)
        End Function

        Friend Shared Function NormalizeText(value As String,
                                             fallback As String) As String
            Return MASFormBuilderFieldPolicy.NormalizeText(value, fallback, MASFormBuilderFieldPolicy.MaxValueLength)
        End Function

    End Class

End Namespace
