Option Strict On
Option Explicit On

Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel

Namespace Nexamas.UI.Virtualization

    ''' <summary>
    ''' Stable integration contract between MASVirtualizedItemsSystem and one current item-oriented Nexamas UI surface. The binding
    ''' references the actual consumer type so rename/removal drift is caught at compile time, but it does not expose virtualization
    ''' through the public API and does not force a visual behavior change.
    ''' </summary>
    Friend NotInheritable Class MASVirtualizationConsumerBinding

        Private ReadOnly _composedThroughConsumerIds As IReadOnlyList(Of String)

        Friend Sub New(id As String,
                       displayName As String,
                       consumerType As Type,
                       kind As MASVirtualizationConsumerKind,
                       stage As MASVirtualizationIntegrationStage,
                       recommendedAxis As MASVirtualizationAxis,
                       scrollRemainsConsumerOwned As Boolean,
                       layoutRemainsConsumerOwned As Boolean,
                       selectionRemainsConsumerOwned As Boolean,
                       Optional consumesSharedController As Boolean = False,
                       Optional extentStrategy As MASVirtualizationExtentStrategy = MASVirtualizationExtentStrategy.EstimatedWithMeasuredOverrides,
                       Optional requiresAutoInvalidationCoordinator As Boolean = True,
                       Optional requiresConsumerBoundaryAudit As Boolean = True,
                       Optional composedThroughConsumerIds As IEnumerable(Of String) = Nothing)
            Me.Id = If(id, String.Empty).Trim()
            Me.DisplayName = If(displayName, String.Empty).Trim()
            Me.ConsumerType = consumerType
            Me.Kind = kind
            Me.Stage = stage
            Me.RecommendedAxis = recommendedAxis
            Me.ScrollRemainsConsumerOwned = scrollRemainsConsumerOwned
            Me.LayoutRemainsConsumerOwned = layoutRemainsConsumerOwned
            Me.SelectionRemainsConsumerOwned = selectionRemainsConsumerOwned
            Me.ConsumesSharedController = consumesSharedController
            Me.ExtentStrategy = extentStrategy
            Me.RequiresAutoInvalidationCoordinator = requiresAutoInvalidationCoordinator
            Me.RequiresConsumerBoundaryAudit = requiresConsumerBoundaryAudit
            _composedThroughConsumerIds = NormalizeComposedThroughConsumerIds(composedThroughConsumerIds)
        End Sub

        Friend ReadOnly Property Id As String
        Friend ReadOnly Property DisplayName As String
        Friend ReadOnly Property ConsumerType As Type
        Friend ReadOnly Property Kind As MASVirtualizationConsumerKind
        Friend ReadOnly Property Stage As MASVirtualizationIntegrationStage
        Friend ReadOnly Property RecommendedAxis As MASVirtualizationAxis
        Friend ReadOnly Property ScrollRemainsConsumerOwned As Boolean
        Friend ReadOnly Property LayoutRemainsConsumerOwned As Boolean
        Friend ReadOnly Property SelectionRemainsConsumerOwned As Boolean
        Friend ReadOnly Property ConsumesSharedController As Boolean
        Friend ReadOnly Property ExtentStrategy As MASVirtualizationExtentStrategy
        Friend ReadOnly Property RequiresAutoInvalidationCoordinator As Boolean
        Friend ReadOnly Property RequiresConsumerBoundaryAudit As Boolean

        Friend ReadOnly Property ComposedThroughConsumerIds As IReadOnlyList(Of String)
            Get
                Return _composedThroughConsumerIds
            End Get
        End Property

        Friend ReadOnly Property IsComposedSharedControllerConsumer As Boolean
            Get
                Return ConsumesSharedController AndAlso
                       Stage = MASVirtualizationIntegrationStage.ComposedSharedControllerConsumer AndAlso
                       _composedThroughConsumerIds.Count > 0
            End Get
        End Property

        Friend ReadOnly Property IsActiveOrComposedSharedControllerConsumer As Boolean
            Get
                Return ConsumesSharedController AndAlso
                       (Stage = MASVirtualizationIntegrationStage.ActiveSharedControllerConsumer OrElse
                        Stage = MASVirtualizationIntegrationStage.ComposedSharedControllerConsumer)
            End Get
        End Property

        Friend ReadOnly Property IsStructurallyValid As Boolean
            Get
                Return Id.Length > 0 AndAlso
                       DisplayName.Length > 0 AndAlso
                       ConsumerType IsNot Nothing AndAlso
                       ScrollRemainsConsumerOwned AndAlso
                       LayoutRemainsConsumerOwned AndAlso
                       SelectionRemainsConsumerOwned AndAlso
                       RequiresAutoInvalidationCoordinator AndAlso
                       RequiresConsumerBoundaryAudit AndAlso
                       System.Enum.IsDefined(GetType(MASVirtualizationExtentStrategy), ExtentStrategy) AndAlso
                       (Stage <> MASVirtualizationIntegrationStage.ComposedSharedControllerConsumer OrElse IsComposedSharedControllerConsumer)
            End Get
        End Property

        Private Shared Function NormalizeComposedThroughConsumerIds(ids As IEnumerable(Of String)) As IReadOnlyList(Of String)
            Dim result As New List(Of String)()

            If ids IsNot Nothing Then
                For Each rawId As String In ids
                    Dim id As String = If(rawId, String.Empty).Trim()
                    If id.Length = 0 Then Continue For
                    If result.Contains(id) Then Continue For
                    result.Add(id)
                Next
            End If

            Return New ReadOnlyCollection(Of String)(result.ToArray())
        End Function

    End Class

End Namespace
