// $Id: UgliDbiScintMdl.h,v 1.12 2005/08/26 19:00:02 rhatcher Exp $

#ifndef UGLIDBISCINTMDL_H
#define UGLIDBISCINTMDL_H

////////////////////////////////////////////////////////////////////////
// UgliDbiScintMdl
//
// Package: UgliGeometry
//
// Concept:
//
//
// R. Hatcher 2001-08-08
////////////////////////////////////////////////////////////////////////

#include "DatabaseInterface/DbiTableRow.h"
#include "LeakChecker/Lea.h"

#include "UgliGeometry/Ugli.h"
#include "Plex/PlexScintMdlId.h"

class DbiValidityRec;

#include <iosfwd>

class UgliDbiScintMdl;
std::ostream& operator<<(std::ostream& os, const UgliDbiScintMdl& udsm);

class UgliDbiScintMdl : public DbiTableRow
{

public:

// Constructors and destructors.

   UgliDbiScintMdl()
      : fModuleId(), fWidth(-1), fTPosRelPln(0), fLPosRelPln(0),
        fZRotRelPlnRad(0), fClearLenEast(-1), fClearLenWest(-1),
        fWlsLenEast(0), fWlsLenWest(0) { LEA_CTOR; };

   UgliDbiScintMdl(PlexScintMdlId scintmdl, Float_t width,
                   Float_t tpos, Float_t lpos, Float_t zrot, 
                   Float_t clear_east, Float_t clear_west,
                   Float_t wls_east = 0, Float_t wls_west = 0)
      : fModuleId(scintmdl), fWidth(width), 
        fTPosRelPln(tpos), fLPosRelPln(lpos), fZRotRelPlnRad(zrot),
        fClearLenEast(clear_east), fClearLenWest(clear_west),
        fWlsLenEast(wls_east), fWlsLenWest(wls_west) 
     { LEA_CTOR; }

   virtual ~UgliDbiScintMdl(){ LEA_DTOR; };

// State testing member functions

   virtual Int_t GetAggregateNo() const { return fModuleId.GetPlane(); }
          UInt_t GetIndex(UInt_t defIndex) const;
   static UInt_t HashToIndex(const PlexScintMdlId scintmdl);

   Detector::Detector_t            GetDetector() const;
   PlaneView::PlaneView_t          GetView() const;
   PlaneCoverage::PlaneCoverage_t  GetCoverage() const;

   // don't expose use of StripEndId as compound of PlaneId + module#
   PlexScintMdlId GetScintMdlId() const { return fModuleId; }
   Int_t          GetPlane() const { return fModuleId.GetPlane(); }
   Int_t          GetModule() const { return fModuleId.GetModule(); }

   Float_t        GetWidth() const { return fWidth; }
   Float_t        GetTPosRelPln() const { return fTPosRelPln; }
   Float_t        GetLPosRelPln() const { return fLPosRelPln; }
   Float_t        GetZRotRelPlnRad() const { return fZRotRelPlnRad; }
   Float_t        GetZRotRelPlnDeg() const;
   Float_t        GetClearLenEast() const { return fClearLenEast; }
   Float_t        GetClearLenWest() const { return fClearLenWest; }
   Float_t        GetWlsLenEast() const { return fWlsLenEast; }
   Float_t        GetWlsLenWest() const { return fWlsLenWest; }

   virtual DbiTableRow* CreateTableRow() const { return new UgliDbiScintMdl; }

// I/O  member functions

   virtual void          Fill(DbiResultSet& rs,
                              const DbiValidityRec* vrec);
   virtual void          Store(DbiOutRowStream& ors,
                               const DbiValidityRec* vrec) const;

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

   static const char*    GetTableDescr();
   static void           SetDefensiveUnpkg(Bool_t defensive) 
      { fgDefensiveUnpkg = defensive; }
   static Bool_t         GetDefensiveUnpkg() { return fgDefensiveUnpkg; }

private:  

// Constructors and destructors.

   UgliDbiScintMdl(const UgliDbiScintMdl& from)
     : DbiTableRow(from) { LEA_CTOR; *this = from; }

// Data members

   
   PlexScintMdlId fModuleId;      // det, plane (+view+cover), module
   Float_t        fWidth;         // width of module along view (tpos) axis
   Float_t        fTPosRelPln;    // view (tpos) placement of mdl on plane
   Float_t        fLPosRelPln;    // lateral placement of mdl on plane
   Float_t        fZRotRelPlnRad; // rot about z-axis relative to pln (align=0)
   Float_t        fClearLenEast;  // length of clear fiber on - (east) side
   Float_t        fClearLenWest;  // length of clear fiber on + (west) side
   Float_t        fWlsLenEast;    // extra WLS fiber on - (east) side [CalDet]
   Float_t        fWlsLenWest;    // extra WLS fiber on + (west) side [CalDet]

// class-wide static

   static Bool_t fgDefensiveUnpkg;

ClassDef(UgliDbiScintMdl,0)

};

inline Detector::Detector_t UgliDbiScintMdl::GetDetector() const
{ return fModuleId.GetDetector(); }

inline PlaneView::PlaneView_t UgliDbiScintMdl::GetView() const
{ return fModuleId.GetPlaneView(); }

inline PlaneCoverage::PlaneCoverage_t  UgliDbiScintMdl::GetCoverage() const
{ return fModuleId.GetPlaneCoverage(); }

inline UInt_t UgliDbiScintMdl::GetIndex(UInt_t /* defIndex */) const 
{ return HashToIndex(fModuleId); }

inline Float_t UgliDbiScintMdl::GetZRotRelPlnDeg() const 
{ return fZRotRelPlnRad * Ugli::rad2deg; }

#endif  // UGLIDBISCINTMDL_H
