#ifndef CALLBACK_H
#define CALLBACK_H

//----------------------------------------
// l i b r a r y c o d e 
// This code is based on Paul Jakubik's code at
// http://www.primenet.com/~jakubik/source-automatically-detect-types.html
// Copyright © 1996-1997 Paul Jakubik
// Modified by Danelle Cline for the Genosensor Project, MBARI 1998
//----------------------------------------
#include "const.h"
#include "types.h"

//----------------------------------------
template <class P1>
class CallbackBase
{
public:
  virtual ~CallbackBase() {}
  virtual void operator()(P1 p1) const = 0;
};
//----------------------------------------
template <class P1, class Client, class Member>
class CallbackBaseBody: public CallbackBase<P1>
{
public:
  CallbackBaseBody(Client& client, Member member_):
  _client (client),
  _member (member_)
  {};
  void operator()(P1 parm) const
  {((&_client)->*_member)(parm);} 
  
private:
  Client &_client;
  Member _member;
};
//----------------------------------------
template <class Client, class TRT, class CallType, class TP1>
inline CallbackBase<TP1> *
newCallback(Client& client, TRT (CallType::* const& memFunc)(TP1))
{
  typedef TRT (CallType::*PMEMFUNC)(TP1);
  return new CallbackBaseBody<TP1,Client,PMEMFUNC>(client, memFunc);
}
//----------------------------------------
class CallbackObject
{
public:
  CallbackObject(CallbackBase<CallbackObject*>* callback):
	  _pCallback (callback){  enable(); };
	  
  virtual ~CallbackObject(){delete _pCallback;};

  virtual void call() { (*_pCallback)(this);}
  void enable() {_enabled = 1;}
  void disable() {_enabled = 0;}
  MBool enabled() { return _enabled;};
private:
  MBool _enabled;
protected:
  const CallbackBase<CallbackObject*>* _pCallback;  
};

#endif