Option Strict On
Option Explicit On

Namespace Nexamas.UI.Components

    Friend NotInheritable Class MASTreeSelectionState

        Private _selectedNode As MASTreeNode = Nothing

        Friend ReadOnly Property SelectedNode As MASTreeNode
            Get
                Return _selectedNode
            End Get
        End Property

        Friend Function IsSelected(node As MASTreeNode) As Boolean
            Return node IsNot Nothing AndAlso Object.ReferenceEquals(_selectedNode, node)
        End Function

        Friend Function SetSingle(node As MASTreeNode) As Boolean
            If Object.ReferenceEquals(_selectedNode, node) Then Return False

            _selectedNode = node
            Return True
        End Function

        Friend Function Clear() As Boolean
            If _selectedNode Is Nothing Then Return False

            _selectedNode = Nothing
            Return True
        End Function

        Friend Sub NormalizeAfterNodesChanged(rootNodes As IReadOnlyList(Of MASTreeNode))
            If _selectedNode Is Nothing Then Return

            If ContainsNode(rootNodes, _selectedNode) Then Return

            _selectedNode = Nothing
        End Sub

        Private Shared Function ContainsNode(nodes As IReadOnlyList(Of MASTreeNode),
                                             target As MASTreeNode) As Boolean

            If nodes Is Nothing OrElse target Is Nothing Then Return False

            For Each n As MASTreeNode In nodes
                If ContainsNodeRecursive(n, target) Then
                    Return True
                End If
            Next

            Return False
        End Function

        Private Shared Function ContainsNodeRecursive(node As MASTreeNode,
                                                      target As MASTreeNode) As Boolean

            If node Is Nothing OrElse target Is Nothing Then Return False

            If Object.ReferenceEquals(node, target) Then
                Return True
            End If

            For Each c As MASTreeNode In node.Children
                If ContainsNodeRecursive(c, target) Then
                    Return True
                End If
            Next

            Return False
        End Function

    End Class

End Namespace