#include <TObject.h>
#include <TrigLevel2.h>
ClassImp(TrigLevel2);

TrigLevel2::TrigLevel2() {    
  this->Clear();
}

void TrigLevel2::Clear(Option_t *t){
  evcount = 0;
  memset(pmtpl, 0, 3*sizeof(Int_t));
  memset(patternbusy, 0, 3*sizeof(Int_t));
  memset(trigrate, 0, 6*sizeof(Int_t));
  memset(patterntrig, 0, 6*sizeof(Int_t));
  memset(dltime, 0, 2*sizeof(Int_t));
  memset(s4calcount, 0, 2*sizeof(Int_t));
  memset(pmtcount1, 0, 24*sizeof(Int_t));
  memset(pmtcount2, 0, 24*sizeof(Int_t));
  trigconf = 0;
  unpackError = 0;
}

/**
 * Fills a struct cTrigLevel2 with values from a TrigLevel2 object (to put data into a F77 common).
 */
void TrigLevel2::GetLevel2Struct(cTrigLevel2 *l2) const{

  l2->evcount  = evcount;
  l2->trigconf = trigconf;
  
  for(int i=0;i<2;i++){
    l2->s4calcount[i] = s4calcount[i];
    l2->dltime[i]     = dltime[i];
  }
  
  for(int i=0;i<3;i++){
    l2->pmtpl[i]       = pmtpl[i];
    l2->patternbusy[i] = patternbusy[i];
  }
  
  for(int i=0;i<6;i++){
    l2->trigrate[i]    = trigrate[i];
    l2->patterntrig[i] = patterntrig[i];
  }
  
  for(int i=0;i<24;i++){
    l2->pmtcount1[i] = pmtcount1[i];
    l2->pmtcount2[i] = pmtcount2[i];
  }
}

void TrigLevel2::SetFromLevel2Struct(cTrigLevel2 *l2){

  evcount  = l2->evcount;
  trigconf = l2->trigconf;
  
  for(int i=0;i<2;i++){
    s4calcount[i] = l2->s4calcount[i];
    dltime[i]     = l2->dltime[i];
  }
  
  for(int i=0;i<3;i++){
    pmtpl[i]       = l2->pmtpl[i];
    patternbusy[i] = l2->patternbusy[i];
  }
  
  for(int i=0;i<6;i++){
    trigrate[i]    = l2->trigrate[i];
    patterntrig[i] = l2->patterntrig[i];
  }
  
  for(int i=0;i<24;i++){
    pmtcount1[i] = l2->pmtcount1[i];
    pmtcount2[i] = l2->pmtcount2[i];
  }
}

bool TrigLevel2::bit(int decimal, char pos){
  return( (decimal>>pos)%2 );
}

