/*
 * PamCutBase.cpp
 *
 *  Created on: 12-feb-2009
 *      Author: Nicola Mori
 */

/*! @file PamCutBase.cpp Implementation for classes defined in PamCut.h */

#include "PamCutBase.h"

/* ************** *
 *     PAMCUT
 * ************** */
int PamCut::ApplyCut(PamLevel2 *event) {

  _nEv++;
  int result = Check(event);
  if (result == CUTOK) {
    _nGood++;
    OnGood(event);
  }
  else {
    OnBad(event, result);
  }
  return result;

}

void PamCut::Process(PamLevel2 *events, ULong_t firstEvent, ULong_t lastEvent) {

  // Prepare the collection for the new analysis
  Setup(events);

  // Check the range of events to analyze
  if (firstEvent > lastEvent) {
    Finalize();
    return;
  }
  if (firstEvent < 0 || lastEvent > events->GetEntries() - 1) {
    Finalize();
    return;
  }

  // Apply the cuts
  for (_currEv = firstEvent; _currEv < lastEvent + 1; _currEv++) {
    events->GetEntry(_currEv);
    ApplyCut(events);
  }

  // Closes the analysis
  Finalize();

}
void PamCut::Setup(PamLevel2 *events) {
  _nEv = _nGood = 0;
}

const char* PamCut::GetName() const {
  return _cutName;
}

void PamCut::SetName(const char *newName) {
  _cutName = newName;
}

PamCut& PamCut::operator=(const PamCut &rightValue) {
  _cutName = rightValue._cutName;
  return *this;
}

/* ************************ *
 *     PAMCUTCOLLECTION
 * ************************ */
PamCutCollection::~PamCutCollection() {

  if (_owns) {
    for (unsigned int i = 0; i < _cuts.size(); i++)
      if (_cuts[i] != NULL) {
        delete _cuts[i];
        _cuts[i] = NULL;
      }
  }
}

void PamCutCollection::AddCut(PamCut *cut) {
  _cuts.push_back(cut);
}

int PamCutCollection::Check(PamLevel2 *event) {

  // Apply the cuts
  if (_cuts.size() == 0) {
    return CUTOK;
  }

  for (unsigned int icut = 0; icut < _cuts.size(); icut++) {
    if (_cuts[icut]->Check(event) != CUTOK) {
      return icut;
    }
  }

  return CUTOK;
}

int PamCutCollection::ApplyCut(PamLevel2 *event) {

  _nEv++;
  // Apply the cuts
  if (_cuts.size() == 0) {
    _nGood++;
    OnGood(event);
    return CUTOK;
  }

  for (unsigned int icut = 0; icut < _cuts.size(); icut++) {
    if (_cuts[icut]->ApplyCut(event) != CUTOK) {
      OnBad(event, icut);
      return icut;
    }
  }

  _nGood++;
  OnGood(event);
  return CUTOK;
}

PamCut *PamCutCollection::GetCut(unsigned int iCut) {
  if (_cuts.size() == 0)
    return NULL;
  if (iCut < 0 || iCut > _cuts.size() - 1)
    return NULL;
  else
    return _cuts[iCut];
}

PamCut *PamCutCollection::GetCut(const char *cutName) {
  if (_cuts.size() == 0)
    return NULL;
  for (unsigned int i = 0; i < _cuts.size(); i++) {
    if (strcmp(_cuts[i]->GetName(), cutName) == 0)
      return _cuts[i];
  }

  return NULL;
}

unsigned int PamCutCollection::GetSize() {
  return (unsigned int) _cuts.size();

}

PamCutCollection& PamCutCollection::operator=(const PamCutCollection &rightValue) {

  PamCut::operator=(rightValue);
  _cuts = rightValue._cuts;
  return *this;
}

void PamCutCollection::Setup(PamLevel2 *events) {

  PamCut::Setup(events);

  for (unsigned int i = 0; i < GetSize(); i++) {
    _cuts[i]->Setup(events);
  }
}

void PamCutCollection::Finalize() {

  // PamCut::Finalize() is currently void, but in future it could contain something, so it's good to place a call here.
  PamCut::Finalize();

  for (unsigned int i = 0; i < GetSize(); i++) {
    _cuts[i]->Finalize();
  }
}
