VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
END
Attribute VB_Name = "API_LinkedComponents"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
' ======= Graph linked components =====
' Shared module version: 20210411
' Tested in: TestCommons
' Depends on: CDS_Graph
' Required reference: Scripting
Option Explicit

Private graph_ As CDS_Graph
Private maxId_ As Long
Private components_ As Scripting.Dictionary

Public Property Get CountComponents() As Long
  CountComponents = maxId_
End Property

Public Function GetComponents(iGraph As CDS_Graph) As Scripting.Dictionary
  maxId_ = 0
  Set components_ = New Scripting.Dictionary
  Set graph_ = iGraph
  
  Dim vNode As Variant
  For Each vNode In graph_.Nodes
    If Not components_.Exists(vNode) Then
      Call VisitNode(vNode)
      maxId_ = maxId_ + 1
    End If
  Next vNode
  Set GetComponents = components_
End Function

' =========
Private Function VisitNode(vNode As Variant)
  If components_.Exists(vNode) Then _
    Exit Function
  Call components_.Add(vNode, maxId_)
  Call VisitParents(vNode)
  Call VisitChildren(vNode)
End Function

Private Function VisitParents(vNode As Variant)
  Dim vParent As Variant
  For Each vParent In graph_.nodes_(vNode).inputs_
    Call VisitNode(vParent)
  Next vParent
End Function

Private Function VisitChildren(vNode As Variant)
  Dim vParent As Variant
  For Each vParent In graph_.nodes_(vNode).outputs_
    Call VisitNode(vParent)
  Next vParent
End Function
