// =====================================================================
//  $Id: rs01vdcview.cc,v 1.7 2003/10/14 22:44:42 goiwai Exp $
//  $Name: CLDAQ-1-11-00 $
//  $Log: rs01vdcview.cc,v $
//  Revision 1.7  2003/10/14 22:44:42  goiwai
//  別々のアップデートサイクルにしました.
//  これで両方起動してもよさげです.
//
//  Revision 1.6  2003/10/12 22:52:22  goiwai
//  秋のビームテストにむけての若干の修正.
//  パラメーターやROOTオブジェクトの出力.
//  WEB閲覧用に毎イベントGIFの出力.
//  オンラインストリームの採用.
//
//  Revision 1.5  2003/10/06 16:28:15  goiwai
//  *** empty log message ***
//
//  Revision 1.4  2003/07/30 16:14:41  goiwai
//  ファイルにコミットログをつけることにしました.
//
// =====================================================================
#include "TDataRecord.hh"
#include "TDataSection.hh"
#include "TDataSegment.hh"
#include "TDataElement.hh"
#include "TEnvironmentVariableTable.hh"
#include "TInputObjectFileOnline.hh"
#include "Trootinit.h"

static const Tstring rcpath = "rs01setup";
static const Tint npin = 32;
static Tint pinpos[ npin ] = {
           3,  4, 5,   6,  7,
      10, 11, 12, 13, 14, 15, 16,
  17, 18, 19, 20, 21, 22, 23, 24,
      26, 27, 28, 29, 30, 31, 32,
          35, 36, 37, 38, 39
};

TInputObjectFile* ifile = 0;
TEnvironmentVariableTable* envtable = 0;
TDataRecord record;
TDataElement element;
Tdouble vdc[ npin ];
Tint elapsed[ npin ];
//
TApplication* theApplication = 0;
TCanvas* CVvdc = 0;
static const Tint nx = 8;
static const Tint ny = 5;
static const Tint npadvdc = nx * ny;
TH1D** H1Dvdc;

Tstring htvdc[ npin ];
Tstring hnamevdc[ npin ];
Tstring fpath, macrof, giff, psf, rootf;
static Tbool autoprint, enableoverwrite;
static Tint modperiod;

static Tvoid initialize( Tint argc, Tchar** argv );
static Tvoid event();
static Tvoid runbegin();
static Tvoid runend();

int main( int argc, char** argv, char** envv )
{
  initialize( argc, argv );

  while ( ifile -> Read( record ) ) {

    Tstring recid = record.GetID();
    if ( recid == "RUN BEGIN" ) {
      runbegin();
      continue;
    } else if ( recid == "EVENT" ) {
      event();
    } else if ( recid == "RUN END" ) {
      runend();
      break;
    } else {
      Tcerr << "unknown tag: " << recid << Tendl;
      break;
    }
    gSystem -> ProcessEvents();
  }

  theApplication -> Run();
  return 0;
}

Tvoid initialize( Tint argc, Tchar** argv )
{
  if ( argc != 2 && argc != 3 ) {
    Tcerr << "usage: " << argv[ 0 ] << " <run#>" << Tendl;
    exit( -1 );
  } 

  Tint runid = (Tint)strtol( argv[ 1 ], 0, 0 );
  Tstring runidstr = itostr( runid );

  envtable = new TEnvironmentVariableTable ( rcpath );
  Tstring rechead = envtable -> GetEnvironmentValue( "RS01_RECORD_HEAD" );
  Tstring recpath = envtable -> GetEnvironmentValue( "RS01_RECORD_DIR" );
  fpath = recpath + Tslash + rechead + runidstr + ".drec";
  ifile = new TInputObjectFileOnline( fpath );

  Tstring rootdir = envtable -> GetEnvironmentValue( "RS01_ROOTFILE_DIR" );
  rootf = rootdir + Tslash + rechead + runidstr + "vdc.root";
  Tstring macrodir = envtable -> GetEnvironmentValue( "RS01_ROOTFILE_DIR" );
  macrof = macrodir + Tslash + rechead + runidstr + "vdc.C";
  Tstring gifdir = envtable -> GetEnvironmentValue( "RS01_FIGURE_DIR" );
  giff = gifdir + Tslash + rechead + runidstr + "vdc.gif";
  Tstring psdir = envtable -> GetEnvironmentValue( "RS01_FIGURE_DIR" );
  psf = psdir + Tslash + rechead + runidstr + "vdc.ps";

  modperiod = envtable -> GetIntegerValue( "RS01_UPDATE_PERIOD_VDC" );
  enableoverwrite = (Tbool)envtable -> GetIntegerValue( "RS01_OVERWRITE_ENABLE" );
  autoprint = (Tbool)envtable -> GetIntegerValue( "RS01_AUTO_PRINT" );



  theApplication = rootinit();
  TGaxis::SetMaxDigits( 1 );


  // 電圧 VS 時間 キャンバス
  CVvdc = new TCanvas( "CVvdc", "VDC VS Time", 960, 720 );
  CVvdc -> ToggleEventStatus();
  CVvdc -> Divide( nx, ny );


  // 電圧 VS 時間の初期設定
  H1Dvdc = new TH1D*[npin];
  for ( Tint ch = 0; ch < npin; ch ++ ) {
    htvdc[ ch ] = "Channel: " + itostr( ch, 2 ) + ", Run ID: " + runidstr;
    hnamevdc[ ch ] = "H1Dvdc" + itostr( ch, 2 );

    H1Dvdc[ ch ] = 
      new TH1D( hnamevdc[ ch ].c_str(), htvdc[ ch ].c_str(), 10, 0.0, 10.0 );

    H1Dvdc[ ch ] -> SetStats( 0 );
    H1Dvdc[ ch ] -> GetXaxis() -> SetTimeDisplay( 1 );
    H1Dvdc[ ch ] -> SetMarkerStyle( 1 );
    H1Dvdc[ ch ] -> SetLineColor( 10 );
    H1Dvdc[ ch ] -> SetLineStyle( 0 );
    H1Dvdc[ ch ] -> SetLineWidth( 0 );
    
    H1Dvdc[ ch ] -> GetXaxis() -> SetNdivisions( 504 );
    H1Dvdc[ ch ] -> GetXaxis() -> SetTimeFormat( "%H:%M:%S" );
    H1Dvdc[ ch ] -> GetXaxis() -> SetTitle( "Time (H:M:S)" );
    H1Dvdc[ ch ] -> GetXaxis() -> CenterTitle();

    H1Dvdc[ ch ] -> GetYaxis() -> SetTitle( "DC Voltage (V)" );
    H1Dvdc[ ch ] -> GetYaxis() -> SetNoExponent();
    H1Dvdc[ ch ] -> GetYaxis() -> CenterTitle();

    CVvdc -> cd( pinpos[ ch ] );
    H1Dvdc[ ch ] -> Draw( "pe" );
  }

  return;
}

