// access and set functions for binary calorimeter tags
// Version 1.0 21 Oct 1998 Richard creation

#ifndef LCDTOWERID_H
#define LCDTOWERID_H

#include "TObject.h"

// Widths of bit fields
#define CAL_K_PHI       11
#define CAL_K_THETA     10
#define CAL_K_LAYER      7
#define CAL_K_SYSTEM     4

// Amount to shift per bit field
#define CAL_V_PHI       0                
#define CAL_V_THETA     (CAL_V_PHI   + CAL_K_PHI  )       
#define CAL_V_LAYER     (CAL_V_THETA + CAL_K_THETA)  
#define CAL_V_SYSTEM    (CAL_V_LAYER + CAL_K_LAYER)   

// Mask (shifted down to least sig. bits) for each bit field
#define CAL_M_PHI       ((1 << CAL_K_PHI)    - 1)       
#define CAL_M_THETA     ((1 << CAL_K_THETA)  - 1)  
#define CAL_M_LAYER     ((1 << CAL_K_LAYER)  - 1)
#define CAL_M_SYSTEM    ((1 << CAL_K_SYSTEM) - 1)

// For (deprecated) use in finding "sign" bit for theta bin
#define CAL_S_THETA     (1 << (CAL_K_THETA  - 1))

class LCDtowerID : public TObject {

public:
  LCDtowerID()           : m_tag(0) {}
  // Default constructor m_tag set equal to 0
  LCDtowerID(UInt_t tag) : m_tag(tag) {}
  ~LCDtowerID() {}

  UInt_t GetTag()          const { return m_tag  ; }
  void   SetTag(UInt_t tagVal)   { m_tag = tagVal; }

  UInt_t GetTheta()        const;
  void   SetTheta(UInt_t thetaVal);

  UInt_t GetPhi()          const;
  void   SetPhi(UInt_t phiVal);

  UInt_t GetLayer()        const;
  void   SetLayer(UInt_t layerVal);

  UInt_t GetSystem()       const; // EM 0; HAD 1; MU 2; LUM 3;      
  void   SetSystem(UInt_t systemVal);

  UInt_t GetBarrelEndcap() const; // Barrel 0; Endcap 1;
  void   SetBarrelEndcap(UInt_t barrelEndcapVal);

  //UInt_t GetNorthSouth()   const;
  //void   SetNorthSouth(UInt_t northSouthVal);

  //UInt_t GetPhiBinWidth()  const;
  //void   SetPhiBinWidth(UInt_t phiBinWidthVal);

  inline LCDtowerID & operator = (const LCDtowerID &);
  inline LCDtowerID & operator = (const UInt_t &);

// 2 routines that ROOT requires
  ULong_t Hash() const { return  m_tag; }
  Bool_t IsEqual(const TObject *obj) const
  { return m_tag == ((LCDtowerID*)obj)->m_tag; }

private:
  UInt_t m_tag; // Calorimeter tower ID number

public:
  ClassDef(LCDtowerID,1)// Calorimeter tower ID number
};

inline LCDtowerID & LCDtowerID::operator = (const LCDtowerID & p) {
  m_tag = p.m_tag;
  return *this;
}

inline LCDtowerID & LCDtowerID::operator = (const UInt_t & p) {
  m_tag = p;
  return *this;
}


#endif
