#ifndef __SPIES_H
#define __SPIES_H

#ifndef __ARRAY_H
#include <array.h>
#endif

enum TSpy_message { spy_delete, spy_change };

class TSpy_target : public TObject
{
  friend class TSpy;
  TPointer_array _spies;

protected:
  bool add_spy(TSpy* spy);
  bool kill_spy(const TSpy* spy);

  void notify(TSpy_message msg, void* hint);

public:
  void notify_change(void* hint = NULL) { notify(spy_change, hint); }

  TSpy_target() { }
  virtual ~TSpy_target();
};

typedef void (*SPY_NOTIFY)(TSpy& spy, TSpy_message msg, void* pJolly);

class TSpy : public TObject
{
  friend class TSpy_target;

  TSpy_target* _target;
  SPY_NOTIFY _notify;
  bool _dirty;

protected:
  virtual void notify(TSpy_message msg, void* pJolly);

public:
  TSpy_target* target_ptr() const { return _target; }
  TSpy_target& target() const { CHECK(_target, "NULL spy target"); return *_target; }

  void spy(TSpy_target* t);
  void set_notify(SPY_NOTIFY sn) { _notify = sn; }
  bool dirty() { bool d = _dirty; _dirty = FALSE; return d; }

  TSpy() : _target(NULL), _notify(NULL), _dirty(FALSE) { }
  TSpy(TSpy_target* t) : _target(NULL), _notify(NULL) { spy(t); }
  virtual ~TSpy();
};

#endif