#ifndef _PROTO_TIME
#define _PROTO_TIME

#include "protoDefs.h"

/**
 * @class ProtoTime
 *
 * @brief System time conversion routines.
 */

class ProtoTime
{
    public:
        ProtoTime();
        ProtoTime(const struct timeval& theTime);
        ProtoTime(double seconds);
        ProtoTime(unsigned long sec, unsigned long usec);
            
        ProtoTime& GetCurrentTime() 
        {
            ProtoSystemTime(tval);
            return *this;
        }
    
        unsigned long sec() const
            {return ((unsigned long)tval.tv_sec);}
        unsigned long usec() const
            {return ((unsigned long)tval.tv_usec);}
        unsigned long nsec() const
            {return ((unsigned long)(1000* tval.tv_usec));}
        
        double GetValue() const
        {
            double val = (double)sec();
            val += 1.0e-06 * (double)usec();
            return val;
        }
        double GetOffsetValue() const;
        
	    bool IsZero() const
	        {return ((0 == tval.tv_sec) && (0 == tval.tv_usec));}
        void Zeroize()
            {tval.tv_sec = tval.tv_usec = 0;}
                
        
        const struct timeval& GetTimeVal() const
            {return tval;}
        struct timeval& AccessTimeVal()
            {return tval;}
        
        void operator+=(const ProtoTime& t);
        void operator+=(double seconds)
        {
            ProtoTime t(seconds);
            *this += t;
        }
        void operator-=(double seconds);
        bool operator==(const ProtoTime& t) const
        {
            return ((sec() == t.sec()) &&
                    (usec() == t.usec()));
        }
        bool operator!=(const ProtoTime& t) const
            {return !(*this == t);}
        bool operator>(const ProtoTime& t) const
        {
            return ((sec() > t.sec()) ||
                     ((sec() == t.sec()) &&
                      (usec() > t.usec())));
        }
        bool operator>=(const ProtoTime& t) const
        {
            return ((sec() > t.sec()) ||
                     ((sec() == t.sec()) &&
                      (usec() >= t.usec())));
        }
        bool operator<(const ProtoTime& t) const
        {
            return ((sec() < t.sec()) ||
                     ((sec() == t.sec()) &&
                      (usec() < t.usec())));
        }
        bool operator<=(const ProtoTime& t) const
        {
            return ((sec() < t.sec()) ||
                     ((sec() == t.sec()) &&
                      (usec() <= t.usec())));
        }
        
        // Computes (t1 - t2)
        static double Delta(const ProtoTime& t1, const ProtoTime& t2);
        double operator-(const ProtoTime& t)
            {return Delta(*this, t);}    
    
    private:
        // (TBD) for now we use struct timeval for convenience, but in future
        //       we may want to control the layout of the struct so it can be
        //       used in a ProtoSortedTree as a sortable key.
        //       We also may want to maintain more _precise_ time as well
        struct timeval tval;        
        
};  // end class ProtoTime

#endif // _PROTO_TIME
