////////////////////////////////////////////////////////////////////////
// $Id: CandTrackSRList.cxx,v 1.14 2004/04/10 00:49:14 gmieg Exp $
//
// CandTrackSRList
//
// This is a concrete Event Candidate (Reconstruction) object.
// CandTrackSRList is descended from CandTrackList.
//
// Each concrete CandBase must define a Dup function.
// CandBase must grant friendship to class CandRefer.
//
// Author:  R. Lee 2001.02.26
////////////////////////////////////////////////////////////////////////

#include "Algorithm/AlgHandle.h"
#include "CandTrackSR/CandTrackSRList.h"
#include "CandTrackSR/CandTrackSRListHandle.h"
#include "CandTrackSR/TrackClusterSR.h"
#include "MessageService/MsgService.h"

ClassImp(CandTrackSRList)

//______________________________________________________________________
CVSID("$Id: CandTrackSRList.cxx,v 1.14 2004/04/10 00:49:14 gmieg Exp $");

//______________________________________________________________________
CandTrackSRList::CandTrackSRList() :
  fTrackClusterList(0)
, fCPUTime(0.)
{
  MSG("Cand", Msg::kDebug)
            << "Begin CandTrackSRList::CandTrackSRList() ctor: " << endl
                                           << "UidInt = " << GetUidInt()
                           << ", ArchUidInt " << GetArchUidInt() << endl
                             << "No. of links = " << GetNLinks() << endl
              << "End CandTrackSRList::CandTrackSRList() ctor." << endl;
}

//______________________________________________________________________
CandTrackSRList::CandTrackSRList(AlgHandle &ah) :
  CandTrackList(ah)  // Should be the next class up on inheritance chain
, fTrackClusterList(0)
, fCPUTime(0.)
{

// The sole purpose of this constructor is to transmit the AlgHandle
// up the inheritance chain to CandBase without having to invoke the
// full constructor of an intermediate Candidate type which the highest
// level Candidate might inherit from.  One only wants to create the
// LocalHandle and invoke the RunAlg() method in the lowest level class.
}

//______________________________________________________________________
CandTrackSRList::CandTrackSRList(AlgHandle &ah, CandHandle &ch,
                                                      CandContext &cx) :
  CandTrackList(ah)  // Should be the next class up on inheritance chain
, fTrackClusterList(new TObjArray)
, fCPUTime(0.)
{
  CreateLocalHandle();
  MSG("Cand", Msg::kDebug)
  << "Begin CandTrackSRList::CandTrackSRList(AlgHandle &, CandHandle &,"
                                     << " CandContext &) ctor: " << endl
                                           << "UidInt = " << GetUidInt()
                           << ", ArchUidInt " << GetArchUidInt() << endl
                             << "No. of links = " << GetNLinks() << endl
   << "End CandTrackSRList::CandTrackSRList(AlgHandle &, CandHandle &, "
                                      << "CandContext &) ctor." << endl;

// Run Algorithm to construct Candidate
  {                                                   // Start of scope.
    CandTrackSRListHandle cshl(this);       // cshl will go out of scope
    ch = cshl;                                      // after setting ch.
  }                                                     // End of scope.
  ah.RunAlg(ch, cx);
}

//______________________________________________________________________
CandTrackSRList::CandTrackSRList(const CandTrackSRList &rhs) :
  CandTrackList(rhs) // Should be the next class up on inheritance chain
, fTrackClusterList(new TObjArray)
, fCPUTime(rhs.fCPUTime)
{

//CreateLocalHandle(); // Moved to Dup function following copy-ctor call
  MSG("Cand", Msg::kDebug)
                             << "Begin CandTrackSRList::CandTrackSRList"
                        << "(const CandTrackSRList &rhs) ctor: " << endl
                                           << "UidInt = " << GetUidInt()
                           << ", ArchUidInt " << GetArchUidInt() << endl
                             << "No. of links = " << GetNLinks() << endl
                               << "End CandTrackSRList::CandTrackSRList"
                        << "(const CandTrackSRList &rhs) ctor." << endl;

  for (int i=0; i<=rhs.fTrackClusterList->GetLast(); i++) {
    TrackClusterSR *tc =
            dynamic_cast<TrackClusterSR*>(rhs.fTrackClusterList->At(i));
    fTrackClusterList->Add(new TrackClusterSR(*tc));
  }
}

//______________________________________________________________________
CandTrackSRList::~CandTrackSRList()
{
  MSG("Cand", Msg::kDebug)
           << "Begin CandTrackSRList::~CandTrackSRList() dtor: " << endl
                                           << "UidInt = " << GetUidInt()
                           << ", ArchUidInt " << GetArchUidInt() << endl
                             << "No. of links = " << GetNLinks() << endl
             << "End CandTrackSRList::~CandTrackSRList() dtor." << endl;

  if (fTrackClusterList) {
    for (int i=0; i<=fTrackClusterList->GetLast(); i++) {
      TrackClusterSR *tc =
                dynamic_cast<TrackClusterSR*>(fTrackClusterList->At(i));
      delete tc;
    }
    delete fTrackClusterList;
  }
}

//______________________________________________________________________
void CandTrackSRList::CreateLocalHandle()
{
  SetLocalHandle(new CandTrackSRListHandle(this));
}

//______________________________________________________________________
CandTrackSRList *CandTrackSRList::Dup() const
{

// Base copy ctor dups owned pointers, but defers copying Daughter List.
// Daughter List copy is made in the derived class Dup() function.
// This is because base class copy constructor hasn't yet created
// fLocalHandle with a CandHandle* of the full derived type.
  CandTrackSRList *cb = new CandTrackSRList(*this);         // Copy-ctor
  cb->CreateLocalHandle();   // Initializes fLocalHandle after copy-ctor
  TIter iterdau = GetDaughterIterator();
  CandHandle *dau;
  while ((dau=(CandHandle *) iterdau())) cb->AddDaughterLink(*dau);
  return cb;
}

//______________________________________________________________________
Bool_t CandTrackSRList::IsEquivalent(const TObject *rhs) const
{
  Bool_t result = true;
  if (!CandTrackList::IsEquivalent(rhs)) result = false;   // superclass
  TestDisplayCandBanner("CandTrackSRList");
  const CandTrackSRList* rCnd =
                              dynamic_cast<const CandTrackSRList*>(rhs);
  if (rCnd == NULL) return false;

  result = TestGenericElemPtrTObjArrayPtrEquivalence<TrackClusterSR>(
                                                "fTrackClusterList",
                                                this->fTrackClusterList,
                                                rCnd->fTrackClusterList,
                                                       kTRUE) && result;
  result = TestEquality("fCPUTime", this->fCPUTime, rCnd->fCPUTime)
                                                              && result;

  return result;
}

//______________________________________________________________________
CandTrackSRListHandle CandTrackSRList::MakeCandidate(AlgHandle &ah,
                                                        CandContext &cx)
{
  CandTrackSRListHandle cshl;
  new CandTrackSRList(ah, cshl, cx); //cshl owns the new CandTrackSRList
  return cshl;
}
