Option Strict On
Option Explicit On

Namespace Nexamas.UI.Virtualization

    ''' <summary>
    ''' Immutable environment stamp supplied by item-heavy controls when virtualization-owned measurements depend on theme, DPI,
    ''' density, font, localization, RTL direction, collection revision, or control-size facts. The stamp keeps invalidation causes
    ''' explicit and testable without letting each control invent private cache-reset booleans.
    ''' </summary>
    Friend NotInheritable Class MASVirtualizationEnvironmentStamp

        Private Shared ReadOnly EmptyStamp As MASVirtualizationEnvironmentStamp =
            New MASVirtualizationEnvironmentStamp(0, 0, 0, 0, 0, 0, 0, 0, 0.0F)

        Friend Shared ReadOnly Property Empty As MASVirtualizationEnvironmentStamp
            Get
                Return EmptyStamp
            End Get
        End Property

        Friend Sub New(themeRevision As Integer,
                       dpiRevision As Integer,
                       densityRevision As Integer,
                       fontRevision As Integer,
                       localizationRevision As Integer,
                       rtlRevision As Integer,
                       itemCollectionRevision As Integer,
                       controlSizeRevision As Integer,
                       viewportExtentPx As Single)
            Me.ThemeRevision = Math.Max(0, themeRevision)
            Me.DpiRevision = Math.Max(0, dpiRevision)
            Me.DensityRevision = Math.Max(0, densityRevision)
            Me.FontRevision = Math.Max(0, fontRevision)
            Me.LocalizationRevision = Math.Max(0, localizationRevision)
            Me.RtlRevision = Math.Max(0, rtlRevision)
            Me.ItemCollectionRevision = Math.Max(0, itemCollectionRevision)
            Me.ControlSizeRevision = Math.Max(0, controlSizeRevision)
            Me.ViewportExtentPx = MASVirtualizationNumericGuard.NormalizeNonNegative(viewportExtentPx)
        End Sub

        Friend ReadOnly Property ThemeRevision As Integer
        Friend ReadOnly Property DpiRevision As Integer
        Friend ReadOnly Property DensityRevision As Integer
        Friend ReadOnly Property FontRevision As Integer
        Friend ReadOnly Property LocalizationRevision As Integer
        Friend ReadOnly Property RtlRevision As Integer
        Friend ReadOnly Property ItemCollectionRevision As Integer
        Friend ReadOnly Property ControlSizeRevision As Integer
        Friend ReadOnly Property ViewportExtentPx As Single

        Friend ReadOnly Property IsValid As Boolean
            Get
                Return MASVirtualizationNumericGuard.IsFinite(ViewportExtentPx)
            End Get
        End Property

        Friend Function ResolveInvalidationReason(previous As MASVirtualizationEnvironmentStamp) As MASVirtualizationInvalidationReason
            If previous Is Nothing Then
                Return MASVirtualizationInvalidationReason.None
            End If

            If ItemCollectionRevision <> previous.ItemCollectionRevision Then
                Return MASVirtualizationInvalidationReason.ItemCollectionChanged
            End If

            If DpiRevision <> previous.DpiRevision Then
                Return MASVirtualizationInvalidationReason.DpiChanged
            End If

            If DensityRevision <> previous.DensityRevision Then
                Return MASVirtualizationInvalidationReason.DensityChanged
            End If

            If FontRevision <> previous.FontRevision Then
                Return MASVirtualizationInvalidationReason.FontChanged
            End If

            If ThemeRevision <> previous.ThemeRevision Then
                Return MASVirtualizationInvalidationReason.ThemeChanged
            End If

            If LocalizationRevision <> previous.LocalizationRevision Then
                Return MASVirtualizationInvalidationReason.LocalizationChanged
            End If

            If RtlRevision <> previous.RtlRevision Then
                Return MASVirtualizationInvalidationReason.RtlChanged
            End If

            If ControlSizeRevision <> previous.ControlSizeRevision OrElse Math.Abs(ViewportExtentPx - previous.ViewportExtentPx) > 0.0001F Then
                Return MASVirtualizationInvalidationReason.ControlSizeChanged
            End If

            Return MASVirtualizationInvalidationReason.None
        End Function

    End Class

End Namespace
