#ifndef EmcConfiguration_HH
#define EmcConfiguration_HH

#include <iostream>
#include <fstream>

#include "RcdHeader.hh"
#include "RcdUserRW.hh"

#include "SubInserter.hh"
#include "SubAccessor.hh"

#include "CrcConfiguration.hh"
#include "CrcReadoutConfigurationData.hh"


class EmcConfiguration : public CrcConfiguration {

public:
  EmcConfiguration() : CrcConfiguration(0xec) {
    _readoutConfiguration.crateNumber(0xec);
  }

  virtual ~EmcConfiguration() {
  }

  virtual bool record(RcdRecord &r) {
    if(doPrint(r.recordType())) {
      std::cout << "EmcConfiguration::record()" << std::endl;
      r.RcdHeader::print(std::cout," ") << std::endl;
    }
    
    // Do underlying CRC configuration
    assert(CrcConfiguration::record(r));
    
    // Check record type
    switch (r.recordType()) {
      
      // Run start 
    case RcdHeader::runStart: {

      // Disable all CRCs except for trigger BE
      for(unsigned s(2);s<=21;s++) _readoutConfiguration.slotEnable(s,false);

      if(_trgLocation.slotNumber()>0)
	_readoutConfiguration.slotEnable(_trgLocation.slotNumber(),true);

      // Now selectively enable some
      std::ifstream fin("EmcFe.txt");
      if(fin) {
	unsigned s,f;
	fin >> s;
	while(fin) {
	  fin >> f;
	  if(f>0) {
	    _readoutConfiguration.slotEnable(s,true);
	    _readoutConfiguration.slotFeEnables(s,f);
	  }
	  fin >> s;
	}


      // ENABLE EVERYTHING IF CANNOT OPEN FILE
      } else {
	for(unsigned s(2);s<=21;s++) {
	  _readoutConfiguration.slotEnable(s,true);
	  _readoutConfiguration.slotFeEnables(s,0xff);
	}
      }

      if(doPrint(r.recordType(),1))
	_readoutConfiguration.print(std::cout," ") << std::endl;
      
      break;
    }
      
      
      // Configuration start 
    case RcdHeader::configurationStart: {
      
      // Handle the ones which need work (N.B. should never be running with SCECAL)
      if(_runType.majorType()==DaqRunType::emc ||
	 _runType.majorType()==DaqRunType::ahc || // KEEP ECAL TICKING OVER!!!
	 _runType.majorType()==DaqRunType::beam ||
	 _runType.majorType()==DaqRunType::cosmics) {

	emcReadoutConfiguration(r);
	//emcBeConfiguration(r);
	//emcBeTrgConfiguration(r);
	emcFeConfiguration(r);
      }
      
      break;
    }
      
    default: {
      break;
    }
    };
    
    return true;
  }

