#include "Oscar97Tree.h"


ClassImp(Oscar97Tree)


//______________
Oscar97Tree::Oscar97Tree(const char *f19List, const char *outRoot,
			 int compression) {
  std::cout << "[Oscar97Tree] Creating an instance" << std::endl;
  mError = false;
  //
  // Creating output root file
  //
  std::cout << "[Oscar97Tree] Creating output root file: "
	    << outRoot << "... ";
  mOutRoot = new TFile(outRoot, "RECREATE");
  if (!mOutRoot) {
    std::cout << "FAIL" << std::endl;
    mError = true;
    return;
  }
  else {
    mOutRoot->SetCompressionLevel(compression);
    std::cout << "OK" << std::endl;
  }
  //
  // Open list of f19 files
  //
  mF19List = fopen(f19List, "r");
  if (!mF19List) {
    std::cout << "[Oscar97Tree] Can't open f19 list file "
	      << f19List << std::endl;
    mError = true;
  }
  //
  // Creating TTree
  //
  mEvent = new Oscar97Event();
  mTree = new TTree("Oscar97Dst", "OscarO97Dst");
  if (!mTree) {
    std::cout << "[Oscar97Tree] Can't create tree" << std::endl;
    mError = true;
  }
  else {
    //    mTree->SetMaxTreeSize(MAXFILESIZE);
    mTree->Branch("Oscar97Event", "Oscar97Event", &mEvent);
  }
  mNBytes = 0;
  
  if (mError)
    std::cout << "[Oscar97Tree FAIL]" << std::endl;
  else
    std::cout << "[Oscar97Tree OK]" << std::endl;
}



void Oscar97Tree::MakeRoot() {
  #define BFSZ 0xFF
  char buf[BFSZ];
  //
  // Read data
  //
  int evNum, nTracks;
  float imp, planeRot;
  int trkRd, refMultA;
  bool readEvent = true; // if true - then keep reading events
  while (!feof(mF19List)) {
    char *retGetS = fgets(buf, BFSZ, mF19List);
    buf[strlen(buf) - 1] = '\0';
    FILE *f19 = fopen(buf, "r");
    if (!f19)   break;
    std::cout << "[Oscar97Tree] File: " << buf << std::endl;
    //
    // Skip three useless lines
    //
    retGetS = fgets(buf, BFSZ, f19);
    retGetS = fgets(buf, BFSZ, f19);
    retGetS = fgets(buf, BFSZ, f19);
    //
    // Read events and tracks
    //
    while (!feof(f19)) {
      if (readEvent) {
	int ret = fscanf(f19, "%i %i %f %f",
			 &evNum, &nTracks, &imp, &planeRot);
	if (ret == 4) {
	  mEvent->Clear();
	  mEvent->SetEventNumber(evNum);
	  mEvent->SetNTracks(nTracks);
	  mEvent->SetImpactPar(imp);
	  mEvent->SetEventPlaneRot(planeRot);
	  trkRd = 0;
	  readEvent = false;
	}
	else // if can't read something like event, skip that line
	  retGetS = fgets(buf, BFSZ, f19);
      }
      else {
	//
	// Read tracks from an event
	//
	int trkId, trkPdg;
	float trkPx, trkPy, trkPz, trkE, trkM,
	  trkXfr, trkYfr, trkZfr, trkTfr;
	int ret1 = fscanf(f19,
			  "%i %i %f %f %f %f",
			  &trkId, &trkPdg, &trkPx, &trkPy, &trkPz, &trkE);
	int ret2 = fscanf(f19,
			  "%f %f %f %f %f",
			  &trkM, &trkXfr, &trkYfr, &trkZfr, &trkTfr);
	if (ret1 + ret2 == 11) {
	  Oscar97Track *track = mEvent->AddTrack(trkRd++);
	  track->SetId(trkId);
	  track->SetPdgId(trkPdg);
	  track->SetPx(trkPx);
	  track->SetPy(trkPy);
	  track->SetPz(trkPz);	  
	  track->SetE(trkE);
	  track->SetMass(trkM);
	  track->SetXfr(trkXfr);
	  track->SetYfr(trkYfr);
	  track->SetZfr(trkZfr);
	  track->SetTfr(trkTfr);
	  track->SetIsSpec(trkXfr < 0.0001 &&
			   trkYfr < 0.0001 &&
			   trkZfr < 0.0001 &&
			   trkTfr < 0.0001);
	  if (trkRd == nTracks) {
	    mNBytes += mTree->Fill();
	    readEvent = true;
	  }
	}
	else // if can't read something like track, skip that line
	  retGetS = fgets(buf, BFSZ, f19);
      }
    }
    fclose(f19);

  }

  std::cout << "[Oscar97Tree] Done! Bytes = " << mNBytes << std::endl;
  fclose(mF19List);
  mOutRoot->Write();
  mOutRoot->Close();
}


//______________
Oscar97Tree::~Oscar97Tree() {
}


//______________
bool Oscar97Tree::GetError() {
  return mError;
}
