#ifndef MpsAnalysisTrimScan_HH
#define MpsAnalysisTrimScan_HH

#include <cassert>

#include "RcdUserRO.hh"
#include "SubAccessor.hh"

#include "HstCfgScan.hh"
#include "MpsSensor1BunchTrainData.hh"


class MpsAnalysisTrimScan : public MpsAnalysisBase {

public:
  MpsAnalysisTrimScan() : MpsAnalysisBase("MpsAnalysisTrimScan") {
    for(unsigned i(0);i<4;i++) {
      std::ostringstream sLabel[2];
      sLabel[0] << "Region" << i << "Lin";
      sLabel[1] << "Region" << i << "Log";
      
      std::ostringstream sTitle[2];
      sTitle[0] << "Region " << i << ", Number of words";
      sTitle[1] << "Region " << i << ", Log10(number of words)";

      _regionWords[i]=new HstCfgScan(sLabel[0].str().c_str(),
				     sTitle[0].str().c_str(),
				     3200,0.0,3200.0);

      _regionLogWs[i]=new HstCfgScan(sLabel[1].str().c_str(),
				     sTitle[1].str().c_str(),
				     1000,0.0,4.0);
    }
  }

  virtual ~MpsAnalysisTrimScan() {
    if(_rootFile!=0) {
      _rootFile->cd();
      endRun();
    }
  }

  virtual bool mpsAnalysisValidRun(IlcRunType::Type t) const {
    return t==IlcRunType::mpsTrimScan;
  }

  bool runStart(const RcdRecord &r) {
    for(unsigned i(0);i<4;i++) {
      _regionWords[i]->runStart(_runStart.runNumber());
      _regionLogWs[i]->runStart(_runStart.runNumber());
    }

    for(unsigned x(0);x<168;x++) {
      for(unsigned y(0);y<168;y++) {
	for(unsigned t(0);t<16;t++) {
	  _count[x][y][t]=0;
	}
      }
    }
    return true;
  }

  bool runEnd(const RcdRecord &r) {
    endRun();
    return true;
  }

  bool configurationStart(const RcdRecord &r) {
    for(unsigned i(0);i<4;i++) {
      _regionWords[i]->configurationStart();
      _regionLogWs[i]->configurationStart();
    }
    return true;
  }
  
  bool bunchTrain(const RcdRecord &r) {
    SubAccessor accessor(r);

    std::vector<const MpsLocationData<MpsSensor1BunchTrainData>* >
      w(accessor.access< MpsLocationData<MpsSensor1BunchTrainData> >());
    assert(w.size()==1);
    if(doPrint(r.recordType(),1)) w[0]->print(std::cout) << std::endl;

    for(unsigned i(0);i<4;i++) {
      _regionWords[i]->Fill(w[0]->data()->numberOfRegionHits(i));
      if(w[0]->data()->numberOfRegionHits(i)>0) {
	_regionLogWs[i]->Fill(std::log10((double)w[0]->data()->numberOfRegionHits(i)));
      }
    }

    for(unsigned region(0);region<4;region++) {
      const MpsSensor1BunchTrainDatum *p(w[0]->data()->regionData(region));
      for(unsigned j(0);j<w[0]->data()->numberOfRegionHits(region);j++) {
	if(p[j].row()<168 && p[j].group()<7) {
	  for(unsigned c(0);c<6;c++) {
	    if(p[j].channel(c)) {
	      //if((6*p[j].group()+c)!=(_configurationStart.configurationNumberInRun()/16)) std::cout << "ERROR" << std::endl;

	      _count[42*region+6*p[j].group()+c][p[j].row()][_configurationStart.configurationNumberInRun()%16]++;
	    }
	  }
	}
      }
    }

    return true;
  }

  void endRun() {
    for(unsigned i(0);i<4;i++) {
      _regionWords[i]->runEnd();
      _regionLogWs[i]->runEnd();
    }

    for(unsigned i(0);i<4;i++) {
      std::ostringstream slab;
      slab << "hTrimRegion" << i;
      std::ostringstream stit;
      stit << "Region " << i << ", Trim values";
      
      _hTrim[i]=new TH1F(slab.str().c_str(),stit.str().c_str(),16,0.0,16.0);
    }

    MpsSensor1ConfigurationData d;
    d.maskSensor(false);
    for(unsigned i(0);i<168;i++) {
      for(unsigned j(0);j<5;j++) {
	unsigned k(5*i+j);
	unsigned kb(~k);
	d.stripCheckBits(k,((kb&0xfff)<<12)+(k&0xfff));
      }
    }

    for(unsigned x(0);x<168;x++) {
      unsigned cut(100);
      if(x>83) cut=1000;

      for(unsigned y(0);y<168;y++) {
	if(x==0) std::cout << std::setw(3) << y;

	unsigned trim(15);
	for(unsigned t(0);t<16;t++) {
	  if(x==0) std::cout << std::setw(6) << _count[x][y][t];
	  
	  if(t==0) {
	    if(_count[x][y][0]>=cut) trim=0;
	  } else {
	    if(_count[x][y][t-1]<cut && _count[x][y][t]>=cut) trim=t;
	  }
	}
	if(x==0) std::cout << " cut = " << cut << ", trim = " << trim << std::endl;
	_hTrim[x/42]->Fill(trim);
	d.trim(x,y,trim);
      }
    }
    d.writeFile("TrimScan.txt");

    endRoot();
  }

private:
  HstCfgScan *_regionWords[4];
  HstCfgScan *_regionLogWs[4];
  TH1F *_hTrim[4];

  unsigned _count[168][168][16];
};

#endif
