#include <spies.h>

///////////////////////////////////////////////////////////
// TSpy_target
///////////////////////////////////////////////////////////

void TSpy_target::notify(TSpy_message msg, void* pJolly)
{
  for (int i = _spies.last(); i >= 0; i = _spies.pred(i))
  {
    TSpy* spy = (TSpy*)_spies.objptr(i);
    spy->notify(msg, pJolly);
  }
}

bool TSpy_target::add_spy(TSpy* spy)
{
#ifdef DBG
  for (int i = _spies.last(); i >= 0; i--)
  {
    TSpy* s = (TSpy*)_spies.objptr(i);
    if (s == spy)
    {
      NFCHECK("Double spy");
      return FALSE;
    }
  }
#endif
  _spies.add(spy);
  return TRUE;
}

bool TSpy_target::kill_spy(const TSpy* spy)
{
	int i;
  for (i = _spies.last(); i >= 0; i--)
  {
    TSpy* s = (TSpy*)_spies.objptr(i);
    if (s == spy)
    {
      _spies.destroy(i, TRUE);
      break;
    }
  }
#ifdef DBG
  if (i < 0)
    NFCHECK("Spy not found");
#endif
  return i >= 0;
}

TSpy_target::~TSpy_target()
{
  notify(spy_delete, NULL);
}

///////////////////////////////////////////////////////////
// TSpy
///////////////////////////////////////////////////////////

void TSpy::spy(TSpy_target* t)
{
  if (_target)
    _target->kill_spy(this);
  _target = t;
  if (_target)
    _target->add_spy(this);
}

void TSpy::notify(TSpy_message msg, void* pJolly)
{
  CHECK (_target, "Unemployed spy notified");
  if (_notify)
    _notify(*this, msg, pJolly);
  if (msg == spy_delete)
    spy(NULL);
}

TSpy::~TSpy()
{
  spy(NULL);
}