#include "RawChip.h"

#include "MessageService/MsgService.h"

//
// $Log $
//

ClassImp(RawChip)

CVSID("$Id: RawChip.cxx,v 1.2 2006/09/19 13:11:27 blake Exp $");

RawChip::RawChip(RawChannelId rawch, Int_t adc, Int_t tdc, RawReadout::ReadoutType_t readout, RawChip::ChipStatus_t status, Int_t errcode)
{
  fChannelWord=0;
  fAdc=adc;
  fTdc=tdc;
  fReadout=readout;
  fStatus=status;
  fErrorCode=errcode;
  
  this->AddChannel(rawch);
}
  
RawChip::RawChip(const RawChip& rhs) :
  TObject(rhs),
  fRawChannelId(rhs.fRawChannelId), 
  fAdc(rhs.fAdc), fTdc(rhs.fTdc),
  fReadout(rhs.fReadout),
  fStatus(rhs.fStatus),
  fErrorCode(rhs.fErrorCode),
  fChannelWord(rhs.fChannelWord)
{

}
  
RawChip::~RawChip()
{

}

void RawChip::AddChannel(RawChannelId rawch, Int_t adc, Int_t /*tdc*/, Int_t errcode)
{
  if( fRawChannelId.GetElecType()==ElecType::kVA ){
    if( fChannelWord>=0 && this->IsSameChip(rawch) ){
      if(adc) fAdc+=adc;
      if(errcode) fErrorCode|=errcode;
      this->AddChannel(rawch);
    }
  }

  if( fRawChannelId.GetElecType()==ElecType::kQIE ){
    if( fChannelWord>=0 && this->IsSameChip(rawch) ){
      if(adc) fAdc+=adc;
      if(errcode) fErrorCode|=errcode;
      this->AddChannel(rawch);
    }
  }

  return;
}

void RawChip::AddChannel(RawChannelId rawch)
{
  // N.B: fChannelWord can be used to hold more 
  // than one VA channel on the same VA chip.

  if( rawch.GetElecType()==ElecType::kVA ){
    if( fChannelWord==0 ){
      fRawChannelId=rawch;
      fChannelWord=rawch.GetVaChannel();
    }
  }

  if( rawch.GetElecType()==ElecType::kQIE ){
    if( fChannelWord==0 ){
      fRawChannelId=rawch;
      fChannelWord=1;
    }
  }

  return;
}

RawChannelId RawChip::GetChannelId() const
{
  return fRawChannelId;
}

Int_t RawChip::GetAdc() const
{
  return fAdc;
}

Int_t RawChip::GetTdc() const
{
  return fTdc;
}

Int_t RawChip::GetNanosec() const
{
  Int_t nsec = -99999;
  Double_t nsec_dub = -99999.0;

  if( fRawChannelId.GetElecType()==ElecType::kVA ) nsec_dub=(Double_t)((1000.0/640.0)*fTdc);

  if( fRawChannelId.GetElecType()==ElecType::kQIE ) nsec_dub=(Double_t)((1000.0/53.1)*fTdc);

  if( nsec_dub>1001000001.0 ) nsec_dub=1001000001.0;
  nsec = (Int_t)(nsec_dub);

  return nsec;
}

RawReadout::ReadoutType_t RawChip::GetReadoutType() const
{
  return fReadout;
}

RawChip::ChipStatus_t RawChip::GetChipStatus() const
{
  return fStatus;
}

Int_t RawChip::GetErrorCode() const
{
  return fErrorCode;
}

Int_t RawChip::GetElecType() const
{
  return fRawChannelId.GetElecType();
}

Int_t RawChip::GetCrate() const
{
  return fRawChannelId.GetCrate();
}
  
Int_t RawChip::GetVarc() const
{
  return fRawChannelId.GetVarcId();
}
  
Int_t RawChip::GetVmm() const
{
  return fRawChannelId.GetVmm();
}
  
Int_t RawChip::GetVaadc() const
{
  return fRawChannelId.GetVaAdcSel();
}
  
Int_t RawChip::GetVaChip() const
{
  return fRawChannelId.GetVaChip();
}

Int_t RawChip::GetVaChannel() const
{
  return fChannelWord;
}

Int_t RawChip::GetVaChannelWord() const
{
  return fChannelWord;
}  

Int_t RawChip::GetVaPriority() const
{
  return 1+3*this->GetVaadc()+this->GetVaChip();
}

Int_t RawChip::GetMaster() const
{
  return fRawChannelId.GetMaster();
}  

Int_t RawChip::GetMinder() const
{
  return fRawChannelId.GetMinder();
} 
 
Int_t RawChip::GetMenu() const
{
  return fRawChannelId.GetMenu();
}

Bool_t RawChip::IsSameElecType(RawChannelId rawch) const
{
  if( this->GetElecType()==rawch.GetElecType() ) return 1;
  else return 0;
}
  
Bool_t RawChip::IsSameElecType(RawChip* chip) const
{
  if( this->GetElecType()==chip->GetElecType() ) return 1;
  else return 0;
}

Bool_t RawChip::IsSameCrate(RawChannelId rawch) const
{
  if( this->IsSameElecType(rawch)
   && this->GetCrate()==rawch.GetCrate() ) return 1; 
  else return 0;
}

Bool_t RawChip::IsSameCrate(RawChip* chip) const
{
  if( this->IsSameElecType(chip)
   && this->GetCrate()==chip->GetCrate() ) return 1; 
  else return 0;
}

