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

//added by MS 06/12/2007
#include "TStyle.h"

#include "HstMpsBunchTrainStore.hh"
#include "ShmObject.hh"

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

  // Connect to shared memory  
  ShmObject<HstMpsBunchTrainStore>
    _shmHstMpsBunchTrainStore(HstMpsBunchTrainStore::shmKey);
  HstMpsBunchTrainStore *_pShm(_shmHstMpsBunchTrainStore.payload());
  assert(_pShm!=0);

  // Reset ROOT
  gROOT->Reset();

  // Added by MS 06/12/2007
  // Will make palettes more pretty
  gStyle->SetNdivisions(99);
  gStyle->SetPalette(1);

  // Allow access of argument as bits
  const UtlPack uBits(bits);
  
  // Canvas locations and sizes
  const unsigned dx(610),dy(610);
  unsigned cx(10),cy(10);

  // Strings to label histograms 
  std::string tags[4];
  tags[0]="Job";
  tags[1]="Run";
  tags[2]="Cfg";
  tags[3]="Bnt";

  // Seting for sensor id
  if(sens>3) return;
  std::ostringstream sid;
  sid << "Sensor " << _pShm->_sensorId[sens];

  // Set up the canvasses
  TCanvas *hstCanvas[4];
  std::string strCanvas[4];

  for(unsigned i(0);i<4;i++) {
    if(uBits.bit(i)) {
      strCanvas[i]=std::string("HstMpsBunchTrain")+tags[i];
      hstCanvas[i]=new TCanvas((strCanvas[i]+"Canvas").c_str(),
                               strCanvas[i].c_str(),
                               cx,cy,(cx+=10)+dx,(cy+=10)+dy);
   } else {
      hstCanvas[i]=0;
    }
  }

  // Define the histograms
  TH2F *hstRecord[4];
  std::string hstTitle[4];
  std::string hLabel[4];

  for(unsigned i(0);i<4;i++) {
    if(uBits.bit(i)) {
      hstTitle[i]=sid.str()+", "+tags[i]+" bunch train hits";
      hLabel[i]=tags[i]+"BunchTrain";
      hstRecord[i]=_pShm->_sensor[sens][i].makeTH2F(hLabel[i].c_str(),"Initialising...");
    }
  }
  bool palette_init=false;
  for(unsigned i(0);i<4;i++) {
    if(uBits.bit(i) && hstCanvas[i]!=0) {
        hstCanvas[i]->cd();
	if(uBits.bit(4)) hstRecord[i]->Draw("lego");
	else             
	{
		hstRecord[i]->Draw("colz");
		if (!palette_init)
		{
			gStyle->SetPalette(1);
                	gStyle->SetNumberContours(99);
			palette_init=true;
		}	
		
		
	}	
    }
  }

/*
  // Make the global canvas
  std::string glbLabel("HstMpsBunchTrainGlobal");
  glbCanvas=new TCanvas((glbLabel+"Canvas").c_str(),
                        glbLabel.c_str(),
                        10,10,610,760);
   
  // Set up global histogram titles
  glbTitle[0]="Number of subrecords;Number;Events";
  glbTitle[1]="Number of subrecords (errors);Number;Events";
  glbTitle[2]="Data errors;Number;Events";
  glbTitle[3]="Trigger input history;Time (25ns units);Input line";
  
  glbHist[0]=_pShm->_size.makeTH1F(glbLabel+"Hist0",
  _pShm->title()+glbTitle[0]);
  glbHist[1]=_pShm->_size.makeTH1F(glbLabel+"Hist1",
				   _pShm->title()+glbTitle[1]);
  glbHist[2]=_pShm->_errors.makeTH1F(glbLabel+"Hist2",
				    _pShm->title()+glbTitle[2]);
  glbHist2D=_pShm->_sensor[sens][1].makeTH2F(glbLabel+"Hist3",
				       _pShm->title()+glbTitle[3]);
   
  // Layout the canvas
  glbCanvas->Divide(1,2);
  glbCanvas->cd(1);
  gPad->Divide(2,1);

  glbCanvas->cd(1);
  gPad->cd(1);
  glbHist[0]->Draw();
  glbHist[1]->Draw("same");
  glbHist[1]->SetFillColor(kRed);

  glbCanvas->cd(1);
  gPad->cd(2);
  glbHist[2]->Draw();
  glbHist[2]->SetFillColor(kRed);

  glbCanvas->cd(2);
  glbHist2D->Draw("lego");
*/

  /*
  for(unsigned t(0);t<32;t++) {
    if(uBits.bit(t)) {
     
      // Set up global per TDC canvases
      std::ostringstream sout;
      sout << "HstMpsBunchTrainLine" << 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]="Input line"+nums[t]+" history;Time (25ns units);Events";
      tdcHist[t]=_pShm->_history[t].makeTH1F(tdcLabel+"Hist"+nums[t],
					     _pShm->title()+tdcTitle[t]);
    
      // Layout the canvas
      tdcCanvas[t]->cd();
      tdcHist[t]->Draw();
    }
  }
*/

  const unsigned sMs(5);
  HstFlags::Level refresh(HstFlags::configuration);
  //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) {

      for(unsigned i(0);i<4;i++) {
	if(uBits.bit(i) && hstCanvas[i]!=0) {
	  hstRecord[i]->SetTitle((_pShm->title()+hstTitle[i]).c_str());
	  _pShm->_sensor[sens][i].fillTH2F(hstRecord[i]);
	}
      }

	  /*
      glbHist2D->SetTitle((_pShm->title()+glbTitle[3]).c_str());
      _pShm->_sensor[sens][1].fillTH2F(glbHist2D);
	  */

	  //	  hstCanvas[i]->Modified();


      for(unsigned i(0);i<4;i++) {
	if(uBits.bit(i) && hstCanvas[i]!=0) {
	  hstCanvas[i]->cd();
	  gPad->Modified();


	  /*
	  gPad->cd(1);
      gPad->Modified();
      glbCanvas->cd(1);
      gPad->cd(2);
      gPad->Modified();
      glbCanvas->cd(2);
      gPad->Modified();
	  */


      /*
      for(unsigned t(0);t<32;t++) {
	if(uBits.bit(t)) {
	  tdcCanvas[t]->Modified();
	}
      }
      */

	}
      }

      // Finally do all the updates
      for(unsigned i(0);i<4;i++) {
	if(uBits.bit(i) && hstCanvas[i]!=0) {
	  hstCanvas[i]->Update();
	}
      }
      /*
      for(unsigned t(0);t<32;t++) {
	if(uBits.bit(t)) {
	  tdcCanvas[t]->Update();
	}
      }
      */
    }

    gSystem->Sleep(sleepMs);
  }
}
