#include "TMHistogrammingEventDump.h"
#include "TMConfig.h"
#include <TStyle.h>
#include <TGText.h>
#include <TGTextView.h>

//_____________________________________________________________________
TMHistogrammingEventDump::TMHistogrammingEventDump() :
  TMHistogramming(), fTimeStampPresent(kTRUE), fModeCollider(kTRUE), fNrLines(0), fDumpToTerminal(kTRUE)
{
}
//_____________________________________________________________________
TMHistogrammingEventDump::~TMHistogrammingEventDump() {
}
//_____________________________________________________________________
void TMHistogrammingEventDump::StartEvent(eventHeaderStruct *event, UInt_t globalEventNumber) {
  TMHistogramming::StartEvent(event, globalEventNumber);
}
//_____________________________________________________________________
void TMHistogrammingEventDump::ProcessEvent(eventHeaderStruct *event) {
  fEvent = event;
}
//_____________________________________________________________________
void TMHistogrammingEventDump::EndEvent(AliITSRawStreamSPD *str, UInt_t globalEventNumber) {
  TMHistogramming::EndEvent(str, globalEventNumber);
}
//_____________________________________________________________________
void TMHistogrammingEventDump::Dump(TGTextView *textview) {
  if (fDumpToTerminal) {
    DumpBuffer();
  }
  else {
    textview->Clear();
    LoadBuffer(textview);
    fNeedRedump=kFALSE;
  }
}
//_____________________________________________________________________
void TMHistogrammingEventDump::DumpBuffer() {
  for (UInt_t i=0; i<fNrLines; i++) {
    printf("%s\n",fTextLines[i].Data());
  }
  if (fNrLines>0) printf("\n");
}
//_____________________________________________________________________
void TMHistogrammingEventDump::LoadBuffer(TGTextView *textview) {
  for (UInt_t i=0; i<fNrLines; i++) {
    textview->AddLineFast(fTextLines[i].Data());
  }
  textview->AddLineFast(" ");
  textview->AddLineFast(" ");
  textview->Update();
}
//_____________________________________________________________________
void TMHistogrammingEventDump::Reset() {
  fNrLines=0;

  fNeedRedump=kTRUE;

  TMHistogramming::Reset();
}
//_____________________________________________________________________
void TMHistogrammingEventDump::DumpPayload(void *ptr) {
  if (NULL==ptr) return;

  Int_t *intPtr = (Int_t*)ptr;
  Int_t i=0, eventSize = (*intPtr)/4;
  struct DATEstartCaster *dsc;
  dsc = (struct DATEstartCaster*)ptr;
  struct DATEraw *raw;
  raw = (struct DATEraw *)ptr;
  Bool_t LDC_false_GDC_true;
  struct equipmentCaster *ec;
  struct headerCaster *hc;
  Int_t  *integerPointer;

  if (0x00030003 <= dsc->header0.eventVersion && 68==dsc->header0.eventHeadSize) 
    fTimeStampPresent = kTRUE;
  else 
    fTimeStampPresent = kFALSE;
        
  if (true == TEST_ANY_ATTRIBUTE(dsc->header0.eventTypeAttribute, ATTR_ORBIT_BC)) fModeCollider = kTRUE;
  else fModeCollider = kFALSE;
    
  if (dsc->header0.eventMagic == EVENT_MAGIC_NUMBER && 
      dsc->header1.eventMagic == EVENT_MAGIC_NUMBER) {
    integerPointer = &(raw->w[i]);
    hc = (struct headerCaster *)integerPointer;
    DumpHeaderStruct(hc, 2);
    if (!fTimeStampPresent) {
      i+=16;
    } 
    else {
      i+=17;
    }
    LDC_false_GDC_true = kTRUE;
  } 
  else if (dsc->header0.eventMagic == EVENT_MAGIC_NUMBER &&
	     dsc->header1.eventMagic != EVENT_MAGIC_NUMBER) {
    LDC_false_GDC_true = kFALSE;
  } 
  else {
    printf("ERROR TMHistogrammingEventDump::DumpPayload: Format fbr !..\n");
    return;
  }

  if (NULL==raw) {
    printf("################## NULL==raw\n\n\n");
  }
	
  Int_t ldcSize=0, eqSize=0, eqSizeSum=0, ldcSizeSum=0, baslikKelimeSayisi=0;
  while(i<eventSize) { // move over 32bits-words
    while(raw->w[i]==Int_t(0xda1e5afe)) {  // LDC header mi ?
      i-=1;
      integerPointer = &(raw->w[i]);
      hc = (struct headerCaster *)integerPointer;
      DumpHeaderStruct(hc, 2);
      ldcSize = (raw->w[i])/4;
      ldcSizeSum+=ldcSize;
      if (!fTimeStampPresent) {
	i+=16;
	baslikKelimeSayisi=16;
      } 
      else {
	i+=17;
	baslikKelimeSayisi=17;
      }
      Int_t k=i;
      eqSizeSum=0;

      if (k+ldcSize-baslikKelimeSayisi > eventSize) {
	break;
      }

      while (i<k+ldcSize-baslikKelimeSayisi) {  // equipment mi ?
	Int_t eqID = raw->w[i+2];
	integerPointer = &(raw->w[i]);
	ec = (struct equipmentCaster *)integerPointer;
	if (eqID>=0 && eqID<20 && TMConfig::Instance()->GETeqActive(eqID)){
	  if (!DumpPayloadStruct(ec)) return;
	}
	eqSize = raw->w[i]/4;
	if (0x300d0401 == TMConfig::Instance()->GETmoodVersionFlag()) {
	  eqSizeSum+=eqSize;
	  i+=eqSize;        
	} 
	else if (0x300d0301 == TMConfig::Instance()->GETmoodVersionFlag()) {
	  eqSizeSum+=eqSize+7;
	  i+=eqSize+7;        
	}
      }
    }
    i++;
  }

}

