// =====================================================================
/*!
//
//  \file TRunManager.hh
//  \brief This file contains the TRunManager class.
//  \author Go IWAI <goiwai@users.sourceforge.jp>
//
//  $Id: TRunManager.hh,v 1.21 2004/03/07 10:30:34 goiwai Exp $
//  $Name: CLDAQ-1-14-03 $
//  $Log: TRunManager.hh,v $
//  Revision 1.21  2004/03/07 10:30:34  goiwai
//  ROOTに組みこむためのおまじないマクロを埋めこみました。
//  全てにおいて完全に動作するわけではありません。
//
//  Revision 1.20  2004/01/19 21:09:43  goiwai
//  プリプロセッサの接頭辞をCLDAQ__に変更しました.
//
//  Revision 1.19  2003/11/03 11:46:42  goiwai
//  コメントをちょっと追加したけど,飽きたのでまだ途中...
//
//  Revision 1.18  2003/11/03 08:35:14  goiwai
//  Doxygen用のタグとコメントをうちこんでいく試みを開始しました.
//
//  Revision 1.17  2003/10/06 17:02:45  goiwai
//  *** empty log message ***
//
//  Revision 1.16  2003/07/30 17:46:19  goiwai
//  Tint GetRunID() const;
//  Tvoid SetRunID( Tint id );
//  を追加しました.
//
//  Revision 1.15  2003/07/30 16:20:31  goiwai
//  ファイルにコミットログをつけることにしました.
//
*/
// =====================================================================
#ifndef CLDAQ__TRUNMANAGER_HH
#define CLDAQ__TRUNMANAGER_HH

#include "Tglobals.h"
#include "TRun.hh"
#include "TSystemTimer.hh"
#include "TSystemClock.hh"
#include "TEnvironmentVariableTable.hh"

class TUserInterface;
class TCommand;
class TSystemAction;
class TRunAction;
class TEventAction;
class TEventManager;
class TSoftwareRunInformationModule;
class TAnalysisManager;
class TSystemTimer;
class TReadoutBookDefinition;
class TReadoutBook;
class TCrateDefinition;
class TCrate;


/*!
// \example terminal.cc
//
// もっとも簡単なランマネージャーの使用例です.
//
*/

/*!
// \example bt00.cc
//
// ランマネージャーの使用例です.
//
*/

/*!
// \example rs00.cc
//
// ランマネージャーの使用例です.
//
*/

/*!
// \example rs01.cc
//
// ランマネージャーの使用例です.
//
*/

/*!
// \example sw00.cc
//
// ランマネージャーの使用例です.
//
*/

/*!
// \example st00.cc
//
// ランマネージャーの使用例です.
//
*/

/*!
// \example st01.cc
//
// ランマネージャーの使用例です.
//
*/

/*!
// \example st02.cc
//
// ランマネージャーの使用例です.
//
*/

/*!
// \class TRunManager
// \brief これはランを管理するためのクラスです.
// \author Go IWAI <goiwai@users.sourceforge.jp>
//
// TRunManagerクラスは全てのDAQアプリケーションで必要となります.
// DAQアプリケーションからインスタンシエートされた全てのオブジェクトは
// ここから参照できるようになっています.
// またいわゆるシングルトンクラスです.
// たいていの場合,このクラスを継承する必要はないと思いますが,もしも
// 複雑な(あるいは特殊な)動作をさせたい場合はこのクラスを継承し,
// 各種メンバ関数をオーバーライドしてください.
//
// \todo 子プロセスを起動できるようにする.
// \todo スレッドを起動できるようにする.
// \bug ラン実行時間の表示がマイナスになってしまう.
// \ingroup RunCategory
*/
class TRunManager
{

  protected:
    //! ランマネージャー自身へのポインタ
    static TRunManager* theRunManager;

  protected:
    //! ランマネージャーの状態
    Tstatus_t theStatus;

    //! 実行中のラン
    TRun theRun;

    //! 
    TSystemAction* theSystemAction;

    //! 
    TRunAction* theRunAction;

    //! イベントマネージャーへのポインタ
    TEventManager* theEventManager;

    //! 
    TUserInterface* theUserInterface;

    //! 
    Tthread_t theThreadOfEventLoop;

    //! 
    TSoftwareRunInformationModule* theRunInformationModule;

    //! 
    TAnalysisManager* theAnalysisManager;

    //! 
    TSystemTimer theRunTimer;

    //! 
    TSystemClock theRunClock;

    //! 
    TReadoutBookDefinition* theReadoutBookDefinition;

    //! 
    TReadoutBook* theReadoutBook;

    //! 
    TCrateDefinition* theCrateDefinition;

