/* Proto.H: nodes defined through the PROTO or EXTERNPROTO mechanism */

#ifndef _PROTO_H_
#define _PROTO_H_

#include <string.h>
#include "vrml.H"
#include "Assoc.H"

class comparable_string {
  char *s;
public:
  comparable_string(char *t =0) { s = t; }
  operator char*() 		{ return s; }
  int operator==(char* t) 	{ return ((!s && !s) || (s && t && strcmp(s,t)==0)); }
};

typedef assoc<comparable_string, SFNode *> namedNodeTable;

class Proto: public SFNode {
  SFNode *master;	// this nodes interface is refered to 
  MFNode *sceneGraph;	// in this sceneGraph.

  void bind(void);
  void unbind(void);

public:
  namedNodeTable namedNodes;	// named nodes in implementation

  // constructs a Proto node with master 'm' and scene graph 'sg'
  Proto(SFNode *m, MFNode *sg, const namedNodeTable& nn)
  {
    SFNode::construct(m->typeId, m->nrInterfaceDeclarations, m->interface);
    master = m;
    sceneGraph = sg;
    namedNodes = nn;
  }

  SFNode *firstnode(void)
  {
    if (!sceneGraph || sceneGraph->size <= 0)
      return this;	// return something meaningful
    else
      return (*sceneGraph)[0]->firstnode();
  }

  // creates an instance of 'this' in which redirected fields and events will
  // point to the interface of 'master'.
  SFNode *instantiate(Proto *master =0);

  void render(void);
  void synchronize(void);

  ostream& print(ostream& s =cout);
};

#endif /*_PROTO_H_*/
