//  The C++ Booch Components (Version 2.0)
//  (C) Copyright 1990-1993 Grady Booch. All Rights Reserved.
//
//  BCNodes.h
//
//  This file contains the declaration of various node classes.
 
#ifndef BCNODES_H
#define BCNODES_H 1

#include <stddef.h>
#include "BCType.h"

// Class denoting an Item/Value pair

template<class Container_Item, class Container_Value>
class BC_TPair {
public:

  BC_TPair();
  BC_TPair(const Container_Item& item)
    : fRepItem(item)
    {}
  BC_TPair(const Container_Item& item, const Container_Value& value)
    : fRepItem(item),
      fRepValue(value)
    {}
  BC_TPair(const BC_TPair<Container_Item, Container_Value>& a)
    : fRepItem(a.fRepItem),
      fRepValue(a.fRepValue)
    {}

  BC_TPair<Container_Item, Container_Value>& operator=(const BC_TPair<Container_Item, Container_Value>& a)
    {fRepItem = a.fRepItem;
     fRepValue = a.fRepValue;
     return *this;}
  BC_Boolean operator==(const BC_TPair<Container_Item, Container_Value>& a) const
    {return (fRepItem == a.fRepItem);}
  BC_Boolean operator!=(const BC_TPair<Container_Item, Container_Value>& a) const
    {return !operator==(a);}

  Container_Item fRepItem;
  Container_Value fRepValue;

};

// Class denoting a simple node consisting of an item and pointers to
// the previous and next Items

template<class Container_Item, class Storage_Manager>
class BC_TNode {
public:

  BC_TNode(const Container_Item& i, BC_TNode<Container_Item, Storage_Manager>* previous,
  						  BC_TNode<Container_Item, Storage_Manager>* next)
    : fRepItem(i),
      fRepPrevious(previous),
      fRepNext(next)
    {if (previous)
       previous->fRepNext = this;
     if (next)
       fRepNext->fRepPrevious = this;}

  Container_Item fRepItem;
  BC_TNode<Container_Item, Storage_Manager>* fRepPrevious;
  BC_TNode<Container_Item, Storage_Manager>* fRepNext;

  static void* operator new(size_t);
  static void operator delete(void*, size_t);

};

// Class denoting a simple node consisting of an item, a pointer to
// the next item, and a reference count

template<class Container_Item, class Storage_Manager>
class BC_TSingleNode {
public:

  BC_TSingleNode(const Container_Item& i, BC_TSingleNode* next)
    : fRepItem(i),
      fRepNext(next),
      fRepCount(1) {}
  ~BC_TSingleNode();

  Container_Item fRepItem;
  BC_TSingleNode<Container_Item, Storage_Manager>* fRepNext;
  BC_Index fRepCount;

  static void* operator new(size_t);
  static void operator delete(void*, size_t);

};

// Class denoting a simple node consisting of an item, pointers to
// the previous and next items, and a reference count

template<class Container_Item, class Storage_Manager>
class BC_TDoubleNode {
public:

  BC_TDoubleNode(const Container_Item& i, BC_TDoubleNode* previous, BC_TDoubleNode* next)
    : fRepItem(i),
      fRepPrevious(previous),
      fRepNext(next),
      fRepCount(1)
    {if (previous)
       previous->fRepNext = this;
     if (next)
       fRepNext->fRepPrevious = this;}
  ~BC_TDoubleNode();

  Container_Item fRepItem;
  BC_TDoubleNode<Container_Item, Storage_Manager>* fRepPrevious;
  BC_TDoubleNode<Container_Item, Storage_Manager>* fRepNext;
  BC_Index fRepCount;

  static void* operator new(size_t);
  static void operator delete(void*, size_t);

};

// Class denoting a simple node consisting of an item, a pointer to
// the parent, pointers to the left and right items, and a reference count

template<class Container_Item, class Storage_Manager>
class BC_TBinaryNode {
public:

  BC_TBinaryNode(const Container_Item& i, BC_TBinaryNode* parent,
                 BC_TBinaryNode* left, BC_TBinaryNode* right)
    : fRepItem(i),
      fRepParent(parent),
      fRepLeft(left),
      fRepRight(right),
      fRepCount(1)
    {if (left)
       fRepLeft->fRepParent = this;
     if (right)
       fRepRight->fRepParent = this;}
  ~BC_TBinaryNode();