    //! 
    TCrate* theCrate;

    //! 
    TEnvironmentVariableTable theEnvironmentVariableTable;

    //! 
    Tint theEventLimit;

  public:
    //! TUserInterfaceクラスを継承したオブジェクトを渡して下さい.
    /*!
    // コンストラクタにはTUserInterfaceクラスを継承したオブジェクトを
    // newして渡して下さい.
    // これを省略した場合,TTerminalUserInterfaceが使用されます.
    */
    TRunManager( TUserInterface* ui = 0 );

    //! 必ず最後に呼ばれなくてはなりません.
    virtual ~TRunManager();

  public:
    //! theUserInterfaceへのポインタを得る
    TUserInterface* GetUserInterface() const;

    //! theRunへの参照を得る
    const TRun& GetRun() const;

    //! theRunへの参照を得る
    TRun& GetRun();

    //! theRunIDを得る
    Tint GetRunID() const;

    //! theRunIDを変更する
    Tvoid SetRunID( Tint id );

    //! theSystemActionへのポインタを得る
    TSystemAction* GetSystemAction() const;

    //! theRunActionへのポインタを得る
    TRunAction* GetRunAction() const;

    //! theEventManagerへのポインタを得る
    TEventManager* GetEventManager() const;

    //! theUserInterfaceを設定する
    Tvoid SetUserInterface( TUserInterface* ui );

    //! コマンドの登録を行なう
    Tint SetUserCommand( TCommand* command );

    //! theRunを変更する
    Tvoid SetRun( const TRun& run );

    //! theSystemActionを設定する
    Tvoid SetSystemAction( TSystemAction* action );

    //! theRunActionを設定する
    Tvoid SetRunAction( TRunAction* action );

    //! theEventActionを設定する
    Tvoid SetEventAction( TEventAction* action );

    //! theEventManagerを設定する
    Tvoid SetEventManager( TEventManager* manager );

    //! theStatus を得る
    Tstatus_t GetStatus() const;

    //! theStatus を変更する
    Tvoid SetStatus( Tstatus_t status );

    //! イベントループを実行しているスレッドのID(theThreadOfEventLoop)を得る
    Tthread_t GetThreadOfEventLoop() const;

    //! イベントループを実行しているスレッドのID(theThreadOfEventLoop)を変更する
    Tvoid SetThreadOfEventLoop( Tthread_t thread );

    //! theRunInformationModuleへのポインタを得る
    TSoftwareRunInformationModule* GetRunInformationModule() const;

    //! theAnalysisManagerへのポインタを得る
    TAnalysisManager* GetAnalysisManager() const;

    //! theRunTimerへの参照を得る
    const TSystemTimer& GetRunTimer() const;

    //! theRunTimerへの参照を得る
    TSystemTimer& GetRunTimer();

    //! theRunTimerを変更する
    Tvoid SetRunTimer( const TSystemTimer& timer );

    //! theRunClockへの参照を得る
    const TSystemClock& GetRunClock() const;

    //! theRunClockへの参照を得る
    TSystemClock& GetRunClock();

    //! theRunClockを変更する
    Tvoid SetRunClock( const TSystemClock& clock );

    //! theReadoutBookDefinitionを得る
    TReadoutBookDefinition* GetReadoutBookDefinition() const;

    //! theReadoutBookを得る
    TReadoutBook* GetReadoutBook() const;

    //! 
    TCrateDefinition* GetCrateDefinition() const;

    //! 
    TCrate* GetCrate() const;

    //! 
    Tvoid SetReadoutBookDefinition( TReadoutBookDefinition* definition );

    //! 
    Tvoid SetCrateDefinition( TCrateDefinition* definition );

    //! 
    const TEnvironmentVariableTable& GetEnvironmentVariableTable() const;

    //! 
    TEnvironmentVariableTable& GetEnvironmentVariableTable();

    //! 
    Tvoid SetEnvironmentVariableTable( const TEnvironmentVariableTable& table );

    //! 
    Tint GetEventLimit() const;

    //! 
    Tvoid SetEventLimit( Tint nevents );

  public:
    //! 
    virtual Tvoid SessionStart();

    //! 
    virtual Tvoid ShowStatus() const;

    //! 
    virtual Tvoid PopupLogo() const;

    //! 
    virtual Tvoid PopdownLogo() const;

    //! 
    virtual Tvoid PrintAuthorInformation( Tostream& tos = Tcout ) const;

    //! 
    virtual Tvoid ShutdownRun();

    //! 
    virtual Tvoid StartRun();

    //! 
    virtual Tvoid StartRun( Tint runid );

    //! 
    virtual Tvoid StopRun();

