// **********************************************************************
//
// Copyright (c) 1999
// Object Oriented Concepts, Inc.
// Billerica, MA, USA
//
// All Rights Reserved
//
// **********************************************************************

#ifndef OB_TIMER_H
#define OB_TIMER_H

//
// The OBTimer class
//
class OBTimer 
{
    friend class OBTimerList;

    //
    // Hide copy-constructor and asignment operator
    //
    OBTimer(const OBTimer&);
    void operator=(const OBTimer&);

protected:

    OBTimer* next_; // Next timer in list
    bool activated_; // Set to true if activated
    timeval timeout_; // The timeout value

    // 
    // Timers are used only as sub classes
    // The bool parameter indicates if timeval is a relativ value
    //
    OBTimer();
    OBTimer(const timeval&, bool = false);
    virtual ~OBTimer();

public:

    //
    // Notification called when timer expires
    //
    virtual void notify() = 0;

    //
    // Activate and stop the timer
    //
    void activate(const timeval&, bool = false);
    void stop();

    bool activated() { return activated_; }
    
    //
    // Get the timeout value
    //
    const timeval& timeout() const { return timeout_; }
};

//
// The OBTimerList class
//
class OBTimerList
{
    //
    // Hide copy-constructor and asignment operator
    //
    OBTimerList(const OBTimerList&);
    void operator=(const OBTimerList&);

protected:

    //
    // The timer list singleton
    //
    static OBTimerList* instance_;
    friend class OBTimerListDestroyer;

    //
    // The head of the timer list
    //
    OBTimer* head_;

    OBTimerList();
    ~OBTimerList();

public:

    //
    // Expire expired timers
    // Returns the number of timers that have expired
    //
    unsigned int expire(const timeval&);

    //
    // Expire one expired timer
    // Returns true if one timer has expired
    //
    bool expireOneTimer(const timeval&);

    //
    // List handling
    //
    bool isEmpty() const { return head_ == 0; }
    OBTimer* first() const { return head_; }
    void add(OBTimer*);
    void remove(OBTimer*);

    //
    // Get the TimerList singleton
    //
    static OBTimerList* instance();

    //
    // Helper functions for handling timeval values
    //
    static int timeCmp(const timeval&, const timeval&);
    static timeval timeSub(const timeval&, const timeval&);
    static timeval timeAdd(const timeval&, const timeval&);
    static timeval timeNow();
};

#endif
