/*
    MultiNode sample code
    Henry Smith (henry@enigmasoftware.ca)
   
    Data structure representing a node that can belong to multiple trees (families)
*/


#ifndef MultiNodeImpl_H
#define MultiNodeImpl_H

#include <map>
#include "NodeImpl.h"

typedef int FamilyID;

////////////////////////////////////////////////////////////////////////////////
//
//  MultiNodeImpl
//
////////////////////////////////////////////////////////////////////////////////

class MultiNodeImpl
{
    public:
        MultiNodeImpl ();
        virtual ~MultiNodeImpl ();

    // Tree structure accessors

        const MultiNodeRef& Parent () const;
        const MultiNodeRef& Child () const;
        const MultiNodeRef& Sibling () const;

        MultiNodeRef& Parent ();
        MultiNodeRef& Child ();
        MultiNodeRef& Sibling ();

    // Scoped family changer object

        struct FamilyScope
        {
            FamilyID mSavedFamily;

            FamilyScope (FamilyID inFamily) : mSavedFamily(sCurrentFamily) {
                sCurrentFamily = inFamily;
            }

            ~FamilyScope () {
                sCurrentFamily = mSavedFamily;
            }
        };
        friend struct FamilyScope;

    private:
        NodeImpl* GetImpl () const;

    private:
        typedef std::map<FamilyID, NodeImpl> NodeImplMap;
        mutable NodeImplMap mImpls;

        static FamilyID sCurrentFamily;
};

#endif  // MultiNodeImpl_H