# The following is an example on how navigate the hierarchy of the scene.
import ufe
import lookdevx as lx

if not shadingContainer:
    raise Exception('This example requires a shading container i.e., a MaterialX document or a USD '
                    'material. Check the other examples to see how to create one.')

# Create a compound and a node inside.
runTimeId = shadingContainer.runTimeId()
compound = lx.createCompound(shadingContainer, ufe.PathComponent("compound1"))
childItem = ufe.NodeDef.definition(runTimeId, 'ND_add_float').createNode(compound, ufe.PathComponent('child'))

# Create some more nodes.
for _ in range(5):
    ufe.NodeDef.definition(runTimeId, 'ND_add_float').createNode(shadingContainer, ufe.PathComponent('add'))

# Explore the hierarchy using `ufe.Hierarchy`.
def printParentAndChildren(item):
    # The hierarchy of the scene can be navigates using the `ufe.Hierarchy` interface.
    hierarchy = ufe.Hierarchy.hierarchy(item)

    # It can be used to find the parent and children of an item.
    parentItem = hierarchy.parent()
    print(f'"{ufe.PathString.string(parentItem.path())}" is the parent of "{ufe.PathString.string(item.path())}".')
    print(f'"{ufe.PathString.string(item.path())}" has the following children:')
    for childItem in hierarchy.children():
        print(f'- {ufe.PathString.string(childItem.path())}')

printParentAndChildren(shadingContainer)
printParentAndChildren(compound)

# It's also possible to navigate the hierarchy by just manipulating paths. For example, the parent
# can easily be found using `pop()` on the path.
parentPath = compound.path().pop()
# This returns the path of the parent, but a scene item can be created from the path.
parentItem = ufe.Hierarchy.createItem(parentPath)
print(f'"{ufe.PathString.string(parentItem.path())}" is the parent of "{ufe.PathString.string(compound.path())}".')

# If the name of a child is known, its path can be created easily from the parent path.
childPath = compound.path() + "child1"
childItem = ufe.Hierarchy.createItem(childPath)
print(f'Manually pointed to child "{ufe.PathString.string(childItem.path())}".')
# This also works across multiple levels.
childPath = shadingContainer.path() + "compound1" + "child1"
childItem = ufe.Hierarchy.createItem(childPath)
print(f'Manually pointed to descendant "{ufe.PathString.string(childItem.path())}".')

# It can also be useful to create items from a path-string when interacting with an existing scene.
# The UFE path-string can be found in the UI at the bottom of the Maya attribute editor, so it can
# easily be copied if necessary.
childPathString = ufe.PathString.string(childItem.path())
print(f'PathString: "{childPathString}". Can be copied from the attribute editor.')

# Create an item from a path-string.
childPath = ufe.PathString.path(childPathString)
childItem = ufe.Hierarchy.createItem(childPath)
print(f'Created item "{ufe.PathString.string(childItem.path())}" form a path-string.')