

#ifndef _timer_h_ /* Thu Oct 13 16:22:48 1994 */
#define _timer_h_



/*
 *
 *          Copyright (C) 1995, M. A. Sridhar
 *  
 *
 *     This software is Copyright M. A. Sridhar, 1995. You are free
 *     to copy, modify or distribute this software  as you see fit,
 *     and to use  it  for  any  purpose, provided   this copyright
 *     notice and the following   disclaimer are included  with all
 *     copies.
 *
 *                        DISCLAIMER
 *
 *     The author makes no warranties, either expressed or implied,
 *     with respect  to  this  software, its  quality, performance,
 *     merchantability, or fitness for any particular purpose. This
 *     software is distributed  AS IS.  The  user of this  software
 *     assumes all risks  as to its quality  and performance. In no
 *     event shall the author be liable for any direct, indirect or
 *     consequential damages, even if the  author has been  advised
 *     as to the possibility of such damages.
 *
 */


#if defined(__GNUC__)
#pragma interface
#endif


#include "ui/uidefs.h"     // Include this first.

#include "base/binding.h"
#include "base/map.h"

// Timer  is a  class that provides a simple timer service. When
// constructed, the Timer must be given a binding to be executed.
// Subsequently, the Timer  can be started using its {\tt Start} method,
// specifing the time interval $n$ as parameter. This results in the binding
// being executed periodically, after every $n$ milliseconds. The Timer
// can be stopped using the {\tt Stop} method. 
//
// Multiple Timer instances can be created; the maximum number of Timers
// that can exist simultaneously is platform-dependent.
//
// The resolution of the Timer notification depends on the platform; so if
// you ask for notification every millisecond, you might not get
// it. Moreover, the Timer only guarantees that the notification occurs
// after {\it at least\/} $n$ millisecons have elapsed; it does not
// guarantee accurate timing.
//
// Caveat: the {\tt Start} method (for {\it any\/} Timer instance) can only be
// called {\it after\/} the main window has been displayed.
//
// The Timer implementation under Motif uses {\tt XtAppAddTimeout}, and
// under X_YACL, it uses {\tt gettimeofday}. So it does not use Unix
// signals in either case. It  does, however, use the {\tt select} system
// call. Under X_YACL, the maximum time interval specifiable is about 900
// seconds.

class YACL_UI UI_Timer: public CL_Object {

public:
    UI_Timer ();
    // Default constructor. The resulting timer can be started, tested for
    // running state (via {\tt IsRunning}) and stopped; but it does not
    // notify any other object when the timer expires.
    
    UI_Timer (const CL_AbstractBinding& bnd);
    // Construct a Timer object which will execute the given binding
    // whenever the timer expires. The constructor clones {\tt bnd}, and
    // the Timer destructor destroys the  copy.

    ~UI_Timer ();
    // Destructor. Stops the timer.
    
    bool Start (long msecs);
    // Start the timer. After this method is called, the timer repeatedly
    // executes its binding every {\tt msecs} milliseconds.
    //
    // This method returns TRUE if successful, FALSE if the system's timer
    // resource is not available.  This method can only be
    // called {\it after\/} the main window has been displayed.
    
    bool Stop ();
    // Stop the timer, and do not execute the binding any more.

    bool IsRunning () const { return _running;};
    // Return TRUE if this Timer is currently running.
    
    long TimerID () const {return _id; };
    // Return a platform-dependent timer identifier.
    
protected:
    CL_AbstractBinding* _bind;
    ulong               _id;
    long                _msecs;
    bool                _running;
    
public:

#if defined(__MS_WINDOWS__) || defined(__MS_WIN32__)
    void DoAlarm ();
    // MS-Windows-specific. For YACL internal use only.

#elif defined(__X_MOTIF__)
    static void DoAlarm (void*, ulong*);
    // X-Motif specific. For YACL internal use only.
    
#elif defined(__X_YACL__)
    static void DoAlarm (UI_Timer* tmr);
    // X-windows specific. For YACL internal use only.
    
#elif defined (__OS2__)
    static void DoAlarm (ulong timerId);

protected:
    static CL_IntPtrMap _TimerMap;
#endif
};





// A OneShotTimer is a Timer that runs only once -- it does not provide
// repeated alarms.

class YACL_UI UI_OneShotTimer: public UI_Timer {


public:
    UI_OneShotTimer ();

private:
    bool Expired ();
};


#endif /* _timer_h_ */
