////////////////////////////////////////////////////////////////////////
// $Id: CandHandle.h,v 1.31 2006/06/21 00:47:01 rhatcher Exp $
//
// CandHandle.h
//
// CandHandle is the base class for specialized access handles to
// CandBase derived objects.
//
// Each concrete CandHandle must define a DupHandle function.
//
// Adapted from Babar's BtaCandidate (written by Gautier Hamel de
// Monchenault and Bob Jacobsen).
//
// Author:  G. Irwin 2/2000
////////////////////////////////////////////////////////////////////////

#ifndef CANDHANDLE_H
#define CANDHANDLE_H

#include "TObject.h"

#include "Candidate/CandBase.h"
#include "Candidate/CandRefer.h"

class CandBase;
class CandRecord;
class CandUid;
class TIter;
class ViewableNotifier;
class VldContext;

class CandHandle;
std::ostream& operator<<(std::ostream& os, const CandHandle& ch);

class CandHandle : public TObject
{

friend class CandBase;

public:
   CandHandle();
   CandHandle(const CandHandle &ch);
   CandHandle(CandBase *cb);
   virtual ~CandHandle();

   CandHandle &operator=(const CandHandle &ch);
   Bool_t operator==(const CandHandle &ch) const;
   Bool_t operator!=(const CandHandle &ch) const;

   const CandHandle *AddDaughterLink(CandHandle &ch,
                                                  Bool_t check = kTRUE);
   const CandHandle *CloneInTree(const CandHandle &ch) const;
   virtual CandHandle *DupHandle() const;
   CandHandle *FindDaughter(const CandHandle *ch) const;
   const CandHandle *FindDaughter(const char *classname = 0,
                                  const char *objname = 0) const;
   const AlgConfig *GetAlgConfig() const;
   UInt_t GetArchUidInt() const;
   const CandBase *GetCandBase() const;
   CandBase *GetCandBase();
   CandRecord *GetCandRecord() const;
   const CandHandle *GetDaughter(Int_t ndau) const;
   TIter GetDaughterIterator() const;
   const CandHandle *GetLocalHandle() const;
   const CandHandle *GetMother() const;
   const char *GetName() const;
   static Int_t GetNAlloc() {return fsNAlloc;}
   Int_t GetNDaughters() const;
   Int_t GetNRefers() const;
   const char *GetTitle() const;
   UInt_t GetUidInt() const;
   ViewableNotifier *GetViewableNotifier() {return fViewableNotifier;}
   const VldContext *GetVldContext() const;
   Bool_t HasOverlapWith(const CandHandle &ch) const;
   Bool_t IsCloneOf(const CandHandle &ch) const;
   Bool_t IsComposite() const;
   virtual Bool_t IsEqual(const TObject *rhs) const;
   virtual Bool_t IsEquivalent(const TObject *rhs) const;
   Bool_t IsLocal() const;
   Bool_t IsLocked() const {return fLocked;}
   static Bool_t IsSlushyEnabled() {return fsSlushyEnabled;}
   Bool_t RemoveDaughter(CandHandle *ch);
   void SetCandRecord(CandRecord *cr);
   void SetName(const char *name);
   void SetLock();
   static void SetSlushyEnabled(Bool_t tf = kTRUE);
   void SetTitle(const char *title);
   void SetViewableNotifier(ViewableNotifier *vn = 0)
                                               {fViewableNotifier = vn;}
   virtual void Trace(const char *c = "") const;

   virtual void Print(Option_t *option="nid3") const;
   virtual std::ostream& FormatToOStream(std::ostream& os,
                                         Option_t *option="nid3") const;

protected:
   CandBase *GetOwnedCandBase();
   const CandRefer &GetCandRefer() const {return fCandRefer;}
   const CandUid &GetCandUid() const;

private:
   CandRefer fCandRefer;                           // Access to CandBase
   CandHandle *fMother;          // Mother CandHandle of this CandHandle
   Bool_t fLocked;           // If true, modifications are a fatal error
   static Int_t fsNAlloc;      // Current number of CandHandle instances
   static Bool_t fsSlushyEnabled;// Freeze Candidates only after read-in
   ViewableNotifier *fViewableNotifier;               //! Dont write out

   void DropMotherLink();
   CandRefer &GetCandRefer() {return fCandRefer;}
   void SetMotherLink(CandHandle *ch);

ClassDef(CandHandle,2)       // User Access channel for CandBase objects
};

#endif                                                   // CANDHANDLE_H
