#ifndef MARS_MTime
#define MARS_MTime

/////////////////////////////////////////////////////////////////////////////
//                                                                         //
// MTime                                                                   //
//                                                                         //
// A generalized MARS time stamp                                           //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////

#ifndef MARS_MParContainer
#include "MParContainer.h"
#endif

class MTime : public MParContainer
{
private:
    //UInt_t   fTimeStamp[2]; // type of raw event which should be processed by this task
    UInt_t   fDuration;     // time of validity

    Byte_t   fHour;
    Byte_t   fMin;
    Byte_t   fSec;
    UInt_t   fNanoSec;

public:
    MTime(const char *name=NULL, const char *title=NULL)
    {
        fName = name ? name : ClassName();
        fTitle = title;

        SetTime((ULong_t)0);
    }

    MTime(MTime& t) { *this = t; }

    void operator=(MTime &t)
    {
        fDuration = t.fDuration;
        fHour     = t.fHour;
        fMin      = t.fMin;
        fSec      = t.fSec;
        fNanoSec  = t.fNanoSec;
    }

    void Print(Option_t *t=NULL) const;

    void SetCT1Time(UInt_t t1, UInt_t t0)
    {
        // int   isecs_since_midday; // seconds passed since midday before sunset (JD of run start)
        // int   isecfrac_200ns;     // fractional part of isecs_since_midday
        // fTime->SetTime(isecfrac_200ns, isecs_since_midday);
        fNanoSec  = 200*t1;
        fSec      = t0%60;
        t0 /= 60;
        fMin      = t0%60;
        t0 /= 60;
        fHour     = (t0+12)%24;
    }

    void SetTime(ULong_t t)
    {
        // t [millisec]
        fNanoSec  = (t*1000000)%1000;
        t /= 1000;
        fSec      = t%60;
        t /= 60;
        fMin      = t%60;
        t /= 60;
        fHour     = t%24;
    }

    void SetTime(Double_t t)
    {
        // t [s]
        fNanoSec  = (UInt_t)(fmod(t, 1)*1e9);
        fSec      = (Byte_t)fmod(t, 60);
        t /= 60;
        fMin      = (Byte_t)fmod(t, 60);
        t /= 60;
        fHour     = (Byte_t)fmod(t, 24);
    }

    void SetTime(Byte_t h, Byte_t m, Byte_t s, UInt_t ns)
    {
        fHour    = h;
        fMin     = m;
        fSec     = s;
        fNanoSec = ns;
    }

    void SetDuration(UInt_t t)
    {
	fDuration = t;
    }

    MTime *GetTime()
    {
        return this;
    }

    UInt_t GetDuration()
    {
	return fDuration;
    }

    operator double() const //[s]
    {
        return fNanoSec/1e9+(fHour*24*60*60+fMin*60+fSec);
    }
    double operator()() const //[s]
    {
        return operator double();
    }

    Byte_t GetHour() const { return fHour; }
    Byte_t GetMin() const { return fMin; }
    Byte_t GetSec() const { return fSec; }
    UInt_t GetNanoSec() const { return fNanoSec; }

    ClassDef(MTime, 2)	//A generalized MARS time stamp
};

inline Double_t operator-(MTime &t1, MTime &t2)
{
    return t1()-t2();
}

inline Bool_t operator<(MTime &t1, MTime &t2)
{
    return t1()<t2();
}

inline Bool_t operator>(MTime &t1, MTime &t2)
{
    return t1()>t2();
}

inline Bool_t operator<=(MTime &t1, MTime &t2)
{
    return t1<=t2();
}

inline Bool_t operator>=(MTime &t1, MTime &t2)
{
    return t1()>=t2();
}

inline Bool_t operator==(MTime &t1, MTime &t2)
{
    return t1()==t2();
}

#endif
