/*
    MultiNode sample code
    Henry Smith (henry@enigmasoftware.ca)
*/


#include "MultiNode.h"
#include "NodeImpl.h"

////////////////////////////////////////////////////////////////////////////////
//
//  TreeOrder
//
////////////////////////////////////////////////////////////////////////////////

MultiNodeRef
TreeOrder::Start (const MultiNodeRef& inRoot, bool inShouldIncludeRoot)
{
    MultiNodeRef start = inRoot;

    // Start with my first child
    if (start != NullRef && !inShouldIncludeRoot) {
        start = Advance( start );
    }
    return start;
}

MultiNodeRef
TreeOrder::Advance (const MultiNodeRef& inPosition)
{
    if (inPosition->Child() != NullRef) {
        return inPosition->Child();
    } else {
        return NextNode( inPosition );
    }
}

MultiNodeRef
TreeOrder::NextNode (const MultiNodeRef& inCurrent)
{
    if (inCurrent->Sibling() != NullRef) {
        return inCurrent->Sibling();
    }
    else
    {
        // Continue with my parent's sibling
        if (inCurrent->Parent() != NullRef) {
            return NextNode( inCurrent->Parent() );
        } else {
            return NullRef;
        }
    }
}


////////////////////////////////////////////////////////////////////////////////
//
//  ChildOrder
//
////////////////////////////////////////////////////////////////////////////////

MultiNodeRef
ChildOrder::Start (const MultiNodeRef& inRoot, bool /* ignored */)
{
    if (inRoot == NullRef) {
        return NullRef;
    }
    else
    {
        if (inRoot->Child() != NullRef) {
            return inRoot->Child();
        } else {
            return NullRef;
        }
    }
}

MultiNodeRef
ChildOrder::Advance (const MultiNodeRef& inPosition)
{
    return inPosition->Sibling();
}


////////////////////////////////////////////////////////////////////////////////
//
//  ParentOrder
//
////////////////////////////////////////////////////////////////////////////////

MultiNodeRef
ParentOrder::Start (const MultiNodeRef& inRoot, bool inShouldIncludeRoot)
{
    MultiNodeRef start = inRoot;

    // Start with first parent
    if (start != NullRef && !inShouldIncludeRoot) {
        start = Advance( start );
    }
    return start;
}

MultiNodeRef
ParentOrder::Advance (const MultiNodeRef& inPosition)
{
    return inPosition->Parent();
}