// =====================================================================
/*!
//
//  \file TSystemTimer.hh
//  \brief This file contains the TSystemTimer class.
//  \author Go IWAI <goiwai@users.sourceforge.jp>
//
//  $Id: TSystemTimer.hh,v 1.7 2004/03/07 10:30:34 goiwai Exp $
//  $Name: CLDAQ-1-14-06 $
//  $Log: TSystemTimer.hh,v $
//  Revision 1.7  2004/03/07 10:30:34  goiwai
//  ROOTに組みこむためのおまじないマクロを埋めこみました。
//  全てにおいて完全に動作するわけではありません。
//
//  Revision 1.6  2004/03/07 07:29:38  goiwai
//  TSystemTimer::WhatTimeIsItNow()が実装されてなかったので実装しました。
//
//  Revision 1.5  2004/01/19 21:09:43  goiwai
//  プリプロセッサの接頭辞をCLDAQ__に変更しました.
//
//  Revision 1.4  2003/11/03 08:35:15  goiwai
//  Doxygen用のタグとコメントをうちこんでいく試みを開始しました.
//
//  Revision 1.3  2003/10/06 16:37:49  goiwai
//  *** empty log message ***
//
//  Revision 1.2  2003/07/30 16:21:21  goiwai
//  ファイルにコミットログをつけることにしました.
//
*/
// =====================================================================
#ifndef CLDAQ__TSYSTEMTIMER_HH
#define CLDAQ__TSYSTEMTIMER_HH

#include "Tglobals.h"


/*!
// \example
//
// If example code exists.
//
*/

/*!
// \class TSystemTimer
// \brief This is the TSystemTimer class.
// \author Go IWAI <goiwai@users.sourceforge.jp>
//
// The TSystemTimer class detail description.
// Write it down ASAP!
//
// \todo None?
// \bug None?
// \ingroup SystemCategory
*/
class TSystemTimer
{

  private:
    enum { tUndefined = -1, tIdle, tReady, tRunning };

  private:
    Tint theStatus;
    Tstring theUnit;
    Tdouble theBeginOfRealTime;
    Tdouble theEndOfRealTime;
    Tdouble theBeginOfSystemTime;
    Tdouble theEndOfSystemTime;
    Tdouble theBeginOfUserTime;
    Tdouble theEndOfUserTime;
    Tdouble thePausedTime;
    Tdouble theRunningTime;
    Tdouble theIdlingTime;
    TdoubleList theRealLapTime;
    TdoubleList theSystemLapTime;
    TdoubleList theUserLapTime;

  public:
    TSystemTimer( const Tstring& theUnit = Tsec );
    TSystemTimer( const TSystemTimer& right );
    ~TSystemTimer();

  public:
    Tint GetStatus() const;
    Tdouble GetBeginOfRealTime() const;
    Tdouble GetEndOfRealTime() const;
    Tdouble GetBeginOfSystemTime() const;
    Tdouble GetEndOfSystemTime() const;
    Tdouble GetBeginOfUserTime() const;
    Tdouble GetEndOfUserTime() const;
    Tdouble GetPausedTime() const;
    Tdouble GetRunningTime() const;
    Tdouble GetIdlingTime() const;
    const TdoubleList& GetRealLapTime() const;
    const TdoubleList& GetSystemLapTime() const;
    const TdoubleList& GetUserLapTime() const;
    const Tstring& GetUnit() const;
    Tint GetNumberOfLaps() const;
    Tstring WhatTimeIsItNow() const;
    Tvoid SetUnit( const Tstring& unit );

  public:
    const TSystemTimer& operator=( const TSystemTimer& right );
    friend Tostream& operator<<( Tostream& tos, const TSystemTimer& right );

  public:
    Tvoid Start();
    Tvoid Pause();
    Tvoid Stop();
    Tvoid Lap();
    Tvoid Restart();

  private:
    Tvoid initialize();
    Tvoid clear();
    Tvoid start();
    Tvoid pause();
    Tvoid stop();
    Tvoid lap();
    Tvoid restart();
    Tvoid convertTimeScale( Tdouble factor );

  public:
    Tdouble GetRealElapsedTime();
    Tdouble GetSystemElapsedTime();
    Tdouble GetUserElapsedTime();
    Tdouble GetTotalRunningTime();
    Tdouble GetTotalIdlingTime();

#ifdef __CLDAQ_ROOT_DLL
    ClassDef(TSystemTimer,0)
#endif

};

inline Tint TSystemTimer::GetStatus() const
{
  return theStatus;
}

inline Tdouble TSystemTimer::GetBeginOfRealTime() const
{
  return theBeginOfRealTime;
}

inline Tdouble TSystemTimer::GetEndOfRealTime() const
{
  return theEndOfRealTime;
}

inline Tdouble TSystemTimer::GetBeginOfSystemTime() const
{
  return theBeginOfSystemTime;
}

inline Tdouble TSystemTimer::GetEndOfSystemTime() const
{
  return theEndOfSystemTime;
}

inline Tdouble TSystemTimer::GetBeginOfUserTime() const
{
  return theBeginOfUserTime;
}

inline Tdouble TSystemTimer::GetEndOfUserTime() const
{
  return theEndOfUserTime;
}

inline Tdouble TSystemTimer::GetPausedTime() const
{
  return thePausedTime;
}

inline Tdouble TSystemTimer::GetRunningTime() const
{
  return theRunningTime;
}

inline Tdouble TSystemTimer::GetIdlingTime() const
{
  return theIdlingTime;
}

inline const TdoubleList& TSystemTimer::GetRealLapTime() const
{
  return theRealLapTime;
}

inline const TdoubleList& TSystemTimer::GetSystemLapTime() const
{
  return theSystemLapTime;
}

inline const TdoubleList& TSystemTimer::GetUserLapTime() const
{
  return theUserLapTime;
}

inline const Tstring& TSystemTimer::GetUnit() const
{
  return theUnit;
}

inline Tint TSystemTimer::GetNumberOfLaps() const
{
  return (Tint)theRealLapTime.size();
}

#endif
