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


#include "MultiNodeBase.h"
#include "NodeImpl.h"

////////////////////////////////////////////////////////////////////////////////
//
//  MultiNodeBase
//
////////////////////////////////////////////////////////////////////////////////


MultiNodeBase::MultiNodeBase ()
{
}

MultiNodeBase::~MultiNodeBase ()
{
}

void
MultiNodeBase::AddChildIn (FamilyID inFamily, MultiNodeRef inNode)
{
    FamilyScope fs (inFamily);
    AddChild( inNode );
}

void
MultiNodeBase::RemoveChildIn (FamilyID inFamily, MultiNodeRef inNode)
{
    FamilyScope fs (inFamily);
    RemoveChild (inNode);
}

bool
MultiNodeBase::HasChildrenIn (FamilyID inFamily) const
{
    FamilyScope fs (inFamily);
    return HasChildren();
}

int
MultiNodeBase::CountChildrenIn (FamilyID inFamily) const
{
    FamilyScope fs (inFamily);
    return CountChildren();
}

void
MultiNodeBase::AddChild (MultiNodeRef& inNode)
{
    assert(inNode != NullRef);

    if (Child() == NullRef) {
        Child() = inNode;
    }
    else
    {
        // Seek to end of children
        MultiNodeRef priorNode = Child();
        while (priorNode->Sibling() != NullRef) {
            priorNode = priorNode->Sibling();
        }
        priorNode->Sibling() = inNode;
    }

    inNode->Parent() = this;
}

void
MultiNodeBase::RemoveChild (MultiNodeRef& inNode)
{
    assert(inNode != NullRef);
    assert(Child() != NullRef);
    assert(inNode->Parent() == this);

    // Seek to node prior to input
    MultiNodeRef priorNode = Child();
    while (priorNode->Sibling() != NullRef) {
        priorNode = priorNode->Sibling();
    }
    priorNode->Sibling() = inNode->Sibling();
   
    inNode->Parent() = NullRef;
    inNode->Sibling() = NullRef;

    if (Child() == inNode) {
        Child() = NullRef;
    }
}

bool
MultiNodeBase::HasChildren () const
{
    return (Child() != NullRef);
}

int
MultiNodeBase::CountChildren () const
{
    int count = 0;
    for (MultiNodeRef child = Child(); child != NullRef; child = child->Sibling()) {
        ++count;
    }
    return count;
}