//___________________________________________________________________________________
void TMHistogrammingEventDump::DumpHeader(void *ptr) {
  if (NULL==ptr) return;

  Int_t *intPtr = (Int_t*)ptr;
  Int_t i=0, eventSize = (*intPtr)/4;
  struct DATEstartCaster *dsc;
  dsc = (struct DATEstartCaster*)ptr;
  struct DATEraw *raw;
  raw = (struct DATEraw *)ptr;
  Bool_t LDC_false_GDC_true;
  struct equipmentCaster *ec;
  struct headerCaster *hc;
  Int_t  *integerPointer;
    
  if (0x00030003 <= dsc->header0.eventVersion && 68==dsc->header0.eventHeadSize)
    fTimeStampPresent = kTRUE;
  else
    fTimeStampPresent = kFALSE;
        
  if (true == TEST_ANY_ATTRIBUTE(dsc->header0.eventTypeAttribute, ATTR_ORBIT_BC))
    fModeCollider = kTRUE;
  else
    fModeCollider = kFALSE;
	
  if (dsc->header0.eventMagic == EVENT_MAGIC_NUMBER && 
      dsc->header1.eventMagic == EVENT_MAGIC_NUMBER) {
    integerPointer = &(raw->w[i]);
    hc = (struct headerCaster *)integerPointer;
    DumpHeaderStruct(hc, 4);
    if (!fTimeStampPresent) {
      i+=16;
    } 
    else {
      i+=17;
    }
    LDC_false_GDC_true = kTRUE;
  } 
  else if (dsc->header0.eventMagic == EVENT_MAGIC_NUMBER &&
	     dsc->header1.eventMagic != EVENT_MAGIC_NUMBER) {
    LDC_false_GDC_true = kFALSE;
  } 
  else {
    printf("Error : Format fbr !..\n");
    return;
  }
	
  if (NULL==raw) {
    printf("################## NULL==raw\n\n\n");
  };
	
  Int_t ldcSize=0, eqSize=0, eqSizeSum=0, ldcSizeSum=0, baslikKelimeSayisi=0;
  while(i<eventSize) { // move over 32bits-words
    while(raw->w[i]==Int_t(0xda1e5afe)) {  // LDC header mi ?
      i-=1;
      integerPointer = &(raw->w[i]);
      hc = (struct headerCaster *)integerPointer;
      DumpHeaderStruct(hc, 4);
      ldcSize = (raw->w[i])/4;
      ldcSizeSum+=ldcSize;
      if (!fTimeStampPresent) {
	i+=16;
	baslikKelimeSayisi=16;
      } else {
	i+=17;
	baslikKelimeSayisi=17;
      }
      Int_t k=i;
      eqSizeSum=0;

      if (k+ldcSize-baslikKelimeSayisi > eventSize) {
	break;
      }

      while (i<k+ldcSize-baslikKelimeSayisi) {  // equipment mi ?
	//	Int_t eqID = raw->w[i+2];
	integerPointer = &(raw->w[i]);
	ec = (struct equipmentCaster *)integerPointer;
	//	if (eqID>=0 && eqID<20 && o.eqActive[eqID]){
	DumpEquipmentHeaderStruct(ec, 4);
	//	}
	eqSize = raw->w[i]/4;
	if (0x300d0401 == TMConfig::Instance()->GETmoodVersionFlag()) {
	  eqSizeSum+=eqSize;
	  i+=eqSize;        
	} 
	else if (0x300d0301 == TMConfig::Instance()->GETmoodVersionFlag()) {
	  eqSizeSum+=eqSize+7;
	  i+=eqSize+7;        
	}
      }
    }
    i++;
  }
    
}
//___________________________________________________________________________________
void TMHistogrammingEventDump::DumpHeaderShort(void *ptr) {
  if (NULL==ptr) return;

  Int_t *intPtr = (Int_t*)ptr;
  Int_t i=0, eventSize = (*intPtr)/4;
  struct DATEstartCaster *dsc;
  dsc = (struct DATEstartCaster*)ptr;
  struct DATEraw *raw;
  raw = (struct DATEraw *)ptr;
  Bool_t LDC_false_GDC_true;
  struct equipmentCaster *ec;
  struct headerCaster *hc;
  Int_t  *integerPointer;
	
  if (0x00030003 <= dsc->header0.eventVersion && 68==dsc->header0.eventHeadSize) 
    fTimeStampPresent = kTRUE;
  else 
    fTimeStampPresent = kFALSE;
        
  if (true == TEST_ANY_ATTRIBUTE(dsc->header0.eventTypeAttribute, ATTR_ORBIT_BC)) 
    fModeCollider = kTRUE;
  else
    fModeCollider = kFALSE;
    
  if (dsc->header0.eventMagic == EVENT_MAGIC_NUMBER && 
      dsc->header1.eventMagic == EVENT_MAGIC_NUMBER) {
    integerPointer = &(raw->w[i]);
    hc = (struct headerCaster *)integerPointer;
    DumpHeaderStruct(hc, 2);
    if (!fTimeStampPresent) {
      i+=16;
    } 
    else {
      i+=17;
    }
    LDC_false_GDC_true = kTRUE;
  } 
  else if (dsc->header0.eventMagic == EVENT_MAGIC_NUMBER &&
	   dsc->header1.eventMagic != EVENT_MAGIC_NUMBER) {
    LDC_false_GDC_true = kFALSE;
  } 
  else {
    printf("Error : Format fbr !..\n");
    return;
  }
	
  if (NULL==raw) {
    printf("################## NULL==raw\n\n\n");
  }
	
  Int_t ldcSize=0, eqSize=0, eqSizeSum=0, ldcSizeSum=0, baslikKelimeSayisi=0;
  while(i<eventSize) { // move over 32bits-words
    while(raw->w[i]==Int_t(0xda1e5afe)) {  // LDC header mi ?
      i-=1;
      integerPointer = &(raw->w[i]);
      hc = (struct headerCaster *)integerPointer;
      DumpHeaderStruct(hc, 2);
      ldcSize = (raw->w[i])/4;
      ldcSizeSum+=ldcSize;
      if (!fTimeStampPresent) {
	i+=16;
	baslikKelimeSayisi=16;
      } 
      else {
	i+=17;
	baslikKelimeSayisi=17;
      }
      Int_t k=i;
      eqSizeSum=0;

      if (k+ldcSize-baslikKelimeSayisi > eventSize) {
	break;
      }
      
      while (i<k+ldcSize-baslikKelimeSayisi) {  // equipment mi ?
	//	Int_t eqID = raw->w[i+2];
	integerPointer = &(raw->w[i]);
	ec = (struct equipmentCaster *)integerPointer;
	//	if (eqID>=0 && eqID<20 && o.eqActive[eqID]){
	DumpEquipmentHeaderStruct(ec, 2);
	//	}
	eqSize = raw->w[i]/4;
	if (0x300d0401 == TMConfig::Instance()->GETmoodVersionFlag()) {
	  eqSizeSum+=eqSize;
	  i+=eqSize;        
	} 
	else if (0x300d0301 == TMConfig::Instance()->GETmoodVersionFlag()) {
	  eqSizeSum+=eqSize+7;
	  i+=eqSize+7;
	}
      }
    }
    i++;
  }
}




