//a jpa creation, all of this
#ifndef  _QV_TRAVERSE_
#define  _QV_TRAVERSE_

//the first param, the void *, is the pointer to the class that's
//being traversed; the second is user data
typedef void TraverseCBType (void *, QvState *, void *); 

class IVCallBacks {
public:
  IVCallBacks (void) : num_registered (0) {}

  void callTraverse (const char *name, void *ptrthis, QvState *state) {
    //we go backwards so that the latest registered CB gets called.
    for (int i = (num_registered - 1); i >= 0; i--)
      {
//cerr << "looking for " << name << ", comparing with " << assocs[i].name << endl;
	if (strcmp (name, assocs[i].name) == 0)
	  {
	    if (assocs[i].cb)
	      (*assocs[i].cb) (ptrthis, state, assocs[i].userdata);
	    break;
	  }
      }
    //if there's a callback registered for name, call it with state
  };

  void registerCB (const char *name, TraverseCBType *cb, void *userdata) {
  //this # is unknown to me.
#define NUM_IV_CLASSES 50

    if (num_registered == NUM_IV_CLASSES)
      {
	cerr << "IVCallBacks class in QvTraverse.h is overloaded! increase NUM_IV_CLASSES constant." << endl;
      }
    else
      {
	//add name/cb to array of cb's.
	strcpy (assocs[num_registered].name, name);
	assocs[num_registered].userdata = userdata;
	assocs[num_registered++].cb = cb;
      }
  };
private:
  struct CBAssoc {
    char name [50]; //name of the class to register CB with
    TraverseCBType *cb; //what to call
    void *userdata;
  };

  CBAssoc assocs [NUM_IV_CLASSES];

  int num_registered;
};

extern IVCallBacks *callbacks;
#endif /* _QV_TRAVERSE_ */
