///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//         This example code is from the book:
//
//           Object-Oriented Programming with C++ and OSF/Motif, 2nd Edition
//         by
//           Douglas Young
//           Prentice Hall, 1995
//           ISBN 0-13-20925507
//
//         Copyright 1995 by Prentice Hall
//         All Rights Reserved
//
//  Permission to use, copy, modify, and distribute this software for 
//  any purpose except publication and without fee is hereby granted, provided 
//  that the above copyright notice appear in all copies of the software.
///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////



//////////////////////////////////////////////////
// Timer.C: A clock class for the stopwatch
///////////////////////////////////////////////////
#include "Timer.h"
#include <Xm/Xm.h>

Timer::Timer ( XtAppContext  app, 
	      TimerCallback callback, 
	      int           interval, 
	      void         *data )
{
    _func     = callback;
    _data     = data;
    _id       = NULL;
    _app      = app;
    _counter  = 0;
    _interval = interval;
}

void Timer::tick()
{
    _counter++;  // Increment a counter for each tick
    
    // Compute the time in seconds and update the Face object
    
    if ( _func )
	(*_func)( elapsedTime(), _data);
    
    // Reinstall the timeout callback
    
    _id = XtAppAddTimeOut ( _app, 
			   _interval, 
			   &Timer::tickCallback, 
			   (XtPointer) this );
}


void Timer::start()
{
    // Reset the elapsed time
    
    _counter = 0;
    
    if ( _id ) // If a previous callback is still in effect, remove it
    {
	XtRemoveTimeOut ( _id );
	_id = NULL;
    }
    
    // Register a function to be called in _interval milliseconds
    
    _id = XtAppAddTimeOut ( _app, 
			   _interval, 
			   &Timer::tickCallback, 
			   (XtPointer) this );
}

void Timer::stop()
{
    // Remove the current timeout function, if any
    
    if ( _id )
	XtRemoveTimeOut ( _id );
    
    _id = NULL;
}

void Timer::tickCallback ( XtPointer clientData, XtIntervalId * )
{
    // Get the object pointer and call the corresponding tick function
    
    Timer *obj = (Timer *) clientData;
    
    obj->tick();
}

float Timer::elapsedTime()
{
    return ( (float) _counter * _interval / 1000.0 );
}