//___________________________________________________________________________________
void TMHistogrammingEventDump::DumpHeaderLong(void *ptr) {
  if (NULL==ptr) return;

  Int_t *intPtr = (Int_t*)ptr;
  Int_t i=0, eventSize = (*intPtr)/4;
  struct DATEstartCaster *dsc;
  dsc = (struct DATEstartCaster*)ptr;
  struct DATEraw *raw;
  raw = (struct DATEraw *)ptr;
  Bool_t LDC_false_GDC_true;
  struct equipmentCaster *ec;
  struct headerCaster *hc;
  Int_t  *integerPointer;

  if (0x00030003 <= dsc->header0.eventVersion && 68==dsc->header0.eventHeadSize)
    fTimeStampPresent = kTRUE;
  else
    fTimeStampPresent = kFALSE;
        
  if (true == TEST_ANY_ATTRIBUTE(dsc->header0.eventTypeAttribute, ATTR_ORBIT_BC))
    fModeCollider = kTRUE;
  else
    fModeCollider = kFALSE;

  if (dsc->header0.eventMagic == EVENT_MAGIC_NUMBER && 
      dsc->header1.eventMagic == EVENT_MAGIC_NUMBER) {
    integerPointer = &(raw->w[i]);
    hc = (struct headerCaster *)integerPointer;
    DumpHeaderStruct(hc, 4);
    if (!fTimeStampPresent) {
      i+=16;
    } 
    else {
      i+=17;
    }
    LDC_false_GDC_true = kTRUE;
  } 
  else if (dsc->header0.eventMagic == EVENT_MAGIC_NUMBER &&
	   dsc->header1.eventMagic != EVENT_MAGIC_NUMBER) {
    LDC_false_GDC_true = kFALSE;
  } 
  else {
    printf("Error : Format fbr !..\n");
    return;
  }
	
  if (NULL==raw) {
    printf("################## NULL==raw\n\n\n");
  }
	
  Int_t ldcSize=0, eqSize=0, eqSizeSum=0, ldcSizeSum=0, baslikKelimeSayisi=0;
  while(i<eventSize) { // move over 32bits-words
    while(raw->w[i]==Int_t(0xda1e5afe)) {  // LDC header mi ?
      i-=1;
      integerPointer = &(raw->w[i]);
      hc = (struct headerCaster *)integerPointer;
      DumpHeaderStruct(hc, 4);
      ldcSize = (raw->w[i])/4;
      ldcSizeSum+=ldcSize;
      if (!fTimeStampPresent) {
	i+=16;
	baslikKelimeSayisi=16;
      } 
      else {
	i+=17;
	baslikKelimeSayisi=17;
      }
      Int_t k=i;
      eqSizeSum=0;

      if (k+ldcSize-baslikKelimeSayisi > eventSize) {
	break;
      }

      while (i<k+ldcSize-baslikKelimeSayisi) {  // equipment mi ?
	//	Int_t eqID = raw->w[i+2];
	integerPointer = &(raw->w[i]);
	ec = (struct equipmentCaster *)integerPointer;
	//	if (eqID>=0 && eqID<20 && o.eqActive[eqID]){
	DumpEquipmentHeaderStruct(ec, 4);
	//	}
	eqSize = raw->w[i]/4;
	if (0x300d0401 == TMConfig::Instance()->GETmoodVersionFlag()) {
	  eqSizeSum+=eqSize;
	  i+=eqSize;        
	} else if (0x300d0301 == TMConfig::Instance()->GETmoodVersionFlag()) {
	  eqSizeSum+=eqSize+7;
	  i+=eqSize+7;        
	}
      }
    }
    i++;
  }
}
//_____________________________________________________________________
void TMHistogrammingEventDump::DumpCalibHeader(void *ptr, UInt_t globalEventNumber) {
  if (NULL==ptr) return;

  Int_t *intPtr = (Int_t*)ptr;
  Int_t i=0, eventSize = (*intPtr)/4;
  struct DATEstartCaster *dsc;
  dsc = (struct DATEstartCaster*)ptr;
  struct DATEraw *raw;
  raw = (struct DATEraw *)ptr;
  Bool_t LDC_false_GDC_true;
  struct equipmentCaster *ec;
  struct headerCaster *hc;
  Int_t  *integerPointer;

  if (0x00030003 <= dsc->header0.eventVersion && 68==dsc->header0.eventHeadSize) 
    fTimeStampPresent = kTRUE;
  else 
    fTimeStampPresent = kFALSE;
        
  if (true == TEST_ANY_ATTRIBUTE(dsc->header0.eventTypeAttribute, ATTR_ORBIT_BC)) fModeCollider = kTRUE;
  else fModeCollider = kFALSE;
    
  if (dsc->header0.eventMagic == EVENT_MAGIC_NUMBER && 
      dsc->header1.eventMagic == EVENT_MAGIC_NUMBER) {
    integerPointer = &(raw->w[i]);
    hc = (struct headerCaster *)integerPointer;
    //    DumpHeaderStruct(hc, 2);
    if (!fTimeStampPresent) {
      i+=16;
    } 
    else {
      i+=17;
    }
    LDC_false_GDC_true = kTRUE;
  } 
  else if (dsc->header0.eventMagic == EVENT_MAGIC_NUMBER &&
	     dsc->header1.eventMagic != EVENT_MAGIC_NUMBER) {
    LDC_false_GDC_true = kFALSE;
  } 
  else {
    printf("ERROR TMHistogrammingEventDump::DumpPayload: Format fbr !..\n");
    return;
  }

  if (NULL==raw) {
    printf("################## NULL==raw\n\n\n");
  }
	
  Int_t ldcSize=0, eqSize=0, eqSizeSum=0, ldcSizeSum=0, baslikKelimeSayisi=0;
  while(i<eventSize) { // move over 32bits-words
    while(raw->w[i]==Int_t(0xda1e5afe)) {  // LDC header mi ?
      i-=1;
      integerPointer = &(raw->w[i]);
      hc = (struct headerCaster *)integerPointer;
      //      DumpHeaderStruct(hc, 2);
      ldcSize = (raw->w[i])/4;
      ldcSizeSum+=ldcSize;
      if (!fTimeStampPresent) {
	i+=16;
	baslikKelimeSayisi=16;
      } 
      else {
	i+=17;
	baslikKelimeSayisi=17;
      }
      Int_t k=i;
      eqSizeSum=0;

      if (k+ldcSize-baslikKelimeSayisi > eventSize) {
	break;
      }

      while (i<k+ldcSize-baslikKelimeSayisi) {  // equipment mi ?
	Int_t eqID = raw->w[i+2];
	integerPointer = &(raw->w[i]);
	ec = (struct equipmentCaster *)integerPointer;
	if (eqID>=0 && eqID<20 && TMConfig::Instance()->GETeqActive(eqID)){
	  if ( (ec->mhc.Get_block_att_24_31() & 0x40) == 0) return; // no calib header
	  if (!DumpCalibHeaderStruct(ec,globalEventNumber)) return;
	}
	eqSize = raw->w[i]/4;
	if (0x300d0401 == TMConfig::Instance()->GETmoodVersionFlag()) {
	  eqSizeSum+=eqSize;
	  i+=eqSize;        
	} 
	else if (0x300d0301 == TMConfig::Instance()->GETmoodVersionFlag()) {
	  eqSizeSum+=eqSize+7;
	  i+=eqSize+7;        
	}
      }
    }
    i++;
  }
}








