
Namespace Data

    ''' <summary>
    ''' A container for an item in a data page.
    ''' </summary>
    Public NotInheritable Class DataContainer(Of T)
        Inherits NotifyMemberBase

        ''' <summary>
        ''' Initializes a new instance of the DataContainer(Of T) class with the specified index.
        ''' </summary>
        ''' <param name="index">The index of this container.</param>
        ''' <remarks></remarks>
        Public Sub New(ByVal index As Integer)
            Me._index = index
        End Sub

        Private _index As Integer

        ''' <summary>
        ''' Gets the index of this container.
        ''' </summary>
        ''' <returns>The index of this container.</returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Index() As Integer
            Get
                Return Me._index
            End Get
        End Property

        ''' <summary>
        ''' Gets a value indicating whether the data in this container is not set.
        ''' </summary>
        ''' <returns>True if the data is not set; otherwise, false.</returns>
        ''' <remarks></remarks>
        Public ReadOnly Property IsLoading() As Boolean
            Get
                Return (Me.Data Is Nothing)
            End Get
        End Property

        Private _data As T

        ''' <summary>
        ''' Gets the contained data item.
        ''' </summary>
        ''' <returns>The contained data item.</returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Data() As T
            Get
                Return Me._data
            End Get
        End Property

        ''' <summary>
        ''' Sets the contained data item.
        ''' </summary>
        ''' <param name="value">The data item value to set.</param>
        ''' <remarks></remarks>
        Public Sub SetData(ByVal value As T)
            Me._data = value
            Me.OnPropertyChanged("Data")
            Me.OnPropertyChanged("IsLoading")
        End Sub

        ''' <summary>
        ''' Gets a value indicating whether this container is in use by another element.
        ''' </summary>
        ''' <returns>True if this container is still in use; otherwise, false.</returns>
        ''' <remarks></remarks>
        Public ReadOnly Property IsInUse() As Boolean
            Get
                Return MyBase.IsPropertyChangedEventAttached
            End Get
        End Property

        Private _canVirtualize As Boolean

        ''' <summary>
        ''' Gets a value indicating whether this container can be virtualized.
        ''' </summary>
        ''' <returns>True if this container can be virtualized; otherwise, false.</returns>
        ''' <remarks></remarks>
        Public ReadOnly Property CanVirtualize() As Boolean
            Get
                Return Me._canVirtualize
            End Get
        End Property

        ''' <summary>
        ''' Sets a value indicating whether this container can be virtualized.
        ''' </summary>
        ''' <param name="value">True to virtualize; otherwise, false.</param>
        ''' <remarks></remarks>
        Public Sub Virtualize(ByVal value As Boolean)
            Me._canVirtualize = value
            OnPropertyChanged("CanVirtualize")
        End Sub

        Public Overrides Function Equals(ByVal obj As Object) As Boolean
            Return DataContainer(Of T).ContainerEquals(Me, TryCast(obj, DataContainer(Of T)))
        End Function

        Public Shared Function ContainerEquals(ByVal x As DataContainer(Of T), ByVal y As DataContainer(Of T)) As Boolean
            If Object.ReferenceEquals(x, Nothing) AndAlso Object.ReferenceEquals(y, Nothing) Then _
                Return True
            If Object.ReferenceEquals(x, Nothing) OrElse Object.ReferenceEquals(y, Nothing) Then _
                Return False

            If x.Index <> y.Index Then _
                Return False
            If Not (DataContainer(Of T).DataEquals(x.Data, y.Data)) Then _
                Return False
            Return True
        End Function

        Public Shared Function DataEquals(ByVal x As T, ByVal y As T) As Boolean
            Return EqualityComparer(Of T).Default.Equals(x, y)
        End Function

    End Class

End Namespace