#include "TSystem.h"
#include "TCanvas.h"
#include "TH1F.h"

#include "HstFlags.hh"
#include "ShmObject.hh"

void HstFlagsTimers(const unsigned key, 
		   const unsigned bits=0x30,
		   const unsigned sleepMs=1000) {

  // Connect to shared memory  
  ShmObject<HstFlags> _shmHstFlags(key);
  HstFlags *_pShm(_shmHstFlags.payload());
  assert(_pShm!=0);

  gROOT->Reset();

  const UtlPack uBits(bits);
  
  // Canvas locations and sizes
  const unsigned dx(600),dy(750);
  unsigned cx(10),cy(10);
 
  // Canvas and histogram variables
  TCanvas *glbCanvas;
  TCanvas *tdcCanvas[RcdHeader::endOfRecordTypeEnum];

  std::string glbTitle;
  std::string tdcTitle[RcdHeader::endOfRecordTypeEnum];

  TH2F *glbHist2D;
  TH1F *tdcHist[RcdHeader::endOfRecordTypeEnum];
   
  std::string nums[RcdHeader::endOfRecordTypeEnum]={"00","01","02","03","04","05","06","07",
						    "08","09","10","11","12","13","14","15",
						    "16","17","18","19","20","21","22","23"};
  //			"24","25","26","27","28","29","30","31"};
  
  // Make the global canvas
  std::string glbLabel("HstFlagsTimersGlobal");
  glbCanvas=new TCanvas((glbLabel+"Canvas").c_str(),
                        glbLabel.c_str(),
                        cx,cy,(cx+=10)+dx,(cy+=10)+dy);
   
  // Set up global histogram titles
  glbTitle="Process time;Time (sec);Record type";

  glbHist2D=new TH2F((glbLabel+"Hist").c_str(),
		     (_pShm->title()+glbTitle).c_str(),
		     10000,0.0,10000.0,
		     RcdHeader::endOfRecordTypeEnum,
		     0.0,RcdHeader::endOfRecordTypeEnum);
   
  // Layout the canvas
  glbCanvas->cd(1);
  glbHist2D->Draw("box");


  for(unsigned t(0);t<RcdHeader::endOfRecordTypeEnum;t++) {
    if(uBits.bit(t)) {
     
      // Set up global per TDC canvases
      std::ostringstream sout;
      sout << "HstFlagsTimersType" << nums[t];
      std::string tdcLabel(sout.str());
       
      tdcCanvas[t]=new TCanvas((tdcLabel+"Canvas").c_str(),
                               tdcLabel.c_str(),
                               cx,cy,(cx+=10)+dx,(cy+=10)+dy);
       
      // Set up global per TDC histograms
      tdcTitle[t]=RcdHeader::recordTypeName((RcdHeader::RecordType)t)+" process time;Time (10 us units);Events";
      tdcHist[t]=_pShm->_timers[t].makeTH1F(tdcLabel+"Hist"+nums[t],
					    _pShm->title()+tdcTitle[t],10);
    
      // Layout the canvas
      tdcCanvas[t]->cd();
      tdcHist[t]->Draw();
    }
  }


  const unsigned sMs(5);
  HstFlags::Level refresh(HstFlags::event);
  //if(acqRefresh) refresh=HstFlags::acquisition;

  while(!gSystem->ProcessEvents()) { // && _pShm->_inJob) {

    //for(unsigned i(0);i<sleepMs && (_pShm->_inAcquisition || !_pShm->_validEvent);i+=sMs) {
    for(unsigned i(0);i<sleepMs && !_pShm->ready(refresh);i+=sMs) {
      std::cout << "NOT FINISHED" << std::endl;
      gSystem->Sleep(sMs);
    }

    //if(_pShm->ready(refresh)) {
    if(true) {

      // Global plots
 
      glbHist2D->SetTitle((_pShm->title()+glbTitle[3]).c_str());

      unsigned entries(0);
      for(unsigned i(0);i<RcdHeader::endOfRecordTypeEnum;i++) {
	for(unsigned j(0);j<_pShm->_timers[i].numberOfBins();j++) {
          glbHist2D->SetBinContent(j+1,i+1,_pShm->_timers[i].contents(j));
        }
	entries+=_pShm->_timers[i].entries();
      }

      glbHist2D->SetEntries(entries);


      for(unsigned t(0);t<RcdHeader::endOfRecordTypeEnum;t++) {
	if(uBits.bit(t)) {
	  tdcHist[t]->SetTitle((_pShm->title()+tdcTitle[t]).c_str());
	  _pShm->_timers[t].fillTH1F(tdcHist[t]);
	}	  
      }


      glbCanvas->Modified();

      for(unsigned t(0);t<RcdHeader::endOfRecordTypeEnum;t++) {
	if(uBits.bit(t)) {
	  tdcCanvas[t]->Modified();
	}
      }


      // Finally do all the updates
      glbCanvas->Update();

      for(unsigned t(0);t<RcdHeader::endOfRecordTypeEnum;t++) {
	if(uBits.bit(t)) {
	  tdcCanvas[t]->Update();
	}
      }
    }

    gSystem->Sleep(sleepMs);
  }
}