  virtual bool emcReadoutConfiguration(RcdRecord &r) {

    SubInserter inserter(r);
    CrcReadoutConfigurationData
      *b(inserter.insert<CrcReadoutConfigurationData>(true));
    *b=_readoutConfiguration;
    
    const unsigned char v(_runType.version());
    const UtlPack u(_runType.version());

    // Now do the readout periods, soft triggers and modes
    switch(_runType.type()) {

    case DaqRunType::emcTest: {
      b->beSoftTrigger(true);
      b->vlinkBlt(true);
      break;
    }
      
    case DaqRunType::emcNoise:
    case DaqRunType::emcFeParameters: {
      /* NOT SO USEFUL...
      if((v%4)==1) {
        b->beSoftTrigger(true);
      }
      if((v%4)==2) {
        b->feBroadcastSoftTrigger(true);
      }
      if((v%4)==3) {
        b->feSoftTrigger(0,true);
        b->feSoftTrigger(1,true);
        b->feSoftTrigger(2,true);
        b->feSoftTrigger(3,true);
        b->feSoftTrigger(4,true);
        b->feSoftTrigger(5,true);
        b->feSoftTrigger(6,true);
        b->feSoftTrigger(7,true);
      }

      b->vlinkBlt(((v/4)%2)==1);
      */

      b->vmePeriod(v/8);
      b->bePeriod(v/8);
      b->fePeriod(v/8);

      b->beSoftTrigger(true);
      b->vlinkBlt(true);
      break;
    }

    case DaqRunType::emcVfeDac:
    case DaqRunType::emcVfeDacScan:
    case DaqRunType::emcVfeHoldScan: {
      b->beSoftTrigger(true);
      b->vlinkBlt(true);
      break;
    }

    case DaqRunType::emcTrgTiming:
    case DaqRunType::emcTrgTimingScan: {
      b->vlinkBlt(true);
      break;
    }

    case DaqRunType::ahcCmNoise:
    case DaqRunType::ahcPmNoise: {
      b->beSoftTrigger(u.bit(0));
      b->vmePeriod(0);
      b->becPeriod(0);
      b->bePeriod(0);
      b->fePeriod(0);
      b->vlinkBlt(true);
      break;
    }

    case DaqRunType::ahcAnalogOut:
    case DaqRunType::ahcDacScan:
    case DaqRunType::ahcCmAsic:
    case DaqRunType::ahcCmAsicVcalibScan:
    case DaqRunType::ahcCmAsicHoldScan:
    case DaqRunType::ahcPmAsic:
    case DaqRunType::ahcPmAsicVcalibScan:
    case DaqRunType::ahcPmAsicHoldScan:
    case DaqRunType::ahcCmLed:
    case DaqRunType::ahcCmLedVcalibScan:
    case DaqRunType::ahcCmLedHoldScan:
    case DaqRunType::ahcPmLed:
    case DaqRunType::ahcPmLedVcalibScan:
    case DaqRunType::ahcPmLedHoldScan:
    case DaqRunType::ahcScintillatorHoldScan: {
      b->vmePeriod(0);
      b->becPeriod(0);
      b->bePeriod(0);
      b->fePeriod(0);
      b->vlinkBlt(true);
      break;
    }

    case DaqRunType::emcBeam:
    case DaqRunType::emcBeamHoldScan:
    case DaqRunType::emcCosmics:
    case DaqRunType::emcCosmicsHoldScan:

    case DaqRunType::beamTest:
    case DaqRunType::beamNoise:
    case DaqRunType::beamData:
    case DaqRunType::beamHoldScan:
    case DaqRunType::beamStage:
    case DaqRunType::beamStageScan:

    case DaqRunType::cosmicsTest:
    case DaqRunType::cosmicsNoise:
    case DaqRunType::cosmicsData:
    case DaqRunType::cosmicsHoldScan: {
      if((_configurationNumber%3)<2) {

        // Ped and calib configuration
#ifndef FNAL_SETTINGS
        b->vmePeriod(0);
        b->becPeriod(16);
        b->bePeriod(64);
        b->fePeriod(200);
#else
        b->vmePeriod(0);
        b->becPeriod(16);
        b->bePeriod(64);
        b->fePeriod(200);
#endif

      } else {
        // Beam configurations

#ifndef FNAL_SETTINGS
        b->vmePeriod(0);
        b->becPeriod(16);
        b->bePeriod(64);
        b->fePeriod(200);
#else
        b->vmePeriod(0);
        b->becPeriod(FNAL_PERIOD);
        b->bePeriod(10*FNAL_PERIOD);
        b->fePeriod(20*FNAL_PERIOD);
#endif
      }
      b->vlinkBlt(true);
      break;
    }
      
    default: {
      break;
    }
    };

    if(doPrint(r.recordType(),1)) b->print(std::cout," ") << std::endl;

    return true;
  }
  
