// This may look like C code, but it is really -*- C++ -*-
// 
// <copyright> 
//  
//  Copyright (c) 1995
//  Institute for Information Processing and Computer Supported New Media (IICM), 
//  Graz University of Technology, Austria. 
//  
// </copyright> 
// 
// 
// <file> 
// 
// Name:        timerman.C
// 
// Purpose:     decouple timer events and Dispatcher
// 
// Created:     28 Mar 96   Joerg Faschingbauer
// 
// Modified:    
// 
// Description: 
// 
// $Id: timerman.C,v 1.5 1997/02/12 23:13:11 jfasch Exp $
// 
// $Log: timerman.C,v $
// Revision 1.5  1997/02/12 23:13:11  jfasch
// moved from HgDcCommon
//
// Revision 1.4  1996/10/03 12:02:50  jfasch
// verbose.h and assert.h moved
//
// Revision 1.3  1996/07/22 08:18:19  jfasch
// *** empty log message ***
//
// Revision 1.2  1996/07/08 13:16:36  jfasch
// *** empty log message ***
//
// Revision 1.1  1996/05/23 14:47:05  jfasch
// Initial revision
//
// 
// </file> 
#include "timerman.h"

#include "dispatcher.h"
#include "iohandler.h"
#include "timerhandler.h"

#include <hyperg/utils/list.h>
#include <hyperg/utils/new.h>
#include <hyperg/utils/verbose.h>



class THandler : public IOHandler, public DLListNode {
public:
   THandler (TimerManager* m, TimerHandler* h) : m(m), h(h) {}

   virtual void timerExpired (long, long) ;

   TimerManager* m ;
   TimerHandler* h ;

private:
   THandler (const TimerHandler&) {}
   THandler& operator = (const TimerHandler&) { return *this; }
} ;
DLListdeclare (THandlerList, THandler) ;

void THandler :: timerExpired (long sec, long usec) {
   m->remove_handler_(this) ;
   h->timerExpired (sec, usec) ;
   HGDELETE (this) ;
}

// --------------------------------------------------------------------
TimerManager* TimerManager :: instance_ = nil ;

TimerManager& TimerManager :: instance() {
   return instance_? *instance_: *(instance_=HGNEW(TimerManager)) ;
}

TimerManager :: TimerManager() 
: handlers_(HGNEW (THandlerList)) {}

void TimerManager :: startTimer (long sec, long usec, TimerHandler* h) {
   DEBUGNL ("TimerManager::startTimer()") ;
   THandler* th = HGNEW (THandler (this, h)) ;
   handlers_->addTail (th) ;
   Dispatcher::instance().startTimer (sec, usec, th) ;
}

void TimerManager :: stopTimer (TimerHandler* h) {
   DEBUGNL ("TimerManager::stopTimer()") ;
   THandler* run = handlers_->getFirst() ;
   while (run) {
      THandler* next = handlers_->getNext (run) ;
      if (run->h == h) {
         handlers_->remove (run) ;
         Dispatcher::instance().stopTimer (run) ;
         HGDELETE (run) ;
      }
      run = next ;
   }
}

void TimerManager :: remove_handler_(THandler* h) {
   DEBUGNL ("TimerManager::remove_handler_()") ;
   handlers_->remove (h) ;
}
