/*
 * ReprocessTrackAction.cpp
 *
 *  Created on: 23/dic/2009
 *      Author: C. De Santis, N. Mori
 */

#include "ReprocessTrackAction.h"

void ReprocessTrackAction::OnGood(PamLevel2 *event) {

  _allEvents++;

  TrkLevel1 *L1 = NULL;
  if (_newTrkL1) {
    if (_externalFlag)
      if (!(*_externalFlag))
        return;
      else
        L1 = *_newTrkL1; // External L1 plus flag=true
    else
      L1 = *_newTrkL1; // External L1 plus no external flag

    // Set the new L1 inside PamLevel2 event
    TrkLevel1 *oldTrkL1 = event->GetTrkLevel1();

    // Sadly, there's no copy constructor for TrkLevel1. We have to copy manually...
    // TODO: replace the following with TrkLevel1 copy constructor (if there will ever be one...)
    // 1. Clean the structure
    oldTrkL1->Set(); // Creates Cluster array if it doesn't exist
    Int_t nClus = oldTrkL1->Cluster->GetEntries();
    for (Int_t i = 0; i < nClus; i++) {
      TrkCluster *clstrPtr = (TrkCluster*) (oldTrkL1->Cluster->UncheckedAt(i));
      if (clstrPtr) {
        delete[] clstrPtr->clsignal;
        clstrPtr->clsignal = NULL;
        delete[] clstrPtr->clsigma;
        clstrPtr->clsigma = NULL;
        delete[] clstrPtr->cladc;
        clstrPtr->cladc = NULL;
        delete[] clstrPtr->clbad;
        clstrPtr->clbad = NULL;
      }
    }
    oldTrkL1->Cluster->Clear("C");

    // 2. Copy the new L1 into the old one
    // 2.1 Fixed size public arrays
    for (int i = 0; i < 12; i++) {
      oldTrkL1->good[i] = (*_newTrkL1)->good[i];
      for (int j = 0; j < 24; j++) {
        oldTrkL1->cn[j][i] = (*_newTrkL1)->cn[j][i];
        oldTrkL1->cnn[j][i] = (*_newTrkL1)->cnn[j][i];
      }
    }
    // 2.2 TClonesArray of TrkCluster objects
    int nClusters = (*_newTrkL1)->Cluster->GetEntries();
    for (int i = 0; i < nClusters; i++) {
      TrkCluster *currCluster = (TrkCluster*) ((*_newTrkL1)->Cluster->At(i));
      new ((*(oldTrkL1->Cluster))[i]) TrkCluster(*currCluster);
    }
  }
  else {

    event->GetPointerTo("TrkLevel1"); // Internal L1 (create it if it doesn't exist)
    TrkLevel0 *L0 = event->GetTrkLevel0();
    if (!L0) {
      cout << "Missing TrkLevel0 event " << endl;
      return;
    }
    L0->ProcessEvent(); // re-processing level0->level1
    L1 = event->GetTrkLevel1();
    L1->Clear();
    L1->SetFromLevel1Struct();
  }

  if (_reprocL2) {
    // See if the event has a track before reprocessing
    TrkLevel2 *trkl2 = event->GetTrkLevel2();
    bool hadTrack = false;
    if (trkl2->GetTrkLevel2()->GetNTracks() > 0)
      hadTrack = true;

    // Reprocess
    _reprocessed++;
    L1->ProcessEvent(); // re-processing level1->level2

    trkl2 = event->GetTrkLevel2();
    trkl2->Clear();
    trkl2->SetFromLevel2Struct();

    // See if we gained or lost a track;
    if (trkl2->GetNTracks() > 0) {
      if (!hadTrack) {
        _recoveredTracks++;
      }
    }
    else if (hadTrack) {
      _lostTracks++;
    }
  }
}