Tvoid event()
{
  for ( Tint ch = 0; ch < npin; ch ++ ) {
    // VDCのスナップショット
    element = record[ 1 ][ ch ][ 0 ];
    element.StorePrimitives( &vdc[ ch ] );

    // ラン開始からの経過秒数(sec)
    element = record[ 1 ][ ch ][ 3 ];
    element.StorePrimitives( &elapsed[ ch ] );

    //電圧 VS 時間
    H1Dvdc[ ch ] -> SetBinContent( elapsed[ ch ], vdc[ ch ] );

    H1Dvdc[ ch ] -> GetXaxis() -> SetNdivisions( 504 );
    H1Dvdc[ ch ] -> GetXaxis() -> SetTimeFormat( "%H:%M:%S" );
    H1Dvdc[ ch ] -> GetXaxis() -> SetTitle( "Time (H:M:S)" );
    H1Dvdc[ ch ] -> GetXaxis() -> CenterTitle();
    H1Dvdc[ ch ] -> GetYaxis() -> SetTitle( "DC Voltage (V)" );
    H1Dvdc[ ch ] -> GetYaxis() -> SetNoExponent();
    H1Dvdc[ ch ] -> GetYaxis() -> CenterTitle();

    H1Dvdc[ ch ] -> SetDrawOption( "pe" );
  }



  // update
  element = record[ 0 ][ 0 ][ 0 ];
  Tint eventid;
  element.StorePrimitives( &eventid );
  if ( eventid % modperiod == 0 ) {
    for ( Tint i = 0; i < npadvdc; i ++ ) {
      CVvdc -> GetPad(i+1)->Modified();
      CVvdc -> GetPad(i+1)->Update();
    }
  }



  return;
}

Tvoid runbegin()
{
  element = record[ 0 ][ 1 ][ 1 ];
  Tint secbuf;
  element.StorePrimitives( &secbuf );
  gStyle -> SetTimeOffset( secbuf );
  return;
}

Tvoid runend()
{
  // update
  for ( Tint i = 0; i < npadvdc; i ++ ) {
    CVvdc -> GetPad(i+1)->Modified();
    CVvdc -> GetPad(i+1)->Update();
  }

  // printout
  CVvdc -> cd();
  if ( !isexist( rootf ) || enableoverwrite ) {
    TFile* file = new TFile( rootf.c_str(), "RECREATE", "VDC VIEW ONLINE" );
    for ( Tint ch = 0; ch < npin; ch ++ ) {
      H1Dvdc[ ch ] -> Write();
    }
    CVvdc -> Write();
    file -> Close();
  }

  if ( !isexist( giff ) || enableoverwrite ) {
    CVvdc -> Print( giff.c_str() );
  }
  if ( !isexist( psf ) || enableoverwrite ) {
    CVvdc -> Print( psf.c_str() );
    if ( autoprint ) {
      Tstring exec = "lpr " + psf;
      system( exec.c_str() );
    }
  }

  return;
}
