////////////////////////////////////////////////////////////////////////////////
// Timer.h -- this file is part of the Emulator Developers Kit
// available at http://ourworld.compuserve.com/homepages/pc64/develop.htm

class Timer : public Object {

  // absolute time when to call the OnFire function
  int iClocks;

  // function to call when the timer reaches 0
  pfn pfnOnFire;

  // pointers to the next/previous timer in the list
  Timer* pNextTimer;
  Timer* pPrevTimer;

  // pointer to Clock::TimerRoot, the head of the active timer list
  Timer* pTimerRoot;

  // the Clock class needs to call the OnFire functions
  friend Clock;
  global void Fire();

public:

  // constructor
  global Timer() {
    iClocks = 0;
    pfnOnFire = NULL;
    pNextTimer = NULL;
    pPrevTimer = NULL;
    pTimerRoot = NULL;
  }

  // destructor
  virtual ~Timer() {
    if (IsCounting()) {
      StopCounter();
    }
  }

  // set a new clock
  global virtual void SetClock(Clock& NewClock);

  // the OnFire function is called when the counter reaches 0
  inline void SetOnFire(pfn pfnNewOnFire)                                                           { pfnOnFire = pfnNewOnFire; }
  inline pfn GetOnFire()                                                                            { return pfnOnFire; }

  // counter access
  global void StartCounter(int iNewClocks);
  global void StopCounter();
  inline int ReadCounter()                                                                          { assert(IsCounting()); return (iClocks - (pTimerRoot->iClocks + pTimerRoot->pNextTimer->iClocks)) & INT_MAX; }
  inline flag IsCounting()                                                                          { return pPrevTimer != NULL; }

  // check the timer list for errors
  global void AssertValid();
};