  virtual bool emcBeConfiguration(RcdRecord &r) {

    // Define vector for configuration data
    std::vector< CrcLocationData<CrcBeConfigurationData> > vBcd;

    _location.slotBroadcast(true);
    _location.crcComponent(CrcLocation::be);
    vBcd.push_back(CrcLocationData<CrcBeConfigurationData>(_location));

    //const unsigned char v(_runType.version());

    switch(_runType.type()) {

    case DaqRunType::emcTest: {
      vBcd[0].data()->j0TriggerEnable(false);
      vBcd[0].data()->j0BypassEnable(false);
      break;
    }
      
    case DaqRunType::emcNoise:
    case DaqRunType::emcFeParameters: {
      //vBcd[0].data()->j0TriggerEnable((v%4)==0);
      vBcd[0].data()->j0TriggerEnable(false);
      vBcd[0].data()->j0BypassEnable(false);
      break;
    }
      
    case DaqRunType::emcVfeDac:
    case DaqRunType::emcVfeDacScan:
    case DaqRunType::emcVfeHoldScan: {
      vBcd[0].data()->j0TriggerEnable(false);
      vBcd[0].data()->j0BypassEnable(false);
      break;
    }
      
    case DaqRunType::emcTrgTiming:
    case DaqRunType::emcTrgTimingScan: {
      vBcd[0].data()->j0TriggerEnable(true);
      vBcd[0].data()->j0BypassEnable(false);
      break;
    }
      
    case DaqRunType::emcBeam:
    case DaqRunType::emcBeamHoldScan:
    case DaqRunType::emcCosmics:
    case DaqRunType::emcCosmicsHoldScan:

    case DaqRunType::beamTest:
    case DaqRunType::beamNoise:
    case DaqRunType::beamData:
    case DaqRunType::beamHoldScan:
    case DaqRunType::beamStage:
    case DaqRunType::beamStageScan:

    case DaqRunType::cosmicsTest:
    case DaqRunType::cosmicsNoise:
    case DaqRunType::cosmicsData:
    case DaqRunType::cosmicsHoldScan: {
      //vBcd[0].data()->j0TriggerEnable((_configurationNumber%3)==2);
      vBcd[0].data()->j0TriggerEnable(true);
      vBcd[0].data()->j0BypassEnable(false);
      break;
    }

    default: {
      vBcd[0].data()->j0TriggerEnable(true);
      vBcd[0].data()->j0BypassEnable(false);
      break;
    }
    };

    // Load configuration into record
    SubInserter inserter(r);
    
    if(doPrint(r.recordType(),1)) std::cout
      << " Number of CrcBeConfigurationData subrecords inserted = "
      << vBcd.size() << std::endl << std::endl;
    
    for(unsigned i(0);i<vBcd.size();i++) {
      if(doPrint(r.recordType(),1)) vBcd[i].print(std::cout,"  ") << std::endl;
      inserter.insert< CrcLocationData<CrcBeConfigurationData> >(vBcd[i]);
    }
    
    return true;
  }
  