Bool_t RawChip::IsSameVarc(RawChannelId rawch) const
{
  if( this->IsSameElecType(rawch)
   && this->IsSameCrate(rawch) 
   && this->GetVarc()==rawch.GetVarcId() ) return 1; 
  else return 0;
}

Bool_t RawChip::IsSameVmm(RawChannelId rawch) const
{
  if( this->IsSameElecType(rawch)
   && this->IsSameCrate(rawch) 
   && this->IsSameVarc(rawch) 
   && this->GetVmm()==rawch.GetVmm() ) return 1; 
  else return 0;
}

Bool_t RawChip::IsSameVaadc(RawChannelId rawch) const
{
  if( this->IsSameElecType(rawch)
   && this->IsSameCrate(rawch)
   && this->IsSameVarc(rawch) 
   && this->IsSameVmm(rawch) 
   && this->GetVaadc()==rawch.GetVaAdcSel() ) return 1; 
  else return 0;
}

Bool_t RawChip::IsSameVaChip(RawChannelId rawch) const
{
  if( this->IsSameElecType(rawch)
   && this->IsSameCrate(rawch) 
   && this->IsSameVarc(rawch) 
   && this->IsSameVmm(rawch)
   && this->IsSameVaadc(rawch) 
   && this->GetVaChip()==rawch.GetVaChip() ) return 1; 
  else return 0;
}

Bool_t RawChip::IsSameVarc(RawChip* chip) const
{
  if( this->IsSameElecType(chip)
   && this->IsSameCrate(chip)
   && this->GetVarc()==chip->GetVarc() ) return 1; 
  else return 0;
}
  
Bool_t RawChip::IsSameVmm(RawChip* chip) const
{
  if( this->IsSameElecType(chip)
   && this->IsSameCrate(chip)
   && this->IsSameVarc(chip)
   && this->GetVmm()==chip->GetVmm() ) return 1; 
  else return 0;
}
  
Bool_t RawChip::IsSameVaadc(RawChip* chip) const
{
  if( this->IsSameElecType(chip)
   && this->IsSameCrate(chip) 
   && this->IsSameVarc(chip) 
   && this->IsSameVmm(chip)
   && this->GetVaadc()==chip->GetVaadc() ) return 1; 
  else return 0;
}
  
Bool_t RawChip::IsSameVaChip(RawChip* chip) const
{
  if( this->IsSameElecType(chip)
   && this->IsSameCrate(chip) 
   && this->IsSameVarc(chip) 
   && this->IsSameVmm(chip) 
   && this->IsSameVaadc(chip) 
   && this->GetVaChip()==chip->GetVaChip() ) return 1; 
  else return 0;
}

Bool_t RawChip::IsSameMaster(RawChannelId rawch) const
{
  if( this->IsSameElecType(rawch)
   && this->IsSameCrate(rawch)
   && this->GetMaster()==rawch.GetMaster() ) return 1;
  else return 0;
}
  
Bool_t RawChip::IsSameMinder(RawChannelId rawch) const
{
  if( this->IsSameElecType(rawch)
   && this->IsSameCrate(rawch)
   && this->IsSameMaster(rawch)
   && this->GetMinder()==rawch.GetMinder() ) return 1;
  else return 0;
}
  
Bool_t RawChip::IsSameMenu(RawChannelId rawch) const
{
  if( this->IsSameElecType(rawch)
   && this->IsSameCrate(rawch)
   && this->IsSameMaster(rawch)
   && this->IsSameMinder(rawch)
   && this->GetMenu()==rawch.GetMenu() ) return 1;
  else return 0;
}

Bool_t RawChip::IsSameMaster(RawChip* chip) const
{
  if( this->IsSameElecType(chip)
   && this->IsSameCrate(chip)
   && this->GetMaster()==chip->GetMaster() ) return 1;
  else return 0;
}

Bool_t RawChip::IsSameMinder(RawChip* chip) const
{
  if( this->IsSameElecType(chip)
   && this->IsSameCrate(chip)
   && this->IsSameMaster(chip)
   && this->GetMinder()==chip->GetMinder() ) return 1;
  else return 0;
}

Bool_t RawChip::IsSameMenu(RawChip* chip) const
{
  if( this->IsSameElecType(chip)
   && this->IsSameCrate(chip)
   && this->IsSameMaster(chip)
   && this->IsSameMinder(chip)
   && this->GetMenu()==chip->GetMenu() ) return 1;
  else return 0;
}

Bool_t RawChip::IsSameChip(RawChannelId rawch) const
{
  Bool_t issamechip=0;

  if( this->GetElecType()==ElecType::kVA 
   && this->IsSameElecType(rawch)
   && this->IsSameVaChip(rawch) ) issamechip=1;

  if( this->GetElecType()==ElecType::kQIE
   && this->IsSameElecType(rawch)
   && this->IsSameMenu(rawch) ) issamechip=1;

  return issamechip;
}
  
Bool_t RawChip::IsSameChip(RawChip* chip) const
{
  Bool_t issamechip=0;

  if( this->GetElecType()==ElecType::kVA 
   && this->IsSameElecType(chip)
   && this->IsSameVaChip(chip) ) issamechip=1;

  if( this->GetElecType()==ElecType::kQIE
   && this->IsSameElecType(chip)
   && this->IsSameMenu(chip) ) issamechip=1;

  return issamechip;
}
