
Namespace Primitives

    ''' <summary>
    ''' Represents a table of in-memory data.
    ''' </summary>
    ''' <remarks></remarks>
    Public Class ObjectTable

        Private WithEvents _columns As ColumnCollection
        Private _rows As RowCollection

        ''' <summary>
        ''' Initializes a default instance of the <see cref="Mercury.Mobile.Forms.Primitives.ObjectTable"/> class.
        ''' </summary>
        Public Sub New()
            Me._columns = New ColumnCollection(Me)
            Me._rows = New RowCollection()
        End Sub

        ''' <summary>
        ''' Gets a collection of columns describing the data properties of items on this table.
        ''' </summary>
        ''' <returns>A <see cref="Mercury.Mobile.Forms.Primitives.ColumnCollection"/> that contains 
        ''' the columns that describe the data properties for the items in this table.  An empty 
        ''' collection is returned if no columns have been specified.</returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Columns() As ColumnCollection
            Get
                Return Me._columns
            End Get
        End Property

        ''' <summary>
        ''' Gets a collection of rows containing the data in this table.
        ''' </summary>
        ''' <returns>A <see cref="Mercury.Mobile.Forms.Primitives.RowCollection"/> that contains 
        ''' the data items in this table.  An empty collection is returned if no data exists.</returns>
        ''' <remarks></remarks>
        Public ReadOnly Property Rows() As RowCollection
            Get
                Return Me._rows
            End Get
        End Property

#Region "Methods"

        ''' <summary>
        ''' Creates a new data row with the same columns as defined on this table.
        ''' </summary>
        ''' <returns>A new data row with the same columns as defined on this table.</returns>
        ''' <remarks></remarks>
        Public Function NewRow() As Row
            Return New Row(Me.Columns.GetIndexer())
        End Function

        Private Sub _ExtendColumnsOnRows(ByVal columnIndex As Integer)
            For Each r As Row In Me.Rows
                r.Insert(columnIndex, Nothing)
            Next
        End Sub

        Private Sub _RemoveValuesOnColumn(ByVal columnIndex As Integer)
            For Each r As Row In Me.Rows
                r.SetNull(columnIndex)
            Next
        End Sub

        Private Sub _RebuildData()
            Dim newRow As Row = Nothing
            Dim current As Row = Nothing
            For i As Integer = 0 To Me.Rows.Count - 1
                current = Me.Rows(i)
                newRow = New Row(Me.Columns.GetIndexer())
                For Each col As Column In Me.Columns
                    Try
                        newRow.Add(current.Item(col.Name))
                    Catch ex As ArgumentOutOfRangeException
                    End Try
                Next
                Me.Rows(i) = newRow
            Next
        End Sub

#End Region

        Private Sub _OnColumnsChanged(ByVal sender As Object, ByVal e As CollectionChangedEventArgs) Handles _columns.CollectionChanged
            ' Get tasks by type
            If e.Action = CollectionChangedAction.Add Then
                Me._ExtendColumnsOnRows(e.Index)
            ElseIf e.Action = CollectionChangedAction.Remove Then
                Me._RemoveValuesOnColumn(e.Index)
            ElseIf e.Action = CollectionChangedAction.Reset Then
                Me._RebuildData()
            End If
            Me.OnColumnsChanged(e)
        End Sub

        Protected Overridable Sub OnColumnsChanged(ByVal e As CollectionChangedEventArgs)
        End Sub

    End Class

End Namespace