  virtual bool emcBeTrgConfiguration(RcdRecord &r) {

    // Set location
    _location.crcComponent(CrcLocation::beTrg);
 
    // Define vectors for configuration data
    std::vector<TrgReadoutConfigurationData> vTrd;
    std::vector< CrcLocationData<CrcBeTrgConfigurationData> > vTcd;

    // Turn trigger off for all CRCs
    if(_configurationNumber==0) {
      _location.slotBroadcast(true);
      vTcd.push_back(CrcLocationData<CrcBeTrgConfigurationData>(_location));
      vTcd[0].data()->inputEnable(0);
      vTcd[0].data()->generalEnable(0);
    }

    // Override if trigger slot is in this crate
    if(_trgLocation.slotNumber()>0) {
      vTrd.push_back(TrgReadoutConfigurationData());

      const unsigned char v(_runType.version());
      const UtlPack vBits(_runType.version());

      switch(_runType.type()) {

      case DaqRunType::emcTest: {
	vTrd[0].enable(false);
	break;
      }
      
      case DaqRunType::emcNoise:
      case DaqRunType::emcFeParameters: {
	/* 
	vTrd[0].beTrgSquirt(true);
	vTrd[0].readPeriod(v/8);

	if((v%4)==0) {
	  unsigned t(vTcd.size());
	  vTcd.push_back(CrcLocationData<CrcBeTrgConfigurationData>(_trgLocation));
	  vTcd[t].data()->inputEnable(0);
	  vTcd[t].data()->generalEnable(1);

	  vTrd[0].clearBeTrgTrigger(true);
	  vTrd[0].beTrgSoftTrigger(true);
	}
	*/
	vTrd[0].enable(false);
	break;
      }
      
      case DaqRunType::emcVfeDac:
      case DaqRunType::emcVfeDacScan:
      case DaqRunType::emcVfeHoldScan: {
	vTrd[0].enable(false);
	break;
      }
      
      case DaqRunType::emcTrgTiming: {
	vTrd[0].clearBeTrgTrigger(true);
	vTrd[0].beTrgSquirt(true);
	  
	unsigned t(vTcd.size());
	vTcd.push_back(CrcLocationData<CrcBeTrgConfigurationData>(_trgLocation));
	vTcd[t].data()->generalEnable(1);
	vTcd[t].data()->oscillatorEnable(true);

	// Lower bits of version give period as power of 2 in 25ns units
	// v=0 is 40MHz, v=1 is 20MHz, ... v=31 is 0.02Hz
	unsigned pwr(vBits.bits(0,4));
	vTcd[t].data()->oscillationPeriod(1<<pwr);
	
	break;
      }
      
      case DaqRunType::emcTrgTimingScan: {
	vTrd[0].clearBeTrgTrigger(true);
	vTrd[0].beTrgSquirt(true);
	  
	unsigned t(vTcd.size());
	vTcd.push_back(CrcLocationData<CrcBeTrgConfigurationData>(_trgLocation));
	vTcd[t].data()->generalEnable(1);
	vTcd[t].data()->oscillatorEnable(true);

	unsigned pwr((_configurationNumber/2)%32);
	vTcd[t].data()->oscillationPeriod(1<<pwr);
	
	break;
      }
      
      case DaqRunType::emcBeam:
      case DaqRunType::emcBeamHoldScan:
      case DaqRunType::emcCosmics:
      case DaqRunType::emcCosmicsHoldScan:

      case DaqRunType::beamTest:
      case DaqRunType::beamNoise:
      case DaqRunType::beamData:
      case DaqRunType::beamHoldScan:
      case DaqRunType::beamStage:
      case DaqRunType::beamStageScan:
	
      case DaqRunType::cosmicsTest:
      case DaqRunType::cosmicsNoise:
      case DaqRunType::cosmicsData:
      case DaqRunType::cosmicsHoldScan: {
	if((_configurationNumber%3)!=2) {
	  vTrd[0].enable(false);
	} else {
	  vTrd[0].clearBeTrgTrigger(true);
	  //vTrd[0].beTrgSquirt(true);
	  vTrd[0].beTrgSquirt(false); //TEMP!
	  vTrd[0].readPeriod(16);
	  vTrd[0].readcPeriod(16);
	  vTrd[0].readPeriod(1); // TEMP!
	  vTrd[0].readcPeriod(1);// TEMP!
	  
	  unsigned t(vTcd.size());
	  vTcd.push_back(CrcLocationData<CrcBeTrgConfigurationData>(_trgLocation));
	  vTcd[t].data()->generalEnable(1);

	  if(v<16) { // Normal cosmic trigger
	    vTcd[t].data()->inputEnable(1<<v);
	    //vTcd[t].data()->inputEnable(0x100ffff);
	    //vTcd[t].data()->inputEnable(0x3001000);
	    //vTcd[t].data()->andEnable(0,0x0100);
	    
	  } else if(v==254) { // Soft trigger
	    vTrd[0].beTrgSoftTrigger(true);
	    vTcd[t].data()->inputEnable(0);
	  } else if(v==255) { // Oscillator
	    vTcd[t].data()->oscillatorEnable(true);
	    vTcd[t].data()->oscillationPeriod(40000); // 1kHz
	    //vTcd[t].data()->oscillationPeriod(40000000); // 1Hz TEMP
	  }
	}
	break;
      }
	
      default: {
	break;
      }
      };
    }

    // Load configuration into record
    SubInserter inserter(r);

    if(doPrint(r.recordType(),1)) std::cout
      << " Number of TrgReadoutConfigurationData subrecords inserted = "
      << vTrd.size() << std::endl << std::endl;
    assert(vTrd.size()<=1);

    for(unsigned i(0);i<vTrd.size();i++) {
      if(doPrint(r.recordType(),1)) vTrd[i].print(std::cout,"  ") << std::endl;
      inserter.insert<TrgReadoutConfigurationData>(vTrd[i]);
    }

    if(doPrint(r.recordType(),1)) std::cout
      << " Number of CrcBeTrgConfigurationData subrecords inserted = "
      << vTcd.size() << std::endl << std::endl;
    assert(vTcd.size()<=2);

    for(unsigned i(0);i<vTcd.size();i++) {
      if(doPrint(r.recordType(),1)) vTcd[i].print(std::cout,"  ") << std::endl;
      inserter.insert< CrcLocationData<CrcBeTrgConfigurationData> >(vTcd[i]);
    }

    return true;
  }
  
  
  virtual bool emcFeConfiguration(RcdRecord &r) {

    // Define vector for configuration data
    std::vector< CrcLocationData<CrcFeConfigurationData> > vFcd;

    _location.slotBroadcast(true);
    _location.crcComponent(CrcLocation::feBroadcast);
    vFcd.push_back(CrcLocationData<CrcFeConfigurationData>(_location));

    // Always do 19 reads to avoid wandering VFE baseline
    // Julien: No it should be 18 = default
    //vFcd[0].data()->vfeMplexClockPulses(19);

    // Always set low gain by default
    EmcVfeControl c;
    c.vfeLowGain(CrcFeConfigurationData::bot,true);
    c.vfeLowGain(CrcFeConfigurationData::top,true);
    vFcd[0].data()->vfeControl(c.data());

    const unsigned char v(_runType.version());
    const UtlPack vBits(_runType.version());

    switch(_runType.type()) {

      case DaqRunType::emcTest: {
	vFcd[0].data()->sequenceDelay(4*v);
	vFcd[0].data()->vfeResetStart(1);
	vFcd[0].data()->vfeResetEnd(100);
	break;
      }
      
      case DaqRunType::emcNoise: {
	c.vfeLowGain(CrcFeConfigurationData::bot,!vBits.bit(0));
	c.vfeLowGain(CrcFeConfigurationData::top,!vBits.bit(1));
	vFcd[0].data()->vfeControl(c.data());
	break;
      }
      
      case DaqRunType::emcFeParameters: {
	// NOT YET IMPLEMENTED
	break;
      }
      
      case DaqRunType::emcVfeDac: {
      vFcd[0].data()->calibEnable(true);
 
     // Top two bit set side and next three bits set calibration group
      unsigned g(vBits.bits(3,5));
      if(g<6) {
	if(!vBits.bit(6)) c.vfeEnable(CrcFeConfigurationData::bot,g,true);
	if(!vBits.bit(7)) c.vfeEnable(CrcFeConfigurationData::top,g,true);
      }
      vFcd[0].data()->vfeControl(c.data());

      // Bottom three bits set DAC value
      vFcd[0].data()->dacData(CrcFeConfigurationData::bot,8192*(v&0x7));
      vFcd[0].data()->dacData(CrcFeConfigurationData::top,8192*(v&0x7));

      // HOLD value set to something reasonable
      vFcd[0].data()->sequenceDelay(30);
      //vFcd[0].data()->calibWidth(0); // TEMP FOR TCMT TCALIB TESTS 0==6.25ns 03/08/06
      break;
    }

    case DaqRunType::emcVfeDacScan: {
      if(_configurationNumber==0 ||
	 _configurationNumber==(unsigned)(6*(v+1)+3)) {
	vFcd[0].data()->calibEnable(false);

      } else if(_configurationNumber==1 ||
		_configurationNumber==(unsigned)(6*(v+1)+2)) {
	vFcd[0].data()->calibEnable(true);
	vFcd[0].data()->sequenceDelay(30);

      } else {
	vFcd[0].data()->calibEnable(true);
	vFcd[0].data()->sequenceDelay(30);

	unsigned group((_configurationNumber-2)%6);
	unsigned step((_configurationNumber-2)/6);

	c.vfeEnable(CrcFeConfigurationData::bot,group,true);
	c.vfeEnable(CrcFeConfigurationData::top,group,true);
	vFcd[0].data()->vfeControl(c.data());

	unsigned steps(v+1);
	vFcd[0].data()->dacData(CrcFeConfigurationData::bot,65536*step/steps);
	vFcd[0].data()->dacData(CrcFeConfigurationData::top,65536*step/steps);
      }
      break;
    }

    case DaqRunType::emcVfeHoldScan: {
      if(_configurationNumber==0 ||
	 _configurationNumber==(unsigned)(6*(v+1)+3)) {
	vFcd[0].data()->calibEnable(false);

      } else if(_configurationNumber==1 ||
		_configurationNumber==(unsigned)(6*(v+1)+2)) {
	vFcd[0].data()->calibEnable(true);
	vFcd[0].data()->sequenceDelay(30);

      } else {
	vFcd[0].data()->calibEnable(true);
	vFcd[0].data()->dacData(CrcFeConfigurationData::bot,16*1024);
	vFcd[0].data()->dacData(CrcFeConfigurationData::top,16*1024);

	unsigned group((_configurationNumber-2)%6);
	unsigned step((_configurationNumber-2)/6);

	c.vfeEnable(CrcFeConfigurationData::bot,group,true);
	c.vfeEnable(CrcFeConfigurationData::top,group,true);
	vFcd[0].data()->vfeControl(c.data());

	unsigned steps(v+1);
	vFcd[0].data()->sequenceDelay(256*step/steps);
      }
      break;
    }

    case DaqRunType::emcTrgTiming: {
      if(vBits.bit(7)) vFcd[0].data()->vfeMplexClockPulses(18);
      break;
    }

    case DaqRunType::emcTrgTimingScan: {
	vFcd[0].data()->sequenceDelay(8);
	vFcd[0].data()->vfeResetStart(1);
	vFcd[0].data()->vfeResetEnd(100);
      if((_configurationNumber%2)==1) vFcd[0].data()->vfeMplexClockPulses(18);
      break;
    }

    case DaqRunType::ahcCmNoise:
    case DaqRunType::ahcPmNoise:
    case DaqRunType::ahcAnalogOut:
    case DaqRunType::ahcDacScan:
    case DaqRunType::ahcCmAsic:
    case DaqRunType::ahcCmAsicVcalibScan:
    case DaqRunType::ahcCmAsicHoldScan:
    case DaqRunType::ahcPmAsic:
    case DaqRunType::ahcPmAsicVcalibScan:
    case DaqRunType::ahcPmAsicHoldScan:
    case DaqRunType::ahcCmLed:
    case DaqRunType::ahcCmLedVcalibScan:
    case DaqRunType::ahcCmLedHoldScan:
    case DaqRunType::ahcPmLed:
    case DaqRunType::ahcPmLedVcalibScan:
    case DaqRunType::ahcPmLedHoldScan:
    case DaqRunType::ahcScintillatorHoldScan: {
	// Just use default
      break;
    }

    case DaqRunType::emcBeam:
      //case DaqRunType::emcBeamHoldScan:
    case DaqRunType::emcCosmics:
      //case DaqRunType::emcCosmicsHoldScan:
      
    case DaqRunType::beamTest:
    case DaqRunType::beamNoise:
    case DaqRunType::beamData:
      //case DaqRunType::beamHoldScan:
    case DaqRunType::beamStage:
    case DaqRunType::beamStageScan:
      
    case DaqRunType::cosmicsTest:
    case DaqRunType::cosmicsNoise:
    case DaqRunType::cosmicsData: {
      //case DaqRunType::cosmicsHoldScan: {
      if((_configurationNumber%3)==1) {

	// Turn on calibration enable (Tcalib) pulse
	vFcd[0].data()->calibEnable(true);

	// Select which group (or 7 = no group) to calibrate
	unsigned group((_configurationNumber/3)%7);
	if(group<6) {
	  c.vfeEnable(CrcFeConfigurationData::bot,group,true);
	  c.vfeEnable(CrcFeConfigurationData::top,group,true);
	}

	vFcd[0].data()->vfeControl(c.data());

	vFcd[0].data()->sequenceDelay(30);
	vFcd[0].data()->dacData(CrcFeConfigurationData::bot,16*1024);
	vFcd[0].data()->dacData(CrcFeConfigurationData::top,16*1024);

      } else {
	//std::cout << "here: " << std::endl;
	//vFcd[0].data()->sequenceDelay(15); //Test by RP 05.07.07 
	//vFcd[0].data()->sequenceDelay(5); // 07.04.06 new hold value from Goetz
	//vFcd[0].data()->sequenceDelay(3); // 22.05.06 new hold value=4 from Goetz
	//vFcd[0].data()->sequenceDelay(1); // 11.08.06 new hold value=2 from Goetz during trigger 100x100
	//vFcd[0].data()->sequenceDelay(13); //  07.07.07 new home for tirgger 10x10 (extracted from HCAL) Erika
	//vFcd[0].data()->sequenceDelay(10); //  24.07.07 new home for tirgger 20x20 (10x10 trigger -3 ticks) Erika

	// Use version number to switch hold values PDD 14/08/07
	/*
	vFcd[0].data()->sequenceDelay(13); // 10x10 default 2007
	if(v==10) vFcd[0].data()->sequenceDelay(10); // 20x20 2007
	if(v==23) vFcd[0].data()->sequenceDelay(1);  // 100x100 2007
	*/
	// update for 2008 FNAL data taking
#ifdef SLOW_TRIGGER
	vFcd[0].data()->sequenceDelay(0);  // (for ECAL 0 = 1 tick!!) default with cherenkov 2008
#else
	vFcd[0].data()->sequenceDelay(6); // 10x10 default 2008
#endif
	if (v==1) vFcd[0].data()->sequenceDelay(6); // 20x20 2008
	//if (v==26)  vFcd[0].data()->sequenceDelay(0); // (for ECAL 0 = 1 tick) 100x100 2008 (calculated value would be -2)
        //CRP 16/5/08 Hold value for muon running to trigger the r/o st the same point on signal curve as
        //for slow trigger running mode at FNAL
        if (v==26)  vFcd[0].data()->sequenceDelay(2); // (for ECAL 0 = 1 tick) 100x100 2008 (calculated value would be -2)

	//	if(v==23) vFcd[0].data()->sequenceDelay(6);  // 10x10 FAST 2008
	

      }

      break;
    }


    case DaqRunType::emcBeamHoldScan:
    case DaqRunType::emcCosmicsHoldScan:
    case DaqRunType::beamHoldScan:
    case DaqRunType::cosmicsHoldScan: {
      if((_configurationNumber%3)==1) {

	// Turn on calibration enable (Tcalib) pulse
	vFcd[0].data()->calibEnable(true);

	// Select which group (or 7 = no group) to calibrate
	unsigned group((_configurationNumber/3)%7);
	if(group<6) {
	  c.vfeEnable(CrcFeConfigurationData::bot,group,true);
	  c.vfeEnable(CrcFeConfigurationData::top,group,true);
	}

	vFcd[0].data()->vfeControl(c.data());

	vFcd[0].data()->sequenceDelay(30);
	vFcd[0].data()->dacData(CrcFeConfigurationData::bot,16*1024);
	vFcd[0].data()->dacData(CrcFeConfigurationData::top,16*1024);

      } else if((_configurationNumber%3)==2) {
	//	unsigned short hold[16]={0,1,2,3,4,5,6,8,10,15,20,30,40,50,100,150};
	unsigned short hold[16]={1,2,3,4,5,6,7,8,9,10,11,12,15,25,30,50};
	unsigned step(_configurationNumber/3);
	vFcd[0].data()->sequenceDelay(hold[step%16]);

	/*
	unsigned step(_configurationNumber/6);
	unsigned fe((_configurationNumber/3)%2);

	unsigned holdEnd(vFcd[0].data()->holdEnd());

	// Hardwired for Feb06 cabling!!!
	for(unsigned s(0);s<3;s++) {
	  unsigned slot(7);
	  if(s==1) slot=15;
	  if(s==2) slot=19;

	  for(unsigned f(0);f<8;f++) {
	    if(s!=0 || f>0) {
	      vFcd.push_back(CrcLocationData<CrcFeConfigurationData>(_location));
	      // Julien: No it should be 18 = default
	      //vFcd[8*s+f].data()->vfeMplexClockPulses(19);
	      vFcd[8*s+f].data()->vfeControl(c.data());
	    }
	    vFcd[8*s+f].slotNumber(slot);
	    vFcd[8*s+f].crcComponent((CrcLocation::CrcComponent)f);
	    
	    // Decide which FEs to move the HOLD for	  
	    if((fe==0 &&
		((slot== 7 && f==3) || (slot==19 && f==5) || (slot== 7 && f==4) || (slot== 7 && f==1) ||
		 (slot== 7 && f==2) || (slot==15 && f==6) || (slot==19 && f==2) || (slot==19 && f==7))) ||
	       (fe==1 &&
		((slot==15 && f==4) || (slot==19 && f==1) || (slot==19 && f==6) || (slot==15 && f==2) ||
		 (slot== 7 && f==0) || (slot==15 && f==1) || (slot==19 && f==4) || (slot==15 && f==7)))) {
	      vFcd[8*s+f].data()->sequenceDelay(hold[step%16]-1);
	      vFcd[8*s+f].data()->holdEnd(holdEnd);
	    } else {
	      vFcd[8*s+f].data()->sequenceDelay(8);
	      vFcd[8*s+f].data()->holdEnd(holdEnd);
	    }
	  }
	}
	*/

      } else {
	//vFcd[0].data()->sequenceDelay(8);
	vFcd[0].data()->sequenceDelay(3); // 22.05.06 new hold value=4 from Goetz
      }

      break;
    }

    default: {
      break;
    }
    };

    // Load configuration into record
    SubInserter inserter(r);
    
    if(doPrint(r.recordType(),1)) std::cout
      << " Number of CrcFeConfigurationData subrecords inserted = "
      << vFcd.size() << std::endl << std::endl;
    
    for(unsigned i(0);i<vFcd.size();i++) {
      if(doPrint(r.recordType(),2)) vFcd[i].print(std::cout,"  ") << std::endl;
      inserter.insert< CrcLocationData<CrcFeConfigurationData> >(vFcd[i]);
    }

    return true;
  }


protected:
  CrcReadoutConfigurationData _readoutConfiguration;
};

#endif
