Namespace UTSModule.Station

    Public Class RowNodeCollection
        Implements IList, ICollection, IEnumerable

        Private ReadOnly _owner As RowNode

        Friend Sub New(node As RowNode)
            _owner = node
        End Sub


        Default Public Property Item(index As Integer) As Object Implements IList.Item
            Get
                Return _owner.Children.Item(index)
            End Get
            Set(value As Object)
                _owner.Children(index) = CType(value, RowNode)
            End Set
        End Property



        Public ReadOnly Property IsReadOnly As Boolean Implements IList.IsReadOnly
            Get
                Return False
            End Get
        End Property

        Public ReadOnly Property IsFixedSize As Boolean Implements IList.IsFixedSize
            Get
                Return False
            End Get
        End Property

        Public ReadOnly Property Count As Integer Implements ICollection.Count
            Get
                Return _owner.Children.Count
            End Get
        End Property

        Public ReadOnly Property SyncRoot As Object Implements ICollection.SyncRoot
            Get
                Return False
            End Get
        End Property

        Public ReadOnly Property IsSynchronized As Boolean Implements ICollection.IsSynchronized
            Get
                Return False
            End Get
        End Property


        ''' <summary>
        ''' 更新节点的所有子节点的流程站指向
        ''' </summary>
        ''' <param name="pNode"></param>
        Private Sub AddNodeUpdateStationPlan(pNode As RowNode)
            For Each cNode As RowNode In pNode.RowNodes
                cNode.StationPlan = pNode.StationPlan

                If cNode.Count > 0 Then
                    AddNodeUpdateStationPlan(cNode)
                End If
            Next
        End Sub


        ''' <summary>
        ''' 更新节点的上一节点指向
        ''' </summary>
        ''' <param name="node">需要更新的节点</param>
        Private Sub AddNodeUpdatePrevNode(node As RowNode)
            If node.RowIndex > 0 Then
                node.PrevNode = node.ParentNode.Children(node.RowIndex - 1)

                '更新上一节点的下一节点指向
                node.PrevNode.NextNode = node
            Else
                node.PrevNode = Nothing
            End If
        End Sub

        ''' <summary>
        ''' 更新节点的下一节点指向
        ''' </summary>
        ''' <param name="node">需要更新的节点</param>
        Private Sub AddNodeUpdateNextNode(node As RowNode)
            If node.RowIndex < node.ParentNode.Children.Count - 1 Then
                node.NextNode = node.ParentNode.Children(node.RowIndex + 1)

                '更新下一节点的上一节点指向
                node.NextNode.PrevNode = node
            Else
                node.NextNode = Nothing
            End If
        End Sub

        ''' <summary>
        ''' 新增节点后,更新父节点的所有子节点计数
        ''' </summary>
        ''' <param name="node">新增的节点</param>
        Private Sub AddNodeUpdateAllChildCount(node As RowNode)
            Dim pNode As RowNode = node.ParentNode

            While pNode IsNot Nothing
                pNode.AllChildCount += (node.AllChildCount + 1)

                pNode = pNode.ParentNode
            End While
        End Sub


        ''' <summary>
        ''' 删除节点后,更新父节点的所有子节点计数
        ''' </summary>
        ''' <param name="node">被删除的节点</param>
        ''' <param name="include">包含当前节点</param>
        Private Sub DelNodeUpdateAllChildCount(node As RowNode, Optional include As Boolean = True)

            Dim removeCount As Integer

            If include Then
                removeCount = node.AllChildCount + 1
            Else
                removeCount = node.AllChildCount
            End If

            Dim pNode As RowNode = node.ParentNode
            While pNode IsNot Nothing
                pNode.AllChildCount -= removeCount

                pNode = pNode.ParentNode
            End While

        End Sub


        ''' <summary>
        ''' 插入节点后,更新节点下方节点的索引
        ''' </summary>
        ''' <param name="node">需要更新下方节点索引的节点</param>
        Private Sub AddNodeUpdateRowIndex(node As RowNode)
            While node.NextNode IsNot Nothing
                node.NextNode.RowIndex = node.RowIndex + 1
                node = node.NextNode
            End While
        End Sub

        ''' <summary>
        ''' 删除节点后,更新节点下方节点的索引
        ''' </summary>
        ''' <param name="node"></param>
        Private Sub DelNodeUpdateRowIndex(node As RowNode)
            If node.NextNode Is Nothing Then Return
            node.NextNode.RowIndex = node.RowIndex
            node = node.NextNode

            While node.NextNode IsNot Nothing
                node.NextNode.RowIndex = node.RowIndex + 1
                node = node.NextNode
            End While
        End Sub


        ''' <summary>
        ''' 获取新添加的节点的链状目录索引
        ''' </summary>
        ''' <param name="node"></param>
        ''' <returns></returns>
        Private Function GetRowListIndex(node As RowNode) As Integer
            Dim rowListIndex As Integer
            If node.RowIndex = 0 Then
                rowListIndex = node.ParentNode.RowListIndex + 1
            Else
                rowListIndex = node.PrevNode.RowListIndex + node.PrevNode.AllChildCount + 1
            End If
            Return rowListIndex
        End Function

        ''' <summary>
        ''' 更新节点的所有子节点的链式结合的指向
        ''' </summary>
        ''' <param name="pNode"></param>
        ''' <param name="node"></param>
        Private Sub AddNodeUpdateRowList(pNode As RowNode, node As RowNode)
            node.RowList = pNode.RowList
            node.RowListIndex = GetRowListIndex(node)
            node.RowList.Insert(node.RowListIndex, node)

            For Each cNode As RowNode In node.RowNodes
                AddNodeUpdateRowList(node, cNode)
            Next
        End Sub

        ''' <summary>
        ''' 删除节点后，更新链状列表
        ''' </summary>
        ''' <param name="node"></param>
        ''' <param name="include">包含当前节点</param>
        Private Sub DelNodeUpdateRowList(node As RowNode, Optional include As Boolean = True)
            Dim index As Integer

            If include Then
                index = node.RowListIndex
                node.RowList.RemoveAt(index)
            Else
                index = node.RowListIndex + 1
            End If

            Dim removeCount As Integer = node.AllChildCount
            While removeCount > 0
                node.RowList.RemoveAt(index)
                removeCount -= 1
            End While

        End Sub

        ''' <summary>
        ''' 插入节点后,更新链状目录中受影响节点的索引
        ''' </summary>
        ''' <param name="node"></param>
        Private Sub AddNodeUpdateRowListIndex(node As RowNode)
            Dim startIndex As Integer = node.RowListIndex + node.AllChildCount + 1

            For index As Integer = startIndex To node.RowList.Count - 1
                node.RowList(index).RowListIndex = index
            Next
        End Sub

        ''' <summary>
        ''' 删除节点后,更新链状目录中受影响节点的索引
        ''' </summary>
        ''' <param name="node">删除的节点</param>
        ''' <param name="include">是否保存该节点</param>
        Private Sub DelNodeUpdateRowListIndex(node As RowNode, Optional include As Boolean = True)
            Dim startIndex As Integer = node.RowListIndex
            If include = False Then startIndex += 1
            For i As Integer = startIndex To node.RowList.Count - 1
                _owner.RowList(i).RowListIndex = i
            Next
        End Sub


        Public Function Add(value As Object) As Integer Implements IList.Add
            Dim node As RowNode
            Try
                node = CType(value, RowNode)
            Catch ex As Exception
                Return -1
            End Try

            _owner.Children.Add(node)
            node.HeadNode = _owner.HeadNode
            node.ParentNode = _owner
            node.RowLever = _owner.RowLever + 1
            node.RowIndex = _owner.Children.Count - 1
            node.RowList = _owner.RowList

            '更新所有子节点的流程计划指向
            AddNodeUpdateStationPlan(node)

            '更新父节点总子节点计数
            AddNodeUpdateAllChildCount(node)

            '更新上一节点指向
            AddNodeUpdatePrevNode(node)

            '更新下一节点指向
            node.NextNode = Nothing

            '将节点及其子节点插入到链状目录中,并更新链状目指向
            AddNodeUpdateRowList(_owner, node)

            '更新下方节点链状索引
            AddNodeUpdateRowListIndex(node)

            Return _owner.Children.Count
        End Function


        Public Sub Insert(index As Integer, value As Object) Implements IList.Insert
            Dim node As RowNode = CType(value, RowNode)
            _owner.Children.Insert(index, node)
            node.HeadNode = _owner.HeadNode
            node.ParentNode = _owner
            node.RowLever = _owner.RowLever + 1
            node.RowIndex = index
            node.RowList = _owner.RowList

            '更新所有子节点的流程计划指向
            AddNodeUpdateStationPlan(node)

            '更新父节点总子节点计数
            AddNodeUpdateAllChildCount(node)

            '更新上一节点指向
            AddNodeUpdatePrevNode(node)

            '更新下一节点指向
            AddNodeUpdateNextNode(node)

            '更新下方节点树状索引
            AddNodeUpdateRowIndex(node)



            '将节点及其子节点插入到链状目录中,并更新链状目指向
            AddNodeUpdateRowList(_owner, node)

            '更新下方节点链状索引
            AddNodeUpdateRowListIndex(node)
        End Sub

        ''' <summary>
        ''' 移除指定节点
        ''' </summary>
        ''' <param name="value"></param>
        Public Sub Remove(value As Object) Implements IList.Remove
            Dim node As RowNode = CType(value, RowNode)
            _owner.Children.Remove(node)

            '更新父节点总子节点计数
            DelNodeUpdateAllChildCount(node)

            '更新上一节点的下一节点指向
            If node.PrevNode IsNot Nothing Then
                node.PrevNode.NextNode = node.NextNode
            End If

            '更新下一节点的上一节点指向
            If node.NextNode IsNot Nothing Then
                node.NextNode.PrevNode = node.PrevNode
            End If

            '更新下方节点树状索引
            DelNodeUpdateRowIndex(node)



            '链状目录移除被删除的节点
            DelNodeUpdateRowList(node)

            '更新链状目录中的节点索引
            DelNodeUpdateRowListIndex(node)
        End Sub

        Public Sub RemoveAt(index As Integer) Implements IList.RemoveAt
            Dim node As RowNode = _owner.Children(index)
            _owner.Children.RemoveAt(index)


            '更新父节点总子节点计数
            DelNodeUpdateAllChildCount(node)

            '更新上一节点的下一节点指向
            If node.PrevNode IsNot Nothing Then
                node.PrevNode.NextNode = node.NextNode
            End If

            '更新下一节点的上一节点指向
            If node.NextNode IsNot Nothing Then
                node.NextNode.PrevNode = node.PrevNode
            End If

            '更新下方节点树状索引
            DelNodeUpdateRowIndex(node)



            '链状目录移除被删除的节点
            DelNodeUpdateRowList(node)

            '更新链状目录中的节点索引
            DelNodeUpdateRowListIndex(node)
        End Sub

        ''' <summary>
        ''' 清空节点
        ''' </summary>
        Public Sub Clear() Implements IList.Clear
            '清空树状目录子节点
            _owner.Children.Clear()

            '更新父节点总子节点计数
            DelNodeUpdateAllChildCount(_owner, False)



            '链状目录移除被删除的节点
            DelNodeUpdateRowList(_owner, False)

            '更新链状目录中的节点索引
            DelNodeUpdateRowListIndex(_owner, False)

            '更新总子节点计数
            _owner.AllChildCount = 0
        End Sub
        Public Sub CopyTo(array As Array, index As Integer) Implements ICollection.CopyTo
            _owner.Children.CopyTo(CType(array, RowNode()), index)
        End Sub


        Public Function Contains(value As Object) As Boolean Implements IList.Contains
            Return _owner.Children.Contains(CType(value, RowNode))
        End Function

        Public Function IndexOf(value As Object) As Integer Implements IList.IndexOf
            Return _owner.Children.IndexOf(CType(value, RowNode))
        End Function

        Public Function GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
            Return _owner.Children.GetEnumerator
        End Function
    End Class
End Namespace