    //! 
    virtual Tvoid SuspendRun();

    //! 
    virtual Tvoid ResumeRun();

    //! 
    virtual Tvoid SetRunInformationModule( TSoftwareRunInformationModule* module );

    //! 
    virtual Tvoid SetRunInformationModule( const Tstring& id );

    //! 
    virtual Tvoid SetRunInformationModule( Tint slot );

    //! 
    virtual Tvoid SetAnalysisManager( TAnalysisManager* manager );

  public:
    //! ランマネージャーへのポインタを得る
    static TRunManager* GetRunManager();

  protected:
    //! 
    static Tvoid* doEventLoop( Tvoid* arguments );

    //! 
    static Tvoid* showLogo( Tvoid* arguments );

    //! 
    static Tvoid catchAlarmSignal( Tint sigid );

  public:
    //! 
    virtual Tvoid GoEventLoop();

    //! 
    virtual Tvoid WaitReturnFromEventLoop();

  protected:
    //! 
    virtual TstringList divide( const Tstring& input ) const;

    //! 
    virtual Tvoid installDefaultCommand();

#ifdef __CLDAQ_ROOT_DLL
    ClassDef(TRunManager,0)
#endif

};

inline TRunManager* TRunManager::GetRunManager()
{
  return theRunManager;
}

inline TUserInterface* TRunManager::GetUserInterface() const
{
  return theUserInterface;
}

inline Tvoid TRunManager::SetRun( const TRun& run )
{
  theRun = run;
  return;
}

inline const TRun& TRunManager::GetRun() const
{
  return theRun;
}

inline TRun& TRunManager::GetRun()
{
  return theRun;
}

inline Tint TRunManager::GetRunID() const
{
  return theRun.GetRunID();
}

inline Tvoid TRunManager::SetRunID( Tint id )
{
  theRun.SetRunID( id );
  return;
}

inline TSystemAction* TRunManager::GetSystemAction() const
{
  return theSystemAction;
}

inline TRunAction* TRunManager::GetRunAction() const
{
  return theRunAction;
}

inline TEventManager* TRunManager::GetEventManager() const
{
  return theEventManager;
}

inline Tstatus_t TRunManager::GetStatus() const
{
  return theStatus;
}

inline Tvoid TRunManager::SetStatus( Tstatus_t status )
{
  theStatus = status;
  return;
}

inline Tthread_t TRunManager::GetThreadOfEventLoop() const
{
  return theThreadOfEventLoop;
}

inline Tvoid TRunManager::SetThreadOfEventLoop( Tthread_t thread )
{
  theThreadOfEventLoop = thread;
  return;
}

inline TSoftwareRunInformationModule* TRunManager::GetRunInformationModule() const
{
  return theRunInformationModule;
}

inline TAnalysisManager* TRunManager::GetAnalysisManager() const
{
  return theAnalysisManager;
}

inline const TSystemTimer& TRunManager::GetRunTimer() const
{
  return theRunTimer;
}

inline TSystemTimer& TRunManager::GetRunTimer()
{
  return theRunTimer;
}

inline TReadoutBookDefinition* TRunManager::GetReadoutBookDefinition() const
{
  return theReadoutBookDefinition;
}

inline TReadoutBook* TRunManager::GetReadoutBook() const
{
  return theReadoutBook;
}

inline TCrateDefinition* TRunManager::GetCrateDefinition() const
{
  return theCrateDefinition;
}

inline TCrate* TRunManager::GetCrate() const
{
  return theCrate;
}

inline Tvoid TRunManager::SetRunTimer( const TSystemTimer& timer )
{
  theRunTimer = timer;
  return;
}

inline const TEnvironmentVariableTable& TRunManager::GetEnvironmentVariableTable() const
{
  return theEnvironmentVariableTable;
}

inline TEnvironmentVariableTable& TRunManager::GetEnvironmentVariableTable()
{
  return theEnvironmentVariableTable;
}

inline Tvoid TRunManager::SetEnvironmentVariableTable( const TEnvironmentVariableTable& table )
{
  theEnvironmentVariableTable = table;
  return;
}

inline const TSystemClock& TRunManager::GetRunClock() const
{
  return theRunClock;
}

inline TSystemClock& TRunManager::GetRunClock()
{
  return theRunClock;
}

inline Tvoid TRunManager::SetRunClock( const TSystemClock& clock )
{
  theRunClock = clock;
  return;
}

inline Tint TRunManager::GetEventLimit() const
{
  return theEventLimit;
}

inline Tvoid TRunManager::SetEventLimit( Tint nevents )
{
  theEventLimit = nevents;
  return;
}

#endif