void TrigLevel2::printpatterntrig(){
  UInt_t *patterntrig = this->patterntrig;
  //S3
  if ( this->bit(patterntrig[2],0) ) printf(" S31_1A \n");
  if ( this->bit(patterntrig[2],1) ) printf(" S31_2A \n");
  if ( this->bit(patterntrig[2],2) ) printf(" S31_3A \n");
  if ( this->bit(patterntrig[2],3) ) printf(" S31_1B\n");
  if ( this->bit(patterntrig[2],4) ) printf(" S31_2B\n");
  if ( this->bit(patterntrig[2],5) ) printf(" S31_3B\n");
  
  if ( this->bit(patterntrig[2],6) ) printf(" S32_1A \n");
  if ( this->bit(patterntrig[2],7) ) printf(" S32_2A \n");
  if ( this->bit(patterntrig[2],8) ) printf(" S32_3A \n");
  if ( this->bit(patterntrig[2],9) ) printf(" S32_1B\n");
  if ( this->bit(patterntrig[2],10) ) printf(" S32_2B\n");
  if ( this->bit(patterntrig[2],11) ) printf(" S32_3B\n");
  
  //S2
  if ( this->bit(patterntrig[3],0) ) printf(" S21_1A \n");
  if ( this->bit(patterntrig[3],1) ) printf(" S21_2A \n");
  if ( this->bit(patterntrig[3],2) ) printf(" S21_1B\n");
  if ( this->bit(patterntrig[3],3) ) printf(" S21_2B\n");
  
  if ( this->bit(patterntrig[3],4) ) printf(" S22_1A \n");
  if ( this->bit(patterntrig[3],5) ) printf(" S22_2A \n");
  if ( this->bit(patterntrig[3],6) ) printf(" S22_1B\n");
  if ( this->bit(patterntrig[3],7) ) printf(" S22_2B\n");
  
  //S12
  if ( this->bit(patterntrig[4],0) ) printf(" S12_1A \n");
  if ( this->bit(patterntrig[4],1) ) printf(" S12_2A \n");
  if ( this->bit(patterntrig[4],2) ) printf(" S12_3A \n");
  if ( this->bit(patterntrig[4],3) ) printf(" S12_4A \n");
  if ( this->bit(patterntrig[4],4) ) printf(" S12_5A \n");
  if ( this->bit(patterntrig[4],5) ) printf(" S12_6A \n");
  
  if ( this->bit(patterntrig[4],6) ) printf(" S12_1A \n");
  if ( this->bit(patterntrig[4],7) ) printf(" S12_2A \n");
  if ( this->bit(patterntrig[4],8) ) printf(" S12_3A \n");
  if ( this->bit(patterntrig[4],9) ) printf(" S12_4B\n");
  if ( this->bit(patterntrig[4],10) ) printf(" S12_5B\n");
  if ( this->bit(patterntrig[4],11) ) printf(" S12_6B\n");
  
  //S11
  if ( this->bit(patterntrig[5],0) ) printf(" S11_1A \n");
  if ( this->bit(patterntrig[5],1) ) printf(" S11_2A \n");
  if ( this->bit(patterntrig[5],2) ) printf(" S11_3A \n");
  if ( this->bit(patterntrig[5],3) ) printf(" S11_4A \n");
  if ( this->bit(patterntrig[5],4) ) printf(" S11_5A \n");
  if ( this->bit(patterntrig[5],5) ) printf(" S11_6A \n");
  if ( this->bit(patterntrig[5],6) ) printf(" S11_7A \n");
  if ( this->bit(patterntrig[5],7) ) printf(" S11_8A \n");
  
  if ( this->bit(patterntrig[5],8) ) printf(" S11_1B\n");
  if ( this->bit(patterntrig[5],9) ) printf(" S11_2B\n");
  if ( this->bit(patterntrig[5],10) ) printf(" S11_3B\n");
  if ( this->bit(patterntrig[5],11) ) printf(" S11_4B\n");
  if ( this->bit(patterntrig[5],12) ) printf(" S11_5B\n");
  if ( this->bit(patterntrig[5],13) ) printf(" S11_6B\n");
  if ( this->bit(patterntrig[5],14) ) printf(" S11_7B\n");
  if ( this->bit(patterntrig[5],15) ) printf(" S11_8B\n");
  
}

