#include "TMapFile.h"
#include "TCanvas.h"
#include "TSystem.h"
#include "TBox.h"
#include "TPaveLabel.h"
#include "TArrow.h"

void HstEmcEvent(const float cut=30.0, unsigned sleepMs=100) {

  // Histogram consumer script. Create a canvas and 3 pads. Connect
  // to memory mapped file "hsimple.map", that was created by hprod.C.
  // It reads the histograms from shared memory and displays them
  // in the pads (sleeping for 0.1 seconds before starting a new read-out
  // cycle). This script runs in an infinite loop, so use ctrl-c to stop it.
  
  gROOT->Reset();
  
  // Open the memory mapped file "hsimple.map" in "READ" (default) mode.
  TMapFile *mfile = TMapFile::Create("HstGeneric.map");

  // Print status of mapped file and list its contents
  mfile->Print();
  
  // Create a new canvas
  TCanvas *hstEmcEventCanvas(0);
   
  // Create pointer to the object in shared memory.
  TH1F *hstCrcEvent(0);
  hstCrcEvent=(TH1F*)mfile->Get("HstCrcSignalCrate0");
  if(hstCrcEvent==0) return;

  hstEmcEventCanvas=new 
    TCanvas("HstEmcEventCanvas","HstEmcEvent",10,10,610,610);
  gPad->Range(0.0,-0.6,1.6,1.0);

  double e(0.002);

  TBox bgXY(0.1-e,0.1-e,0.9+e,0.9+e);
  bgXY.SetFillColor(1);
  bgXY.Draw("f");

  TBox *bXY[18][18];
  for(unsigned i(0);i<18;i++) {
    for(unsigned j(0);j<18;j++) {
      bXY[i][j]=new TBox(0.1+e+0.8*i/18.0,
			 0.1+e+0.8*j/18.0,
			 0.1-e+0.8*(i+1)/18.0,
			 0.1-e+0.8*(j+1)/18.0);
      bXY[i][j]->SetFillColor(0);
      bXY[i][j]->Draw("f");
    }
  }
  
  TBox bgXZ(0.1-e,-(0.1-e),0.9+e,-(0.5+e));
  bgXZ.SetFillColor(1);
  bgXZ.Draw("f");

  TBox *bXZ[18][30];
  for(unsigned i(0);i<18;i++) {
    for(unsigned j(0);j<30;j++) {
      bXZ[i][j]=new TBox(0.1+e+0.8*i/18.0,
		       -(0.1+e+0.4*j/30.0),
			 0.1-e+0.8*(i+1)/18.0,
		       -(0.1-e+0.4*(j+1)/30.0));
      bXZ[i][j]->SetFillColor(0);
      bXZ[i][j]->Draw("f");
    }
  }
  
  TBox bgYZ(1.1-e,0.1-e,1.5+e,0.9+e);
  bgYZ.SetFillColor(1);
  bgYZ.Draw("f");

  TBox *bYZ[18][30];
  for(unsigned i(0);i<18;i++) {
    for(unsigned j(0);j<30;j++) {
      bYZ[i][j]=new TBox(1.1+e+0.4*j/30.0,
		         0.1+e+0.8*i/18.0,
			 1.1-e+0.4*(j+1)/30.0,
		         0.1-e+0.8*(i+1)/18.0);
      bYZ[i][j]->SetFillColor(0);
      bYZ[i][j]->Draw("f");
    }
  }
  
  TPaveLabel label(1.1,-0.3,1.5,-0.2,"NO DATA");
  label.Draw();

  TArrow aXYx(0.05,0.05,0.15,0.05);
  TArrow aXYy(0.05,0.05,0.05,0.15);
  aXYx.Draw();
  aXYy.Draw();

  TArrow aXZx(0.05,-0.05,0.15,-0.05);
  TArrow aXZz(0.05,-0.05,0.05,-0.15);
  aXZx.Draw();
  aXZz.Draw();

  TArrow aYZz(1.05,0.05,1.15,0.05);
  TArrow aYZy(1.05,0.05,1.05,0.15);
  aYZz.Draw();
  aYZy.Draw();


  unsigned slot[30],fe[30];

  // Dec04
  /*
  unsigned nLayers(10);
  slot[ 0]=17;fe[ 0]=5;
  slot[ 1]=12;fe[ 1]=5;
  slot[ 2]=12;fe[ 2]=1;
  slot[ 3]=12;fe[ 3]=2;
  slot[ 4]=12;fe[ 4]=3;
  slot[ 5]=12;fe[ 5]=4;
  slot[ 6]=17;fe[ 6]=1;
  slot[ 7]=17;fe[ 7]=2;
  slot[ 8]=17;fe[ 8]=3;
  slot[ 9]=17;fe[ 9]=4;
  */

  // Dec05
  /*
  unsigned nLayers(16);
  slot[ 0]= 7;fe[ 0]=0;
  slot[ 1]= 7;fe[ 1]=1;
  slot[ 2]= 7;fe[ 2]=2;
  slot[ 3]= 7;fe[ 3]=3;
  slot[ 4]= 7;fe[ 4]=4;
  slot[ 5]= 7;fe[ 5]=5;
  slot[ 6]= 7;fe[ 6]=6;
  slot[ 7]= 7;fe[ 7]=7;
  slot[ 8]=17;fe[ 8]=0;
  slot[ 9]=17;fe[ 9]=1;
  slot[10]=17;fe[10]=2;
  slot[11]=17;fe[11]=3;
  slot[12]=17;fe[12]=4;
  slot[13]=17;fe[13]=5;
  slot[14]=17;fe[14]=6;
  slot[15]=17;fe[15]=7;
  */

  // Feb06
  unsigned nLayers(16);
  slot[ 0]= 7;fe[ 0]=3;
  slot[ 1]=15;fe[ 1]=4;
  slot[ 2]=19;fe[ 2]=5;
  slot[ 3]=19;fe[ 3]=1;
  slot[ 4]= 7;fe[ 4]=4;
  slot[ 5]=19;fe[ 5]=6;
  slot[ 6]= 7;fe[ 6]=1;
  slot[ 7]=15;fe[ 7]=2;
  slot[ 8]= 7;fe[ 8]=2;
  slot[ 9]= 7;fe[ 9]=0;
  slot[10]=15;fe[10]=6;
  slot[11]=15;fe[11]=1;
  slot[12]=19;fe[12]=2;
  slot[13]=19;fe[13]=4;
  slot[14]=19;fe[14]=7;
  slot[15]=15;fe[15]=7;

  unsigned map[18][18][30];

  for(unsigned i(0);i<18;i++) {
    for(unsigned j(0);j<18;j++) {
      for(unsigned k(0);k<30;k++) {
	map[i][j][k]=0;
      }
    }
  }  

  for(unsigned i(0);i<18;i++) {
    unsigned xLocal=i;
    for(unsigned j(6);j<18;j++) {
      unsigned yLocal=j-6;
      unsigned chip=(xLocal/3);
      chip+=6*(yLocal/6);
      unsigned chan=(xLocal%3);
      chan+=3*(5-(yLocal%6));

      for(unsigned k(0);k<nLayers;k+=2) {
	map[i][j][k]=slot[k]*8*12*18+fe[k]*12*18+18*chip+chan;
      }

      yLocal=17-j;
      chip=(xLocal/3);
      chip+=6*(yLocal/6);
      chan=(xLocal%3);
      chan+=3*(5-(yLocal%6));

      for(unsigned k(1);k<nLayers;k+=2) {
	map[i][j][k]=slot[k]*8*12*18+fe[k]*12*18+18*chip+chan;
      }
    }
  }

  while (hstCrcEvent!=0) {
    //hstCrcEvent->Draw();

    /*
      std::cout << "Bin 1 = " << hstCrcEvent->GetBinContent(1) << std::endl;
      std::cout << "Bin 2 = " << hstCrcEvent->GetBinContent(2) << std::endl;
      std::cout << "Bin 3 = " << hstCrcEvent->GetBinContent(3) << std::endl;
      std::cout << "Bin 4 = " << hstCrcEvent->GetBinContent(4) << std::endl;
      std::cout << "Bin 5 = " << hstCrcEvent->GetBinContent(5) << std::endl;
      std::cout << "Bin 6 = " << hstCrcEvent->GetBinContent(6) << std::endl;
      std::cout << "Bin 7 = " << hstCrcEvent->GetBinContent(7) << std::endl;
      std::cout << "Bin 8 = " << hstCrcEvent->GetBinContent(8) << std::endl;
    */
    
    unsigned n[4];

    for(unsigned i(0);i<4;i++) n[i]=(unsigned)hstCrcEvent->GetBinContent(i+ 1);
    unsigned runNumber=(n[3]<<24)+(n[2]<<16)+(n[1]<<8)+(n[0]);
    
    for(unsigned i(0);i<4;i++) n[i]=(unsigned)hstCrcEvent->GetBinContent(i+ 5);
    unsigned cfgNumber=(n[3]<<24)+(n[2]<<16)+(n[1]<<8)+(n[0]);
    
    for(unsigned i(0);i<4;i++) n[i]=(unsigned)hstCrcEvent->GetBinContent(i+ 9);
    unsigned acqNumber=(n[3]<<24)+(n[2]<<16)+(n[1]<<8)+(n[0]);
    
    for(unsigned i(0);i<4;i++) n[i]=(unsigned)hstCrcEvent->GetBinContent(i+13);
    unsigned evtNumber=(n[3]<<24)+(n[2]<<16)+(n[1]<<8)+(n[0]);
    
    //if(hstCrcEvent->GetBinContent(1)>0.5) {
    if(runNumber>0 || cfgNumber>0 || acqNumber>0 || evtNumber>0) {
      
      // Set colours all to white
      for(unsigned i(0);i<18;i++) {
	for(unsigned j(0);j<18;j++) {
	  bXY[i][j]->SetFillColor(0);
	}
	for(unsigned j(0);j<30;j++) {
	  bXZ[i][j]->SetFillColor(0);
	  bYZ[i][j]->SetFillColor(0);
	}
      }
	
      for(unsigned i(0);i<18;i++) {
	for(unsigned j(0);j<18;j++) {
	  for(unsigned k(0);k<30;k++) {
	    float signal(0.0);
	    if(map[i][j][k]>0) {
	      signal=hstCrcEvent->GetBinContent(1+map[i][j][k]);
	      //std::cout << "signal = " << signal << std::endl;
	    }

	    //float py;
	    //gRandom->Rannor(signal,py);

	    if(signal<-cut) {
	      bXY[i][j]->SetFillColor(4);
	      bXZ[i][k]->SetFillColor(4);
	      bYZ[j][k]->SetFillColor(4);
	    }
	    if(signal>cut) {
	      bXY[i][j]->SetFillColor(2);
	      bXZ[i][k]->SetFillColor(2);
	      bYZ[j][k]->SetFillColor(2);
	    }
	  }
	}
      }
      
      std::ostringstream sout;
      sout << "Run " << runNumber
	   << ", Configuration " << cfgNumber
	   << ", Acquisition " << acqNumber
	   << ", Event " << evtNumber << std::endl;

      std::string temp(sout.str());
      label.SetLabel(temp.c_str());
      
      hstEmcEventCanvas->Modified();
      hstEmcEventCanvas->Update();
      
    } else {
      /*
      std::cout << "Bin 1 = " << hstCrcEvent->GetBinContent(1) << std::endl;
      std::cout << "Bin 2 = " << hstCrcEvent->GetBinContent(2) << std::endl;
      std::cout << "Bin 3 = " << hstCrcEvent->GetBinContent(3) << std::endl;
      std::cout << "Bin 4 = " << hstCrcEvent->GetBinContent(4) << std::endl;
      std::cout << "Bin 5 = " << hstCrcEvent->GetBinContent(5) << std::endl;
      std::cout << "Bin 6 = " << hstCrcEvent->GetBinContent(6) << std::endl;
      std::cout << "Bin 7 = " << hstCrcEvent->GetBinContent(7) << std::endl;
      std::cout << "Bin 8 = " << hstCrcEvent->GetBinContent(8) << std::endl;
      */
      std::cout << "Imcomplete event" << std::endl;
    }

    gSystem->Sleep(sleepMs);
    if (gSystem->ProcessEvents()) break;

    delete hstCrcEvent;
    hstCrcEvent=(TH1F*)mfile->Get("HstCrcSignalCrate0");
  }
}
