Option Strict On
Option Explicit On

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

Namespace Nexamas.UI.Components

    ''' <summary>
    ''' Friend-only TreeGrid row-window snapshot. It proves the control can keep a
    ''' large stable source projection while exposing only a bounded realized row
    ''' window to rendering/input diagnostics. It is not a storage provider, not an
    ''' external virtualizer, and not a public binding API.
    ''' </summary>
    Friend NotInheritable Class MASTreeGridRowWindowSnapshot

        Private ReadOnly _keys As IReadOnlyList(Of String)

        Friend Sub New(firstRowIndex As Integer,
                       lastRowIndex As Integer,
                       totalVisibleRows As Integer,
                       requestedCapacity As Integer,
                       projectionRevision As Integer,
                       keys As IEnumerable(Of String))
            Me.FirstRowIndex = Math.Max(0, firstRowIndex)
            Me.LastRowIndex = lastRowIndex
            Me.TotalVisibleRows = Math.Max(0, totalVisibleRows)
            Me.RequestedCapacity = Math.Max(1, requestedCapacity)
            Me.ProjectionRevision = projectionRevision

            Dim normalized As New List(Of String)()
            If keys IsNot Nothing Then
                For Each key As String In keys
                    Dim trimmed As String = If(key, String.Empty).Trim()
                    If trimmed.Length > 0 Then normalized.Add(trimmed)
                Next
            End If
            _keys = New ReadOnlyCollection(Of String)(normalized.ToArray())
        End Sub

        Friend ReadOnly Property FirstRowIndex As Integer
        Friend ReadOnly Property LastRowIndex As Integer
        Friend ReadOnly Property TotalVisibleRows As Integer
        Friend ReadOnly Property RequestedCapacity As Integer
        Friend ReadOnly Property ProjectionRevision As Integer

        Friend ReadOnly Property RealizedRowKeys As IReadOnlyList(Of String)
            Get
                Return _keys
            End Get
        End Property

        Friend ReadOnly Property RealizedRowCount As Integer
            Get
                Return _keys.Count
            End Get
        End Property

        Friend ReadOnly Property IsEmpty As Boolean
            Get
                Return TotalVisibleRows <= 0 OrElse RealizedRowCount <= 0
            End Get
        End Property

        Friend ReadOnly Property IsBounded As Boolean
            Get
                Return RealizedRowCount <= RequestedCapacity
            End Get
        End Property

        Friend ReadOnly Property CoversPartialVisibleSet As Boolean
            Get
                Return TotalVisibleRows > RealizedRowCount
            End Get
        End Property

        Friend Function ContainsKey(rowKey As String) As Boolean
            Dim normalized As String = If(rowKey, String.Empty).Trim()
            If normalized.Length = 0 Then Return False
            For Each key As String In _keys
                If String.Equals(key, normalized, StringComparison.OrdinalIgnoreCase) Then Return True
            Next
            Return False
        End Function

    End Class

    Partial Public NotInheritable Class MASTreeGrid

#Region "Friend row-window diagnostics"

        Friend ReadOnly Property VisibleProjectionRevision As Integer
            Get
                Return _treeRevision
            End Get
        End Property

        Friend Function CreateRowWindowSnapshot(Optional requestedCapacity As Integer = 0) As MASTreeGridRowWindowSnapshot
            Dim visible As List(Of VisibleTreeGridRow) = BuildVisibleRows()
            Dim total As Integer = visible.Count
            Dim capacity As Integer = Math.Max(1, If(requestedCapacity > 0, requestedCapacity, _rowViewportCapacity))
            If total <= 0 Then
                Return New MASTreeGridRowWindowSnapshot(0, -1, 0, capacity, _treeRevision, Array.Empty(Of String)())
            End If

            Dim first As Integer = Math.Max(0, Math.Min(_topRowIndex, total - 1))
            Dim last As Integer = Math.Min(total - 1, first + capacity - 1)
            Dim keys As New List(Of String)()
            For i As Integer = first To last
                Dim item As VisibleTreeGridRow = visible(i)
                If item IsNot Nothing AndAlso item.Row IsNot Nothing Then keys.Add(item.Row.Key)
            Next

            Return New MASTreeGridRowWindowSnapshot(first, last, total, capacity, _treeRevision, keys)
        End Function

        Friend Function GetRealizedRowKeys(Optional requestedCapacity As Integer = 0) As IReadOnlyList(Of String)
            Return CreateRowWindowSnapshot(requestedCapacity).RealizedRowKeys
        End Function

        Friend Function HasBoundedRowWindow(totalVisibleThreshold As Integer,
                                            maxRealizedRows As Integer) As Boolean
            Dim snapshot As MASTreeGridRowWindowSnapshot = CreateRowWindowSnapshot(maxRealizedRows)
            Return snapshot.TotalVisibleRows >= Math.Max(1, totalVisibleThreshold) AndAlso
                   snapshot.RealizedRowCount <= Math.Max(1, maxRealizedRows) AndAlso
                   snapshot.CoversPartialVisibleSet
        End Function

        Friend Function SetDiagnosticRowViewportCapacity(capacity As Integer) As Boolean
            Dim normalized As Integer = Math.Max(1, capacity)
            If _rowViewportCapacity = normalized Then Return True
            _rowViewportCapacity = normalized
            _topRowIndex = Math.Max(0, Math.Min(_topRowIndex, ResolveRowViewportMaxTop()))
            InvalidateVisual()
            Return True
        End Function

#End Region

    End Class

End Namespace
