#include "CandDeadChipHandle.h"
#include "MessageService/MsgService.h"

ClassImp(CandDeadChipHandle)

CandDeadChipHandle::CandDeadChipHandle()
{

}

CandDeadChipHandle::CandDeadChipHandle(const CandDeadChipHandle& cdh) :
  CandHandle(cdh)
{

}
CandDeadChipHandle::CandDeadChipHandle(CandDeadChip* cd) :
  CandHandle(cd)
{

}

CandDeadChipHandle::~CandDeadChipHandle()
{

}

CandDeadChipHandle* CandDeadChipHandle::DupHandle() const
{
  return new CandDeadChipHandle(*this);
}

Int_t CandDeadChipHandle::GetEntries() const
{
  return dynamic_cast<const CandDeadChip*>(GetCandBase())->fEntries;
}

RawChannelId CandDeadChipHandle::GetChannelId() const
{
  return dynamic_cast<const CandDeadChip*>(GetCandBase())->fRawChannelId;
}

Int_t CandDeadChipHandle::GetAdc() const
{
  return dynamic_cast<const CandDeadChip*>(GetCandBase())->fAdc;
}

Int_t CandDeadChipHandle::GetTdc() const
{
  return dynamic_cast<const CandDeadChip*>(GetCandBase())->fTdc;
}

Int_t CandDeadChipHandle::GetTdc0() const
{
  return dynamic_cast<const CandDeadChip*>(GetCandBase())->fTdc0;
}

Int_t CandDeadChipHandle::GetErrorCode() const
{
  return dynamic_cast<const CandDeadChip*>(GetCandBase())->fErrorCode;
}

Int_t CandDeadChipHandle::GetTriggerRate() const
{
  return dynamic_cast<const CandDeadChip*>(GetCandBase())->fTriggerRate;
}

CandDeadChip::ChipStatus_t CandDeadChipHandle::GetChipStatus() const
{
  return dynamic_cast<const CandDeadChip*>(GetCandBase())->fStatus;
}
  
void CandDeadChipHandle::SetChannelId(RawChannelId rawch)
{
  dynamic_cast<CandDeadChip*>(GetOwnedCandBase())->fRawChannelId=rawch;
}
  
void CandDeadChipHandle::SetAdc(Int_t adc)
{
  dynamic_cast<CandDeadChip*>(GetOwnedCandBase())->fAdc=adc;
}
  
void CandDeadChipHandle::SetTdc(Int_t tdc)
{
  dynamic_cast<CandDeadChip*>(GetOwnedCandBase())->fTdc=tdc;
}

void CandDeadChipHandle::SetTdc0(Int_t tdc0)
{
  dynamic_cast<CandDeadChip*>(GetOwnedCandBase())->fTdc0=tdc0;
}
  
void CandDeadChipHandle::SetErrorCode(Int_t errcode)
{
  dynamic_cast<CandDeadChip*>(GetOwnedCandBase())->fErrorCode=errcode;
}
  
void CandDeadChipHandle::SetTriggerRate(Int_t trigrate)
{
  dynamic_cast<CandDeadChip*>(GetOwnedCandBase())->fTriggerRate=trigrate;
}
  
void CandDeadChipHandle::SetChipStatus(CandDeadChip::ChipStatus_t status)
{
  dynamic_cast<CandDeadChip*>(GetOwnedCandBase())->fStatus=status;
}

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

  RawChannelId myrawch = this->GetChannelId();

  if( myrawch.GetElecType()==ElecType::kVA && rawch.GetElecType()==ElecType::kVA
   && myrawch.GetCrate()==rawch.GetCrate()
   && myrawch.GetVarcId()==rawch.GetVarcId()
   && myrawch.GetVmm()==rawch.GetVmm()
   && myrawch.GetVaAdcSel()==rawch.GetVaAdcSel()
   && myrawch.GetVaChip()==rawch.GetVaChip() ) issamechip=1;

  if( myrawch.GetElecType()==ElecType::kQIE && rawch.GetElecType()==ElecType::kQIE
   && myrawch.GetCrate()==rawch.GetCrate()
   && myrawch.GetMaster()==rawch.GetMaster()
   && myrawch.GetMinder()==rawch.GetMinder()
   && myrawch.GetMenu()==rawch.GetMenu() ) issamechip=1;

  return issamechip;
}

void CandDeadChipHandle::AddRawChip(RawChip* chip)
{
  
  // Set the TDC, ADC and Channel ID
  // (choose the chip with the latest time)
  Int_t newadc=chip->GetAdc();
  Int_t newtdc=chip->GetTdc();
  if(this->GetTdc()<0 || chip->GetTdc()>=this->GetTdc()){
    this->SetChannelId(chip->GetChannelId());
    if( chip->GetTdc()==this->GetTdc() ) this->SetAdc(this->GetAdc()+newadc);
    if( chip->GetTdc()>this->GetTdc() ) this->SetAdc(newadc);
    this->SetTdc(newtdc);
  }

  // Record TDC0 (the earliest TDC value)
  if(this->GetTdc0()<0 || chip->GetTdc()<this->GetTdc0()){
    this->SetTdc0(newtdc);
  }

  // Set the chip status
  // (set status bits and also any error codes or trigger rates)
  CandDeadChip::ChipStatus_t mystatus = this->GetChipStatus();
  RawChip::ChipStatus_t newstatus = chip->GetChipStatus();

  if(newstatus==RawChip::kCold){ 
    mystatus=(CandDeadChip::ChipStatus_t)(mystatus|CandDeadChip::kBad);
    mystatus=(CandDeadChip::ChipStatus_t)(mystatus|CandDeadChip::kCold);
    this->SetTriggerRate(chip->GetErrorCode());
  }

  if(newstatus==RawChip::kHot){ 
    mystatus=(CandDeadChip::ChipStatus_t)(mystatus|CandDeadChip::kBad);
    mystatus=(CandDeadChip::ChipStatus_t)(mystatus|CandDeadChip::kHot);
    this->SetTriggerRate(chip->GetErrorCode());
  }

  if(newstatus==RawChip::kBusy){ 
    mystatus=(CandDeadChip::ChipStatus_t)(mystatus|CandDeadChip::kBad);
    mystatus=(CandDeadChip::ChipStatus_t)(mystatus|CandDeadChip::kBusy);
    
  }

  if(newstatus==RawChip::kError){ 
    mystatus=(CandDeadChip::ChipStatus_t)(mystatus|CandDeadChip::kBad);
    mystatus=(CandDeadChip::ChipStatus_t)(mystatus|CandDeadChip::kError);
    this->SetErrorCode(chip->GetErrorCode());
  }
  
  this->SetChipStatus(mystatus);
  this->AddEntry();
  
}

void CandDeadChipHandle::AddEntry()
{
  dynamic_cast<CandDeadChip*>(GetOwnedCandBase())->fEntries++;
}

XXXITRIMP(CandDeadChipHandle)

