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

#include "HstLalHodoscopeStore.hh"
#include "ShmObject.hh"

void HstLalHodoscope(const unsigned bits=0xf, const unsigned sleepMs=1000) {

  // Connect to shared memory  
  ShmObject<HstLalHodoscopeStore>
    _shmHstLalHodoscopeStore(HstLalHodoscopeStore::shmKey);
  HstLalHodoscopeStore *_pShm(_shmHstLalHodoscopeStore.payload());
  assert(_pShm!=0);
  
  // Create the global canvas always
  gROOT->Reset();
  
  const UtlPack uBits(bits);
  
  TCanvas *cvsChannel[3];
  std::string hCanvas[3];
  std::string hTitle[3];
  
  for(unsigned i(0);i<3;i++) {
    if(uBits.bit(i)) {
      std::ostringstream scan;
      scan << "HstLalHodoscope" << i;
      hCanvas[i]=scan.str();
      
      cvsChannel[i]=new TCanvas((hCanvas[i]+"Canvas").c_str(),
				hCanvas[i].c_str(),
				10+10*i,10+10*i,610+10*i,760+10*i);
      if(i==0) {
	cvsChannel[i]->Divide(1,2);
      } else {
	cvsChannel[i]->Divide(1,3);
      }
      
      if(i==0) hTitle[i]="HstLalHodoscope Digital ";
      if(i==1) hTitle[i]="HstLalHodoscope Analogue x ";
      if(i==2) hTitle[i]="HstLalHodoscope Analogue y ";
    }
  }
  
  
  TH1F *hstLalHodoscope[8];
  if(uBits.bit(0)) {
    hstLalHodoscope[0]=new TH1F((hTitle[0]+"x").c_str(),"Initialising...",
				128,0,128);
    hstLalHodoscope[1]=new TH1F((hTitle[0]+"y").c_str(),"Initialising...",
				128,0,128);
    
    cvsChannel[0]->cd(1);
    hstLalHodoscope[0]->Draw();
    cvsChannel[0]->cd(2);
    hstLalHodoscope[1]->Draw();
  }
  
  if(uBits.bit(1)) {
    hstLalHodoscope[2]=new TH1F((hTitle[1]+"Number").c_str(),"Initialising...",
				128,0,128);
    hstLalHodoscope[3]=new TH1F((hTitle[1]+"Mean").c_str(),"Initialising...",
				128,0,128);
    hstLalHodoscope[4]=new TH1F((hTitle[1]+"RMS").c_str(),"Initialising...",
				128,0,128);
    
    cvsChannel[1]->cd(1);
    hstLalHodoscope[2]->Draw();
    cvsChannel[1]->cd(2);
    hstLalHodoscope[3]->Draw();
    cvsChannel[1]->cd(3);
    hstLalHodoscope[4]->Draw();
  }

  if(uBits.bit(2)) {
    hstLalHodoscope[5]=new TH1F((hTitle[2]+"Number").c_str(),"Initialising...",
				128,0,128);
    hstLalHodoscope[6]=new TH1F((hTitle[2]+"Mean").c_str(),"Initialising...",
				128,0,128);
    hstLalHodoscope[7]=new TH1F((hTitle[2]+"RMS").c_str(),"Initialising...",
				128,0,128);
    
    cvsChannel[2]->cd(1);
    hstLalHodoscope[5]->Draw();
    cvsChannel[2]->cd(2);
    hstLalHodoscope[6]->Draw();
    cvsChannel[2]->cd(3);
    hstLalHodoscope[7]->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(uBits.bit(0)) {
	hstLalHodoscope[0]->SetTitle((_pShm->title()+hTitle[0]+"x").c_str());
	hstLalHodoscope[1]->SetTitle((_pShm->title()+hTitle[0]+"y").c_str());
	
	_pShm->_digitalHits[0].fillTH1F(hstLalHodoscope[0]);
	_pShm->_digitalHits[1].fillTH1F(hstLalHodoscope[1]);
      }

      if(uBits.bit(1)) {
	hstLalHodoscope[2]->SetTitle((_pShm->title()+hTitle[1]+"Number").c_str());
	hstLalHodoscope[3]->SetTitle((_pShm->title()+hTitle[1]+"Mean").c_str());
	hstLalHodoscope[4]->SetTitle((_pShm->title()+hTitle[1]+"RMS").c_str());

	for(unsigned i(0);i<128;i++) {
	  hstLalHodoscope[2]->SetBinContent(i+1,_pShm->_analogueHits[0][i].number());
	  hstLalHodoscope[3]->SetBinContent(i+1,_pShm->_analogueHits[0][i].average());
	  hstLalHodoscope[4]->SetBinContent(i+1,_pShm->_analogueHits[0][i].sigma());
        }
      }

      if(uBits.bit(2)) {
	hstLalHodoscope[5]->SetTitle((_pShm->title()+hTitle[2]+"Number").c_str());
	hstLalHodoscope[6]->SetTitle((_pShm->title()+hTitle[2]+"Mean").c_str());
	hstLalHodoscope[7]->SetTitle((_pShm->title()+hTitle[2]+"RMS").c_str());

	for(unsigned i(0);i<128;i++) {
	  hstLalHodoscope[5]->SetBinContent(i+1,_pShm->_analogueHits[1][i].number());
	  hstLalHodoscope[6]->SetBinContent(i+1,_pShm->_analogueHits[1][i].average());
	  hstLalHodoscope[7]->SetBinContent(i+1,_pShm->_analogueHits[1][i].sigma());
        }
      }

      for(unsigned i(0);i<3;i++) {
	if(uBits.bit(i)) {
	  cvsChannel[i]->cd(1);
	  gPad->Modified();
	  cvsChannel[i]->cd(2);
	  gPad->Modified();
	  if(i>0) {
	    cvsChannel[i]->cd(3);
	    gPad->Modified();
	  }    
	}
      }
      
      for(unsigned i(0);i<3;i++) {
	if(uBits.bit(i)) {
	  cvsChannel[i]->Update();
	}    
      }    
    }
    
    gSystem->Sleep(sleepMs);
  }
}
