#ifndef COSY_Timer
#define COSY_Timer

struct timeval;

class ostream;

class Timer
{
    friend ostream &operator<<(ostream &out, Timer &t);
private:
    double fMs;  // Microsec in units of sec as returned by gettimeofday
    int fSecs;   // Seconds as returned by gettimeofday

    int fSec;    // Sec of time
    int fMin;    // Min of time
    int fHor;    // Hor of time
    int fDay;    // Day of time
    int fMon;    // Mon of time
    int fYea;    // Yea of time

    double fDiv; // Division of day
    double fMjd; // MJD

    char fDateStr[30];

    //void Set(const long mjd);

public:
    Timer(int d, int m, int y, int h, int min, int s, double ms)
        : fMs(ms), fSecs(0), fSec(s), fMin(m), fHor(h), fDay(d), fMon(m), fYea(y), fDiv(0), fMjd(0) {}
    Timer() : fMs(0), fSecs(0), fSec(0), fMin(0), fHor(0), fDay(0), fMon(0), fYea(0), fDiv(0), fMjd(0) {}
    Timer(double t);
    Timer(struct timeval *tv);
    Timer(const Timer &t);

    void SetTimer(int tv_sec, double tv_usec);
    void SetTimer(const struct timeval *tv);
    void SetTimer(int y, int m, int d, int h, int min, int s, double ms)
    {
        fMs = ms;
        fSec = s;
        fMin = min;
        fHor = h;
        fDay = d;
        fMon = m;
        fYea = y;
    }

    void GetTimeval(struct timeval *tv) const;

    int GetSecs() { return fSecs; }

    double Now(); //[s]
    double GetMjd() const { return fMjd/*+fDiv*/; }

    virtual void SetMjd(double mjd);

    int Day() const   { return fDay; }
    int Month() const { return fMon; }
    int Year() const  { return fYea; }

    int H() const { return fHor; }
    int M() const { return fMin; }
    int S() const { return fSec; }
    int MilliSec() const { return (int)(fMs*1000); }
    double MicroSec() const { return fMs; }

    const char *GetTimeStr();

    void Print();

    operator double() const; //[s]
};

ostream &operator<<(ostream &out, Timer &t);

#endif