  Container_Item fRepItem;
  BC_TBinaryNode<Container_Item, Storage_Manager>* fRepParent;
  BC_TBinaryNode<Container_Item, Storage_Manager>* fRepLeft;
  BC_TBinaryNode<Container_Item, Storage_Manager>* fRepRight;
  BC_Index fRepCount;

  static void* operator new(size_t);
  static void operator delete(void*, size_t);

};

// Class denoting a simple node consisting of an item, a pointer to
// the parent, pointers to the child and sibling items, and a reference count

template<class Container_Item, class Storage_Manager>
class BC_TMultiwayNode {
public:

  BC_TMultiwayNode(const Container_Item& i, BC_TMultiwayNode* parent,
                   BC_TMultiwayNode* child, BC_TMultiwayNode* sibling)
    : fRepItem(i),
      fRepParent(parent),
      fRepChild(child),
      fRepSibling(sibling),
      fRepCount(1)
    {if (child)
       fRepChild->fRepParent = this;}
  ~BC_TMultiwayNode();

  Container_Item fRepItem;
  BC_TMultiwayNode<Container_Item, Storage_Manager>* fRepParent;
  BC_TMultiwayNode<Container_Item, Storage_Manager>* fRepChild;
  BC_TMultiwayNode<Container_Item, Storage_Manager>* fRepSibling;
  BC_Index fRepCount;

  static void* operator new(size_t);
  static void operator delete(void*, size_t);

};

// Forward declarations

template<class Vertex_Item, class Arc_Item, class Storage_Manager>
class BC_TVertexNode;

template<class Vertex_Item, class Arc_Item, class Storage_Manager>
class BC_TArcNode;

// Class denoting a simple node consisting of an item, a pointer to
// the enclosing context, a pointer to the next vertex, pointers to the 
// outgoing and incoming arcs, and a reference count

template<class Vertex_Item, class Arc_Item, class Storage_Manager>
class BC_TVertexNode {
public:

  BC_TVertexNode(const Vertex_Item& i, void* enclosing, 
                 BC_TArcNode<Vertex_Item, Arc_Item, Storage_Manager>* in,
                 BC_TArcNode<Vertex_Item, Arc_Item, Storage_Manager>* out,
                 BC_TVertexNode* next)
    : fRepItem(i),
      fRepEnclosing(enclosing),
      fRepIn(in),
      fRepOut(out),
      fRepNext(next),
      fRepCount(1) {}
  ~BC_TVertexNode();

  Vertex_Item fRepItem;
  void* fRepEnclosing;
  BC_TArcNode<Vertex_Item, Arc_Item, Storage_Manager>* fRepIn;
  BC_TArcNode<Vertex_Item, Arc_Item, Storage_Manager>* fRepOut;
  BC_TVertexNode<Vertex_Item, Arc_Item, Storage_Manager>* fRepNext;
  BC_Index fRepCount;

  static void* operator new(size_t);
  static void operator delete(void*, size_t);

};

// Class denoting a simple node consisting of an item, a pointer to
// the enclosing context, a pointer to the next arc, pointers to the 
// vertices to and from the arc, and a reference count

template<class Vertex_Item, class Arc_Item, class Storage_Manager>
class BC_TArcNode {
public:

  BC_TArcNode(const Arc_Item& i, void* enclosing,
              BC_TVertexNode<Vertex_Item, Arc_Item, Storage_Manager>* from,
              BC_TVertexNode<Vertex_Item, Arc_Item, Storage_Manager>* to,
              BC_TArcNode* next_in,  BC_TArcNode* next_out)
    : fRepItem(i),
      fRepEnclosing(enclosing),
      fRepFrom(from),
      fRepTo(to),
      fRepNextIn(next_in),
      fRepNextOut(next_out),
      fRepCount(1) {}
  ~BC_TArcNode();

  Arc_Item fRepItem;
  void* fRepEnclosing;
  BC_TVertexNode<Vertex_Item, Arc_Item, Storage_Manager>* fRepFrom;
  BC_TVertexNode<Vertex_Item, Arc_Item, Storage_Manager>* fRepTo;
  BC_TArcNode<Vertex_Item, Arc_Item, Storage_Manager>* fRepNextIn;
  BC_TArcNode<Vertex_Item, Arc_Item, Storage_Manager>* fRepNextOut;
  BC_Index fRepCount;

  static void* operator new(size_t);
  static void operator delete(void*, size_t);

};

#endif
