// =====================================================================
//  $Id: Bt00EventAction.cc,v 1.4 2004/03/04 14:55:45 goiwai Exp $
//  $Name: CLDAQ-1-14-03 $
//  $Log: Bt00EventAction.cc,v $
//  Revision 1.4  2004/03/04 14:55:45  goiwai
//  Actionクラスの関数名変更したので。
//
//  Revision 1.3  2003/10/06 16:28:14  goiwai
//  *** empty log message ***
//
//  Revision 1.2  2003/07/30 16:13:49  goiwai
//  ファイルにコミットログをつけることにしました.
//
// =====================================================================
#include "TRunManager.hh"
#include "TOutputObjectFile.hh"
#include "TCamacInterruptRegisterModule.hh"
#include "TCamacOutputRegisterModule.hh"
#include "TDataRecord.hh"
#include "TDataSection.hh"
#include "TDataSegment.hh"
#include "TDataElement.hh"
#include "TCrate.hh"
#include "TReadoutBook.hh"

#include "Bt00EventAction.hh"
#include "Bt00RunAction.hh"
#include "Bt00RunSummary.hh"

Bt00EventAction::Bt00EventAction()
{;}

Bt00EventAction::~Bt00EventAction()
{;}

TReadoutList* Bt00EventAction::WaitTrigger()
{
  // define trigger.
  enum { nosignal = 0x0000, event = 0x0001, scaler = 0x0002, both = 0x0003 };

  TCamacInterruptRegisterModule* ir =
    (TCamacInterruptRegisterModule*)( theCrate -> GetModule( "Interrupt Register" ) );

  Tbool trigger = Tfalse;
  Tint trgtype = nosignal;
  do {
    ir -> ReadInterruptRegister();
    if ( ir -> GetCamacData() != nosignal ) {
      trigger = Ttrue;
      trgtype = ir -> GetCamacData();
      break;
    }
  } while ( trigger == Tfalse );

  if ( trgtype == event || trgtype == both ) {
    return theReadoutBook -> GetReadoutList( "CSI EVENT" );
  } else if ( trgtype == scaler ) {
    return theReadoutBook -> GetReadoutList( "SCALER EVENT" );
  } else {
    Tcerr << "unnown trigger, exception occured." << Tendl;
    Tcerr << "check the hardware." << Tendl;
    return 0;
  }

}

Tvoid Bt00EventAction::AtFirst( TEvent& anEvent )
{
  TCamacOutputRegisterModule* org =
    (TCamacOutputRegisterModule*)( theCrate -> GetModule( "Output Register" ) );
  org -> Pulse( 0x0001 );  // bit pattern
  return;
}

Tvoid Bt00EventAction::AtLast( TEvent& anEvent )
{
  Bt00RunAction* action =
    (Bt00RunAction*)( TRunManager::GetRunManager() -> GetRunAction() );
  TOutputObjectFile* ofile = action -> GetOutputFile();

  TDataRecord record = anEvent.GetDataRecord();
  *ofile << record;

  Tstring evttype = record.GetID();

  if ( evttype == "CSI EVENT" ) {
    fillCsIEventInformation( record );
    theCrate -> Update( "csi event" );
  } else if ( evttype == "SCALER EVENT" ) {
    fillScalerEventInformation( record );
    theCrate -> Update( "scaler event" );
  } else {
    Tstring head = "Bt00EventAction::EndOfEventAction: ";
    Tcerr << head << "unkown trigger." << Tendl;
    Tcerr << record << Tendl;
    Tcerr << head << "confuse." << Tendl;    
  }

  return;
}

Tvoid Bt00EventAction::fillCsIEventInformation( const TDataRecord& record )
{
  Bt00RunAction* action =
    (Bt00RunAction*)( TRunManager::GetRunManager() -> GetRunAction() );
  Bt00RunSummary* summary = action -> GetRunSummary();
  
  Tint ncsi = summary -> GetNumberOfCsIEvents();
  Tint nevents = summary -> GetNumberOfAllEvents();
  summary -> SetNumberOfCsIEvents( ++ ncsi );
  summary -> SetNumberOfAllEvents( ++ nevents );

  return;
}

Tvoid Bt00EventAction::fillScalerEventInformation( const TDataRecord& record )
{
  Bt00RunAction* action =
    (Bt00RunAction*)( TRunManager::GetRunManager() -> GetRunAction() );
  Bt00RunSummary* summary = action -> GetRunSummary();

  Tint nscaler = summary -> GetNumberOfScalerEvents();
  Tint nevents = summary -> GetNumberOfAllEvents();

  static Tstring findtag[ 2 ] = { "EVENT", "SCALER" };
  TDataSegment scaler;
  record.FindDataSegment( findtag, scaler );

  for ( Tsize_t i = 0; i < scaler.size(); i ++ ) {
    TUint databuf = *( scaler[ i ].GetUnsignedIntData() );
    summary -> AddAccumulatedScaler( i, (Tint)databuf );
  }

  summary -> SetNumberOfScalerEvents( ++ nscaler );
  summary -> SetNumberOfAllEvents( ++ nevents );

  return;
}