//___________________________________________________________________________________
Bool_t TMHistogrammingEventDump::DumpHeaderStruct(struct headerCaster *hc, Int_t status) {
  // dump header struct
  // status = 100 for only headers, 010 for only eventDump-like, 001 for only exact dump
  //        = 110, 011, 101, 111 can be used as well (binary)

  Char_t line[1000];
  if ( (status & 0x00000004)>>2 == 1 ) {
    DumpThis(" ");
    DumpThis("A Header Struct");
    DumpThis("---------------");
    DumpThis("eventSize...................", hc->header.eventSize, "dec");
    DumpThis("eventMagic..................", hc->header.eventMagic, "hex");
    DumpThis("eventHeadSize...............", hc->header.eventHeadSize, "dec");
    DumpThis("eventVersion................", hc->header.eventVersion, "hex");
    DumpThis("eventType...................", hc->header.eventType, "dec");
    DumpThis("eventRunNb..................", hc->header.eventRunNb, "dec");
    if (!fModeCollider) {
      DumpThis("eventId[0]..................", hc->header.eventId[0], "hex");
      DumpThis("eventId[1]..................", hc->header.eventId[1], "hex");
    } else {
      DumpThis("Period......................", EVENT_ID_GET_PERIOD(hc->header.eventId), "dec");
      DumpThis("Orbit.......................", EVENT_ID_GET_ORBIT(hc->header.eventId), "dec");
      DumpThis("Bunch Crossing..............", EVENT_ID_GET_BUNCH_CROSSING(hc->header.eventId), "dec");
    }
    DumpThis("eventTriggerPattern[0]......", hc->header.eventTriggerPattern[0], "hex");
    DumpThis("eventTriggerPattern[1]......", hc->header.eventTriggerPattern[1], "hex");
    DumpThis("eventDetectorPattern[0].....", hc->header.eventDetectorPattern[0], "hex");
    DumpThis("eventTypeAttribute[0].......", hc->header.eventTypeAttribute[0], "hex");
    DumpThis("eventTypeAttribute[1].......", hc->header.eventTypeAttribute[1], "hex");
    DumpThis("eventTypeAttribute[2].......", hc->header.eventTypeAttribute[2], "hex");
    DumpThis("eventLdcId..................", hc->header.eventLdcId, "dec");
    DumpThis("eventGdcId..................", hc->header.eventGdcId, "dec");
    if (fTimeStampPresent) DumpThis("eventTimestamp..............", hc->header.eventTimestamp, "tme");
    if (fTimeStampPresent) DumpThis("eventTimestamp...........dec", hc->header.eventTimestamp, "dec");
    
  }
  if ( (status & 0x00000002)>>1 == 1 || (status & 0x00000001) == 1) {
    DumpThis("_______________________________________________________________________ LDC/GDC Header");
    sprintf(line, "Size:%d (header:%d) Version:0x%08x Type:%d", hc->header.eventSize, hc->header.eventHeadSize, hc->header.eventVersion, hc->header.eventType);
    DumpThis(line);
    if (!fModeCollider) {
      sprintf(line, "RunNb:%d nbInRun:%d ldcId:%d gdcId:%d",
	      hc->header.eventRunNb, hc->header.eventId[0], hc->header.eventLdcId, hc->header.eventGdcId);
    } else {
      time_t time;
      time=(time_t)hc->header.eventTimestamp;
      Char_t *s;
      s=ctime(&time);
      s[strlen(s)-1]=0;
      sprintf(line, "RunNb:%d Period:%d Orbit:%d BunchCrossing:%d ldcId:%d gdcId:%d time:%s",
	      hc->header.eventRunNb,
	      EVENT_ID_GET_PERIOD(hc->header.eventId),
	      EVENT_ID_GET_ORBIT(hc->header.eventId),
	      EVENT_ID_GET_BUNCH_CROSSING(hc->header.eventId),
	      hc->header.eventLdcId,
	      hc->header.eventGdcId,
	      s);
    }
    DumpThis(line);
    sprintf(line, "Attributes:(0x%08x.0x%08x.0x%08x)", hc->header.eventTypeAttribute[0], hc->header.eventTypeAttribute[1], hc->header.eventTypeAttribute[2]);
    DumpThis(line);
    sprintf(line, "triggerPattern:0x%08x-0x%08x detectorPattern:0x%08x", hc->header.eventTriggerPattern[0], hc->header.eventTriggerPattern[1], hc->header.eventDetectorPattern[0]);
    DumpThis(line);
  }
  return kTRUE;
}
//___________________________________________________________________________________
Bool_t TMHistogrammingEventDump::DumpEquipmentHeaderStruct(struct equipmentCaster *ec, Int_t status, Bool_t spdOnly) { 
  // dump equipment header struct
  // status = 100 for only headers, 010 for only eventDump-like, 001 for only exact dump
  //        = 110, 011, 101, 111 can be used as well (binary)

  if (spdOnly && ec->eq.equipmentId >= 20) {
    // do nothing
    return kTRUE;
  }

  Char_t line[1000];
  if ( (status & 0x00000004)>>2 == 1 ) {
    // if first bit is set
    DumpThis(" ");
    DumpThis("An Equipment Header Struct");
    DumpThis("--------------------------");
    DumpThis("equipmentSize...............", ec->eq.equipmentSize, "dec");
    DumpThis("equipmentType...............", ec->eq.equipmentType, "dec");
    DumpThis("equipmentId.................", ec->eq.equipmentId, "dec");
    DumpThis("equipmentTypeAttribute[0]...", ec->eq.equipmentTypeAttribute[0], "hex");
    DumpThis("equipmentTypeAttribute[1]...", ec->eq.equipmentTypeAttribute[1], "hex");
    DumpThis("equipmentTypeAttribute[2]...", ec->eq.equipmentTypeAttribute[2], "hex");
    DumpThis("equipmentBasicElementSize...", ec->eq.equipmentBasicElementSize, "dec");
    DumpThis(" ");
    DumpThis("A Common Data Header Struct                               Binary Representation");
    DumpThis("------------------------------------------------------    -------------------------------");
    DumpThis("blockLength_0_31...................", ec->mhc.Get_blockLength_0_31()                 , "bin", 32);
    DumpThis("event_ID1_0_11.....................", ec->mhc.Get_event_ID1_0_11()                   , "bin", 12);
    DumpThis("MBZ_12_13..........................", ec->mhc.Get_MBZ_12_13()                        , "bin", 2);
    DumpThis("L1_trigger_type_14_23..............", ec->mhc.Get_L1_trigger_type_14_23()            , "bin", 10);
    DumpThis("format_version_24_31...............", ec->mhc.Get_format_version_24_31()             , "bin", 8);
    DumpThis("eventID2_0_23......................", ec->mhc.Get_eventID2_0_23()                    , "bin", 24);
    DumpThis("MBZ2_24_31.........................", ec->mhc.Get_MBZ2_24_31()                       , "bin", 8);
    DumpThis("participating_sub_detectors_0_23...", ec->mhc.Get_participating_sub_detectors_0_23() , "bin", 24);
    DumpThis("block_att_24_31....................", ec->mhc.Get_block_att_24_31()                  , "bin", 8);
    DumpThis("mini_event_ID_0_11.................", ec->mhc.Get_mini_event_ID_0_11()               , "bin", 12);
    DumpThis("status_error_bits_12_27............", ec->mhc.Get_status_error_bits_12_27()          , "bin", 16);
    DumpThis("ResBZ_28_31........................", ec->mhc.Get_ResBZ_28_31()                      , "bin", 4);
    DumpThis("trigger_classes_low_0_31...........", ec->mhc.Get_trigger_classes_low_0_31()         , "bin", 32);
    DumpThis("trigger_classes_high_0_17..........", ec->mhc.Get_trigger_classes_high_0_17()        , "bin", 18);
    DumpThis("MBZ_18_27..........................", ec->mhc.Get_MBZ_18_27()                        , "bin", 10);
    DumpThis("ROI_Low_28_31......................", ec->mhc.Get_ROI_Low_28_31()                    , "bin", 4);
    DumpThis("ROI_High_0_31......................", ec->mhc.Get_ROI_High_0_31()                    , "bin", 32);
    DumpThis(" ");
  }
	
  if ( (status & 0x00000002)>>1 == 1 || (status & 0x00000001) == 1) {
    // if second bit is set
    DumpThis("_______________________________________________________________________ Equipment Header");
    sprintf(line, "Size:%d Type:%d ID:%d Attribute:(0x%08x.0x%08x.0x%08x)",
	    ec->eq.equipmentSize,
	    ec->eq.equipmentType,
	    ec->eq.equipmentId,
	    ec->eq.equipmentTypeAttribute[0],
	    ec->eq.equipmentTypeAttribute[1],
	    ec->eq.equipmentTypeAttribute[2]);
    DumpThis(line);
    sprintf(line, "BlockLength:%d EventID:%d L1_Type:%d Common Data (Mini) Header",
	    ec->mhc.Get_blockLength_0_31(),
	    ec->mhc.Get_event_ID1_0_11(),
	    ec->mhc.Get_L1_trigger_type_14_23());
    DumpThis(line);

  }
  return kTRUE;
}
//___________________________________________________________________________________
Bool_t TMHistogrammingEventDump::DumpPayloadStruct(struct equipmentCaster *ec) {
  // dump payload

  Char_t line[500], line2[100];
  Int_t numberOfLines, numberOfResidualWords, mask[4], size=0;
  div_t d;

  mask[0] = 0xff000000;
  mask[1] = 0x00ff0000;
  mask[2] = 0x0000ff00;
  mask[3] = 0x000000ff;
    
  if (0x300D0301 == TMConfig::Instance()->GETmoodVersionFlag()) size = ec->eq.equipmentSize/4;
  //  if (0x300D0401 == o.moodVersionFlag) size = ((ec->eq.equipmentSize)-60)/4;  // Not all of the equipment 
  if (0x300D0401 == TMConfig::Instance()->GETmoodVersionFlag()) size = (ec->eq.equipmentSize)/4;  // Not all of the equipment 
  // payloads has a data format header
  // this is why it is 28 but not 60. !!! HT: changed from 28 to 60 !!!
  d = div(size, 4);
  numberOfLines = d.quot;
  numberOfResidualWords = d.rem;
	
  for (int i=0 ; i<numberOfLines*4 ; i+=4) {
    sprintf(line, "| %08d) %08x %08x %08x %08x | ",
	    i*4,
	    ec->justAfter[i-15],
	    ec->justAfter[i-15+1],
	    ec->justAfter[i-15+2],
	    ec->justAfter[i-15+3]
	    );
    for (int j=0 ; j<4 ; j++) {
      if (i+j>=15) {
	strcat(line, parseWord(ec->justAfter[i-15+j]).Data());
      }
      else {
	strcat(line, "                    ");
      }
    }
    strcat(line, "|");
    if (!DumpThis(line)) return kFALSE;
  }
  if (numberOfResidualWords != 0) {
    sprintf(line, "| %08d) ", numberOfLines*16);
    for (int i=0 ; i<numberOfResidualWords ; i++) {
      sprintf(line2, "%08x ", ec->justAfter[numberOfLines*4+i-15]);
      strcat(line, line2);
    }
    for (int i=0 ; i<4-numberOfResidualWords ; i++) {
      strcat(line, "         ");
    }
    strcat(line, "| ");
    for (int j=0 ; j<numberOfResidualWords ; j++) {
      strcat(line, parseWord(ec->justAfter[numberOfLines*4-15+j]).Data());
    }
    strcat(line, "|");
    if (!DumpThis(line)) return kFALSE;
  }
  return kTRUE;
}
//___________________________________________________________________________________
Bool_t TMHistogrammingEventDump::DumpCalibHeaderStruct(struct equipmentCaster *ec, UInt_t globalEventNumber) {
  Int_t *intPtr = (Int_t*)&(ec->justAfter[0]);
  Int_t headerLen=*intPtr; // Header length
  if (headerLen==0) return kFALSE;

  UInt_t eqID = ec->eq.equipmentId;

  Char_t eqMess[100];
  sprintf(eqMess,"--- Event %d , EqID %d , Length %d ---",globalEventNumber, eqID, headerLen);
  DumpThis(eqMess);

  Int_t calHeadWord[AliITSRawStreamSPD::kCalHeadLenMax];
  for (Int_t iword=0; iword<headerLen; iword++) {
    intPtr++;
    calHeadWord[iword]=*((Int_t *)intPtr);
  }

  UInt_t type = (Int_t)((calHeadWord[1]) & 0x000000ff);


  if (type!=FASTOR) { // SCAN CALIB

    // header data variables
    UInt_t routerNr;
    Bool_t halfStaveScanned[6];
    Bool_t dataFormat;
    UInt_t triggers;
    Bool_t chipPresent[6][10];
    UInt_t dacStart;  
    UInt_t dacEnd;
    UInt_t dacStep;
    UInt_t dacId;
    UInt_t rowStart;  
    UInt_t rowEnd;
    UInt_t rowValue;
    UInt_t dacValue;
    UInt_t dacHigh[6];
    UInt_t dacLow[6];
    UInt_t TPAmp[6];
    UInt_t globalDBversion;
    Bool_t minTHchipPresent[10];

    // read calib values
    routerNr = (calHeadWord[0] & 0x0000003f);
    dataFormat = (Bool_t)(((calHeadWord[1]) & 0x00000100)>>8);
    triggers = calHeadWord[2];
    dacStart = ((calHeadWord[5]>>24) & 0x000000ff);
    dacEnd = ((calHeadWord[5]>>16) & 0x000000ff);
    dacStep = ((calHeadWord[5]>>8) & 0x000000ff);
    dacId = ((calHeadWord[5]) & 0x000000ff);
    rowStart = (UInt_t) ((calHeadWord[6]>>24) & 0x000000ff);
    rowEnd = (UInt_t) ((calHeadWord[6]>>16) & 0x000000ff);
    rowValue = (UInt_t) ((calHeadWord[6]>> 8) & 0x000000ff);
    dacValue = (Int_t) ((calHeadWord[6]) & 0x000000ff);

    for (UInt_t hs=0; hs<6; hs++) {
      halfStaveScanned[hs]=(Bool_t)((calHeadWord[0]>>(6+hs)) & (0x00000001));
      dacHigh[hs] = (calHeadWord[hs/2+7]>>(24-16*(hs%2)) & 0x000000ff);
      dacLow[hs] = (calHeadWord[hs/2+7]>>(16-16*(hs%2)) & 0x000000ff);
      TPAmp[hs] = calHeadWord[hs+10];
      for (UInt_t chip=0; chip<10; chip++) {
	chipPresent[hs][chip] = ((( calHeadWord[hs/3+3]>>((hs%3)*10+chip)) & 0x00000001) == 1);
      }
    }

    for (UInt_t chip=0; chip<10; chip++) {
      minTHchipPresent[chip] = ((( calHeadWord[7]>>(16+chip)) & 0x00000001) == 1);
    }
    globalDBversion = calHeadWord[16];


    for (Int_t iword=0; iword<headerLen; iword++) {
      Char_t wordMess[200];
      Char_t wordMessTmp[200];
      sprintf(wordMessTmp,"%2d: %08x",iword,calHeadWord[iword]);
    
      if      (iword==0) {
	sprintf(wordMess,"%s | RouterNr %d , HS scanned %d%d%d%d%d%d",
		wordMessTmp,routerNr,halfStaveScanned[0],halfStaveScanned[1],halfStaveScanned[2],
		halfStaveScanned[3],halfStaveScanned[4],halfStaveScanned[5]);
      }
      else if (iword==1) {
	if (dataFormat==kTRUE) {
	  sprintf(wordMess,"%s | Type %d , DataFormat \"histogram\"",wordMessTmp,type);
	}
	else {
	  sprintf(wordMess,"%s | Type %d , DataFormat \"normal\"",wordMessTmp,type);	
	}
      }
      else if (iword==2) {
	sprintf(wordMess,"%s | Triggers %d",wordMessTmp,triggers);
      }
      else if (iword==3) {
	sprintf(wordMess,"%s | Chip present HS 0 1 2:  %d%d%d%d%d%d%d%d%d%d %d%d%d%d%d%d%d%d%d%d %d%d%d%d%d%d%d%d%d%d",
		wordMessTmp,chipPresent[0][0],chipPresent[0][1],
		chipPresent[0][2],chipPresent[0][3],chipPresent[0][4],chipPresent[0][5],
		chipPresent[0][6],chipPresent[0][7],chipPresent[0][8],chipPresent[0][9],
		chipPresent[1][0],chipPresent[1][1],chipPresent[1][2],chipPresent[1][3],
		chipPresent[1][4],chipPresent[1][5],chipPresent[1][6],chipPresent[1][7],
		chipPresent[1][8],chipPresent[1][9],chipPresent[2][0],chipPresent[2][1],
		chipPresent[2][2],chipPresent[2][3],chipPresent[2][4],chipPresent[2][5],
		chipPresent[2][6],chipPresent[2][7],chipPresent[2][8],chipPresent[2][9]);
      }
      else if (iword==4) {
	sprintf(wordMess,"%s | Chip present HS 3 4 5:  %d%d%d%d%d%d%d%d%d%d %d%d%d%d%d%d%d%d%d%d %d%d%d%d%d%d%d%d%d%d",
		wordMessTmp,chipPresent[3][0],chipPresent[3][1],
		chipPresent[3][2],chipPresent[3][3],chipPresent[3][4],chipPresent[3][5],
		chipPresent[3][6],chipPresent[3][7],chipPresent[3][8],chipPresent[3][9],
		chipPresent[4][0],chipPresent[4][1],chipPresent[4][2],chipPresent[4][3],
		chipPresent[4][4],chipPresent[4][5],chipPresent[4][6],chipPresent[4][7],
		chipPresent[4][8],chipPresent[4][9],chipPresent[5][0],chipPresent[5][1],
		chipPresent[5][2],chipPresent[5][3],chipPresent[5][4],chipPresent[5][5],
		chipPresent[5][6],chipPresent[5][7],chipPresent[5][8],chipPresent[5][9]);
      }
      else if (iword==5) {
	sprintf(wordMess,"%s | DacStart %d , DacEnd %d , DacStep %d , DacId %d",
		wordMessTmp,dacStart,dacEnd,dacStep,dacId);
      }
      else if (iword==6 && (type==MEANTH || type==UNIMA)) {
	sprintf(wordMess,"%s | RowStart %d , RowEnd %d , RowValue %d , RowSpan %d",
		wordMessTmp,rowStart,rowEnd,rowValue,dacValue);
      }
      else if (iword==6) {
	sprintf(wordMess,"%s | RowStart %d , RowEnd %d , RowValue %d , DacValue %d",
		wordMessTmp,rowStart,rowEnd,rowValue,dacValue);
      }
      else if (iword==7 && type==MINTH) {
	sprintf(wordMess,"%s | MinTh: chips scanned %d%d%d%d%d%d%d%d%d%d",
		wordMessTmp,minTHchipPresent[0],minTHchipPresent[1],
		minTHchipPresent[2],minTHchipPresent[3],minTHchipPresent[4],
		minTHchipPresent[5],minTHchipPresent[6],minTHchipPresent[7],
		minTHchipPresent[8],minTHchipPresent[9]);
      }
      else if (iword==7 && type==DELAY) {
	sprintf(wordMess,"%s | MiscCtrl %d",
		wordMessTmp,dacHigh[0]);
      }
      else if (iword==7 && type==MEANTH) {
	sprintf(wordMess,"%s | DacHigh,DacLow HS 0 1: %d,%d  %d,%d",
		wordMessTmp,dacHigh[0],dacLow[0],dacHigh[1],dacLow[1]);
      }
      else if (iword==7) {
	sprintf(wordMess,"%s |",wordMessTmp);
      }
      else if (iword==8 && type==MEANTH) {
	sprintf(wordMess,"%s | DacHigh,DacLow HS 2 3: %d,%d  %d,%d",
		wordMessTmp,dacHigh[2],dacLow[2],dacHigh[3],dacLow[3]);
      }
      else if (iword==8) {
	sprintf(wordMess,"%s |",wordMessTmp);
      }
      else if (iword==9 && type==MEANTH) {
	sprintf(wordMess,"%s | DacHigh,DacLow HS 4 5: %d,%d  %d,%d",
		wordMessTmp,dacHigh[4],dacLow[4],dacHigh[5],dacLow[5]);
      }
      else if (iword==9) {
	sprintf(wordMess,"%s |",wordMessTmp);
      }
      else if (iword>=10 && iword<16 && type==MEANTH) {
	sprintf(wordMess,"%s | TP Amp HS %d: %d",
		wordMessTmp,iword-10,TPAmp[iword-10]);
      }
      else if (iword>=10 && iword<16) {
	sprintf(wordMess,"%s |",wordMessTmp);
      }
      else if (iword==16) {
	sprintf(wordMess,"%s | Global DB Version: %d",wordMessTmp,globalDBversion);
      }

      DumpThis(wordMess);

    }

  }
  else { // FASTOR CALIB
    if (headerLen<39) {
      printf("ERROR: TMHistogrammingEventDump::DumpCalibHeaderStruct: Calib Header length < 39\n");
      return kFALSE;
    }

    Bool_t chipPresent[6][10];
    for (UInt_t hs=0; hs<6; hs++) {
      for (UInt_t chip=0; chip<10; chip++) {
	chipPresent[hs][chip] = ((( calHeadWord[hs/3+3]>>((hs%3)*10+chip)) & 0x00000001) == 1);
      }
    }

    for (Int_t iword=0; iword<7; iword++) {
      TString wordMess = "";
      if      (iword==0) {
	wordMess = Form("%2d: %08x | RouterNr: %d",iword,calHeadWord[iword],(calHeadWord[iword] & 0x0000003f));
      }
      else if (iword==1) {
	wordMess = Form("%2d: %08x | Type: %d",iword,calHeadWord[iword],(Int_t)((calHeadWord[iword]) & 0x000000ff));
      }
      else if (iword==2) {
	wordMess = Form("%2d: %08x | Triggers: %d",iword,calHeadWord[iword],calHeadWord[iword]);
      }
      else if (iword==3) {
	wordMess = Form("%2d: %08x | Chip present HS 0 1 2:  %d%d%d%d%d%d%d%d%d%d %d%d%d%d%d%d%d%d%d%d %d%d%d%d%d%d%d%d%d%d",
			iword,calHeadWord[iword],chipPresent[0][0],chipPresent[0][1],
			chipPresent[0][2],chipPresent[0][3],chipPresent[0][4],chipPresent[0][5],
			chipPresent[0][6],chipPresent[0][7],chipPresent[0][8],chipPresent[0][9],
			chipPresent[1][0],chipPresent[1][1],chipPresent[1][2],chipPresent[1][3],
			chipPresent[1][4],chipPresent[1][5],chipPresent[1][6],chipPresent[1][7],
			chipPresent[1][8],chipPresent[1][9],chipPresent[2][0],chipPresent[2][1],
			chipPresent[2][2],chipPresent[2][3],chipPresent[2][4],chipPresent[2][5],
			chipPresent[2][6],chipPresent[2][7],chipPresent[2][8],chipPresent[2][9]);
      }
      else if (iword==4) {
	wordMess = Form("%2d: %08x | Chip present HS 3 4 5:  %d%d%d%d%d%d%d%d%d%d %d%d%d%d%d%d%d%d%d%d %d%d%d%d%d%d%d%d%d%d",
			iword,calHeadWord[iword],chipPresent[3][0],chipPresent[3][1],
			chipPresent[3][2],chipPresent[3][3],chipPresent[3][4],chipPresent[3][5],
			chipPresent[3][6],chipPresent[3][7],chipPresent[3][8],chipPresent[3][9],
			chipPresent[4][0],chipPresent[4][1],chipPresent[4][2],chipPresent[4][3],
			chipPresent[4][4],chipPresent[4][5],chipPresent[4][6],chipPresent[4][7],
			chipPresent[4][8],chipPresent[4][9],chipPresent[5][0],chipPresent[5][1],
			chipPresent[5][2],chipPresent[5][3],chipPresent[5][4],chipPresent[5][5],
			chipPresent[5][6],chipPresent[5][7],chipPresent[5][8],chipPresent[5][9]);
      }
      else if (iword==5) {
	wordMess = Form("%2d: %08x | Global DB Version: %d",iword,calHeadWord[iword],calHeadWord[iword]);
      }
      else if (iword==6) {
	wordMess = Form("%2d: %08x | Test Pulse Matrix: %d , Pixel Col: %d , Pixel Row: %d",iword,calHeadWord[iword],
			calHeadWord[iword] & 0xf,
			(calHeadWord[iword] >> 20) & 0x1f,
			(calHeadWord[iword] >> 10) & 0xff);
      }
      DumpThis(wordMess.Data());
    }

    for (Int_t iword=7; iword<7+(headerLen-37); iword++) {
      TString wordMess = "";
      if (iword%2==1) {
	wordMess = Form("%2d: %08x | DAC%d Index: %d",iword,calHeadWord[iword],(iword-7)/2+1,calHeadWord[iword]);
      }
      else {
	wordMess = Form("%2d: %08x | DAC%d Value: %d",iword,calHeadWord[iword],(iword-7)/2+1,calHeadWord[iword]);
      }
      DumpThis(wordMess.Data());
    }

    for (UInt_t hs=0; hs<6; hs++) {
      TString wordMess = "";
      for (UInt_t chip=0; chip<10; chip++) {
	if (chip==0) wordMess.Append(Form("HS %d: ",hs));
	else         wordMess.Append(",");
	if (chip%2==0) {
	  wordMess.Append(Form("%5d",(calHeadWord[7 + (headerLen-37) + (hs*10 + chip)/2] >> 16) & 0x0000ffff));
	}
	else {
	  wordMess.Append(Form("%5d",calHeadWord[7 + (headerLen-37) + (hs*10 + chip)/2] & 0x0000ffff));
	}
      }
      DumpThis(wordMess.Data());
    }



  }

  
  return kTRUE;
}



