#include "StO97DstMaker.h"
#include "TBranch.h"


ClassImp(StO97DstMaker)


//
// Set maximum file size to 1.9 GB (Root has a 2GB limit)
//
#define MAXFILESIZE 1900000000


//_________________
StO97DstMaker::StO97DstMaker(const Char_t *iFileName,
			     const Char_t *oFileName) {
  std::cout << "[StO97DstMaker] Creating an instance... ";
  mOutFileName = oFileName;
  mInFileName  = iFileName;
  mTree = 0;
  mOutFile = 0;
  mInFile = 0;
  mCompression = 9;
  mNEvents = 0;
  mStop = false;
  
  std::cout << "[OK]" << std::endl;
}


//_________________
StO97DstMaker::~StO97DstMaker() {
  /* nothing to do */
}


//_________________
Int_t StO97DstMaker::Init() {
  std::cout << "[StO97DstMaker] ---=== Initializing maker ===---" << std::endl;
  mEvent = new StO97Event();
  //
  // Input file
  //
  std::cout << "[StO97DstMaker] Openning an input file... ";
  if (mInFile)
    fclose(mInFile);
  mInFile = fopen(mInFileName, "r");
  if (mInFile)
    std::cout << "[OK]" << std::endl;
  else {
    std::cout << "[FAIL]" << std::endl;
    return kStFatal;
  }
  //
  // Output file
  //
  std::cout << "[StO97DstMaker] Creating output file... ";
  if (mOutFile) {
    mOutFile->Close();
    mOutFile->Open(mOutFileName, "RECREATE");
  }
  else
    mOutFile = new TFile(mOutFileName, "RECREATE");
  if (mOutFile)
    std::cout << "[OK]" << std::endl;
  else {
    std::cout << "[FAIL]" << std::endl;
    return kStFatal;
  }
  SetCompressionlevel(mCompression); // default value from constructor
  //
  // TTree setup
  //
  std::cout << "[StO97DstMaker] Creating TTree... ";
  if (mTree)
    delete mTree;
  mTree = new TTree("StO97Dst", "StO97Dst");
  if (!mTree) {
    std::cout << "[FAIL]" << std::endl;
    return kStFatal;
  }
  mTree->SetMaxTreeSize(MAXFILESIZE);
  mTree->Branch("StO97Event", "StO97Event", &mEvent);
  mNBytes = 0;
  std::cout << "[OK]" << std::endl;
  //
  // Finalization of initialization :)
  //
  std::cout << "[StO97DstMaker] ---=== Initialization complite ===---" << std::endl;
  
  return StMaker::Init();
}


//_________________
void StO97DstMaker::SetCompressionlevel(Int_t comp) {
  mCompression = comp;
  std::cout << "[StO97DstMaker] Compression level = " << mCompression << std::endl;
  mOutFile->SetCompressionLevel(mCompression);
}


//_________________
Int_t StO97DstMaker::Make() {
  //
  // Read event
  //
  mNEvents++;
  mStop = ReadEvent();
  if (mStop)
    return kStOk;
  //
  // Read tracks
  //
  mStop = ReadTracks();
  if (!mStop)
    mNBytes += mTree->Fill();
  
  return kStOk;
}


//_________________
Int_t StO97DstMaker::Finish() {
  std::cout << "[StO97DstMaker] ---=== Finalization of maker ===---"
	    << "[StO97DstMaker] total number of events = "
	    << mNEvents << std::endl
	    << "[StO97DstMaker] total bytes = "
	    << mNBytes
	    << std::endl;
  if (mInFile) {
    fclose(mInFile);
    mInFile = 0;
  }
  if (mTree) {
    if (mOutFile)
      mOutFile->Write();
    delete mTree;
    mTree = 0;
  }
  if (mOutFile) {
    mOutFile->Close();
    delete mOutFile;
    mOutFile = 0;
  }
  
  return kStOk;
}


//_________________
Bool_t StO97DstMaker::ReadEvent() {
  Int_t eventNumber;
  Int_t nTracks;
  Float_t impPar;
  Float_t rot;
  Char_t buf[128];
  

  while (1) {
    Int_t ret = fscanf(mInFile, " %i %i %f %f",
		     &eventNumber, &nTracks, &impPar, &rot);
    if (ret <= 0)               // if can't read a line
      fgets(buf, 127, mInFile); // skip it
    else if (ret == 4) { // 4 - total number of event parameters
      mEvent->Clear();
      mEvent->SetEventNumber(eventNumber);
      mEvent->SetNTracks(nTracks);
      mEvent->SetImpactPar(impPar);
      mEvent->SetEventPlaneRot(rot);
      return false;
    }
    if (feof(mInFile)) // if EOF then return stop flag
      return true;
  }
}


//_________________
Bool_t StO97DstMaker::ReadTracks() {
  Int_t id;
  Int_t pdgId;
  Float_t px, py, pz;
  Float_t energy, mass;
  Float_t xFr, yFr, zFr, tFr;
  Int_t nTracks = mEvent->GetNTracks();
  

  for (Int_t iTrack = 0; iTrack < nTracks; iTrack++) {
    Int_t ret = fscanf(mInFile, " %i %i %f %f %f %f %f %f %f %f %f",
		     &id, &pdgId, &px, &py, &pz,
		     &energy, &mass, &xFr, &yFr, &zFr, &tFr);
    if (ret != 11)
      return true;
    else {
      StO97Track *track = mEvent->AddTrack(iTrack);
      track->SetId(id);
      track->SetPdgId(pdgId);
      track->SetPx(px);
      track->SetPy(py);
      track->SetPz(pz);
      track->SetE(energy);
      track->SetMass(mass);
      track->SetXfr(xFr);
      track->SetYfr(yFr);
      track->SetZfr(zFr);
      track->SetTfr(tFr);
      track->SetIsSpec(xFr < 0.0001 &&
		       yFr < 0.0001 &&
		       zFr < 0.0001 &&
		       tFr < 0.0001);
    }
  }
  return false;
}