bool TrigLevel2::checkPMTpatterntrig(){
  UInt_t *patterntrig = this->patterntrig;
  int S11 = 0;
  int S12 = 0;
  int S21 = 0;
  int S22 = 0;
  int S31 = 0;
  int S32 = 0;

  //S3
  if ( this->bit(patterntrig[2],0) ) S31 = 1;
  if ( this->bit(patterntrig[2],1) ) S31 = 1;
  if ( this->bit(patterntrig[2],2) ) S31 = 1;
  if ( this->bit(patterntrig[2],3) ) S31 = 1;
  if ( this->bit(patterntrig[2],4) ) S31 = 1;
  if ( this->bit(patterntrig[2],5) ) S31 = 1;
  if ( this->bit(patterntrig[2],6) ) S32 = 1;
  if ( this->bit(patterntrig[2],7) ) S32 = 1;
  if ( this->bit(patterntrig[2],8) ) S32 = 1;
  if ( this->bit(patterntrig[2],9) ) S32 = 1;
  if ( this->bit(patterntrig[2],10) ) S32 = 1;
  if ( this->bit(patterntrig[2],11) ) S32 = 1;
  //S2
  if ( this->bit(patterntrig[3],0) ) S21 = 1;
  if ( this->bit(patterntrig[3],1) ) S21 = 1;
  if ( this->bit(patterntrig[3],2) ) S21 = 1;
  if ( this->bit(patterntrig[3],3) ) S21 = 1;
  if ( this->bit(patterntrig[3],4) ) S22 = 1;
  if ( this->bit(patterntrig[3],5) ) S22 = 1;
  if ( this->bit(patterntrig[3],6) ) S22 = 1;
  if ( this->bit(patterntrig[3],7) ) S22 = 1;
  //S12
  if ( this->bit(patterntrig[4],0) ) S12 = 1;
  if ( this->bit(patterntrig[4],1) ) S12 = 1;
  if ( this->bit(patterntrig[4],2) ) S12 = 1;
  if ( this->bit(patterntrig[4],3) ) S12 = 1;
  if ( this->bit(patterntrig[4],4) ) S12 = 1;
  if ( this->bit(patterntrig[4],5) ) S12 = 1;
  if ( this->bit(patterntrig[4],6) ) S12 = 1;
  if ( this->bit(patterntrig[4],7) ) S12 = 1;
  if ( this->bit(patterntrig[4],8) ) S12 = 1;
  if ( this->bit(patterntrig[4],9) ) S12 = 1;
  if ( this->bit(patterntrig[4],10) ) S12 = 1;
  if ( this->bit(patterntrig[4],11) ) S12 = 1;
  //S11
  if ( this->bit(patterntrig[5],0) ) S11 = 1;
  if ( this->bit(patterntrig[5],1) ) S11 = 1;
  if ( this->bit(patterntrig[5],2) ) S11 = 1;
  if ( this->bit(patterntrig[5],3) ) S11 = 1;
  if ( this->bit(patterntrig[5],4) ) S11 = 1;
  if ( this->bit(patterntrig[5],5) ) S11 = 1;
  if ( this->bit(patterntrig[5],6) ) S11 = 1;
  if ( this->bit(patterntrig[5],7) ) S11 = 1;
  if ( this->bit(patterntrig[5],8) ) S11 = 1;
  if ( this->bit(patterntrig[5],9) ) S11 = 1;
  if ( this->bit(patterntrig[5],10) ) S11 = 1;
  if ( this->bit(patterntrig[5],11) ) S11 = 1;
  if ( this->bit(patterntrig[5],12) ) S11 = 1;
  if ( this->bit(patterntrig[5],13) ) S11 = 1;
  if ( this->bit(patterntrig[5],14) ) S11 = 1;
  if ( this->bit(patterntrig[5],15) ) S11 = 1;

  // trigger configuration for the event from patterntrig
  int TOF1 = (S11 + S12) * (S21 + S22) * (S31 + S32); 
  int TOF2 = (S11 * S12) * (S21 * S22) * (S31 * S32); 

  int TOF3 = (S21 + S22) * (S31 + S32); 
  int TOF4 = (S21 * S22) * (S31 * S32); 

  int TOF5 = S12 * (S21 * S22);

  int TOF6 = (S11 + S12) * (S31 + S32); 
  int TOF7 = (S11 * S12) * (S31 * S32); 

  // trigger configuration of the run
  bool TCTOF1 = false;
  bool TCTOF2 = false;
  bool TCTOF3 = false;
  bool TCTOF4 = false;
  bool TCTOF5 = false;
  bool TCTOF6 = false;
  bool TCTOF7 = false;
  if ( this->trigconf & (1<<0) ) TCTOF1 = true;
  if ( this->trigconf & (1<<1) ) TCTOF2 = true;
  if ( this->trigconf & (1<<2) ) TCTOF3 = true;
  if ( this->trigconf & (1<<3) ) TCTOF4 = true;
  if ( this->trigconf & (1<<4) ) TCTOF5 = true;
  if ( this->trigconf & (1<<5) ) TCTOF6 = true;
  if ( this->trigconf & (1<<6) ) TCTOF7 = true;

  // do patterntrig pmts match the trigger configuration?
  bool patterntrig_trigconf_match = true;
  if ( TOF1 == 0 && TCTOF1 ) patterntrig_trigconf_match = false; 
  if ( TOF2 == 0 && TCTOF2 ) patterntrig_trigconf_match = false; 
  if ( TOF3 == 0 && TCTOF3 ) patterntrig_trigconf_match = false; 
  if ( TOF4 == 0 && TCTOF4 ) patterntrig_trigconf_match = false; 
  if ( TOF5 == 0 && TCTOF5 ) patterntrig_trigconf_match = false; 
  if ( TOF6 == 0 && TCTOF6 ) patterntrig_trigconf_match = false; 
  if ( TOF7 == 0 && TCTOF7 ) patterntrig_trigconf_match = false; 

  return patterntrig_trigconf_match;
}