//_____________________________________________________________________
Bool_t TMHistogrammingEventDump::DumpThis(const Char_t *msg) {
  if (fNrLines>=gMAXLINES-1) {
    if (fNrLines==gMAXLINES-1) {
      fTextLines[fNrLines] = Form("MAXIMUM NUMBER OF LINES (%d) REACHED...REST IS SKIPPED",gMAXLINES);
      fNrLines++;
    }
    return kFALSE;
  }
  fTextLines[fNrLines] = msg;
  fNrLines++;
  return kTRUE;
}
//_____________________________________________________________________
Bool_t TMHistogrammingEventDump::DumpThis(const Char_t *msg, Int_t value, Char_t *status, Int_t binaryLength) {
  // status = hex / dec / bin

  if (fNrLines>=gMAXLINES-1) {
    if (fNrLines==gMAXLINES-1) {
      fTextLines[fNrLines] = Form("MAXIMUM NUMBER OF LINES (%d) REACHED...REST IS SKIPPED",gMAXLINES);
      fNrLines++;
    }
    return kFALSE;
  }

  Char_t m[400];
  if ("hex" == status) sprintf(m, "%s : 0x%08x  (hex)", msg, value);
  if ("dec" == status) sprintf(m, "%s : %10d  (dec)", msg, value);
  if ("tme" == status) {
    time_t time;
    time=(time_t)value;
    Char_t *s;
    s=ctime(&time);
    s[strlen(s)-1]=0;
    sprintf(m, "%s : %s (tme)", msg, s);
  }
  if ("bin" == status) {
    sprintf(m, "%s : 0x%08x  (hex)   %02d bits dump : ", msg, value, binaryLength);
    for (Int_t i=binaryLength-1 ; i>=0 ; i--) {
      if ( 1 == ((value>>i)&(0x00000001)) ) {
	strcat(m, "1");
      } 
      else {
	strcat(m, "0");
      }
    }
  }

  //  TString messSTR = Form("%s",m);

  fTextLines[fNrLines] = m;
  fNrLines++;
  return kTRUE;
}
//_____________________________________________________________________
TString TMHistogrammingEventDump::parseWord(Int_t word) { 
  // input is 32-bit word

  TString returnVal = "";
  for (Int_t i=0; i<2; i++) {  // Two times 16 bits...
    Int_t word16 = 0;
    if (i==0) word16 = ((word & 0xffff0000) >> 16);
    if (i==1) word16 = ((word & 0x0000ffff)      );
    //    printf("W %x %x\n",word,word16);

    int id = (word16 >> 14) & 0x0003;
    if (id==2) {
      int row = (word16 >> 5) & 0x00ff;
      int col = (word16)      & 0x001f;
      TString appendVal = Form("DD-%02d-%03d ",col,row);
      returnVal.Append(appendVal);
    }
    else if (id==1) {
      int chip = word16 & 0x000f;
      int hs   = (word16 >> 11) & 0x0007;
      int evC  = (word16 >> 4) & 0x007f;
      TString appendVal = Form("H-%0d-%0d-%03d ",hs,chip,evC);
      returnVal.Append(appendVal);
    }
    else if (id==0) {
      int numHits = (word16 & 0x0fff);
      Bool_t errorBit = (word16 & 0x1000);
      Bool_t fastorBit = (word16 & 0x2000);
      TString appendVal = Form("T%0d-%0d-%04d ",fastorBit,errorBit,numHits);
      returnVal.Append(appendVal);
    }
    else {
      TString appendVal = "FFFFFFFFF ";
      returnVal.Append(appendVal);
    }
  }
  return returnVal;
}
