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

void HstCrcNoise(const unsigned swi=0, const unsigned bits=0xffffff, const unsigned sleepMs=1000) {

   gROOT->Reset();

   // Open the memory mapped file in "READ" (default) mode.
   TMapFile* mfile = TMapFile::Create("HstGeneric.map");

   // Print status of mapped file
   mfile->Print();

   // Create a new canvas and 3 pads
   TCanvas *hstCrcNoiseCanvas[2][22];

   // Create pointers to the objects in shared memory.
   TH1F *hstCrcNoise[2][22][4];
   std::string hTitle[2][22][4];
   unsigned nCanvas(0);

   // Loop over crates
   for(unsigned c(0);c<2;c++) {
     for(unsigned i(0);i<22;i++) hstCrcNoiseCanvas[c][i]=0;
     if((bits&(1<<(22+c)))!=0) {

       // Loop over slots
       for(unsigned i(0);i<=21;i++) {
	 if((bits&(1<<i))!=0) {

	   // Make title strings
	   std::ostringstream title;
	   title << "HstCrcNoiseCrate" << c << "Slot";
	   if(i<10) title << "0";
	   title << i;
	   if (swi != 0) title << "Tot";

	   //std::cout << title.str() << std::endl;

	   hTitle[c][i][0]=title.str()+std::string("Number");
	   hTitle[c][i][1]=title.str()+std::string("Average");
	   hTitle[c][i][2]=title.str()+std::string("Rms");
	   hTitle[c][i][3]=title.str()+std::string("Unverified");
	   
	   for(unsigned j(0);j<4;j++) {
	     hstCrcNoise[c][i][j]=(TH1F*)mfile->Get(hTitle[c][i][j].c_str());
	     //if(hstCrcNoise[c][i][j]==0) {
	       //std::cout << "Histogram " << hTitle[c][i][j]
	       //	 << " not found" << std::endl;
	     //}
	   }

	   // Put up canvas
	   if(hstCrcNoise[c][i][0]!=0 &&
	      hstCrcNoise[c][i][1]!=0 &&
	      hstCrcNoise[c][i][2]!=0 &&
	      hstCrcNoise[c][i][3]!=0) {
	     std::string cTitle(title.str());
	     hstCrcNoiseCanvas[c][i]=new TCanvas((cTitle+"Canvas").c_str(),
						 cTitle.c_str(),
						 10+20*nCanvas,10+20*nCanvas,
						 610+20*nCanvas,760+20*nCanvas);
	     hstCrcNoiseCanvas[c][i]->Divide(1,3);
	     nCanvas++;
	   }
	 }
       }
     }
   }

   // Create pointers to the objects in shared memory.
   TH1F *localHstCrcNoise[2][22][4];
   for(unsigned c(0);c<2;c++) {
     for(unsigned i(0);i<22;i++) {
       if(hstCrcNoiseCanvas[c][i]!=0) {

	 for(unsigned j(0);j<4;j++) {
	   if(hstCrcNoise[c][i][j]!=0) localHstCrcNoise[c][i][j]=new TH1F(*hstCrcNoise[c][i][j]);

	   if(j<3) {
	     hstCrcNoiseCanvas[c][i]->cd(j+1);
	     localHstCrcNoise[c][i][j]->Draw();
	   } else {
	     hstCrcNoiseCanvas[c][i]->cd(1);
	     localHstCrcNoise[c][i][j]->SetFillColor(kRed);
	     localHstCrcNoise[c][i][j]->Draw("same");
	   }
	 }
       }
     }
   }

   while(!gSystem->ProcessEvents()) {
     for(unsigned c(0);c<2;c++) {
       for(unsigned i(0);i<22;i++) {
	 if(hstCrcNoiseCanvas[c][i]!=0) {
	   
	   for(unsigned j(0);j<4;j++) {
	     hstCrcNoise[c][i][j]=(TH1F*)mfile->Get(hTitle[c][i][j].c_str(),hstCrcNoise[c][i][j]);
	     
	     if(hstCrcNoise[c][i][j]!=0) {
	       localHstCrcNoise[c][i][j]->SetEntries(hstCrcNoise[c][i][j]->GetEntries());
	       for(int k(0);k<=1+hstCrcNoise[c][i][j]->GetNbinsX();k++) {
		 localHstCrcNoise[c][i][j]->SetBinContent(k,hstCrcNoise[c][i][j]->GetBinContent(k));
		 if(j>0 && j<3) localHstCrcNoise[c][i][j]->SetBinError(k,hstCrcNoise[c][i][j]->GetBinError(k));
	       }

	       /*
	       if(j<3) {
		 hstCrcNoiseCanvas[c][i]->cd(j+1);
		 localHstCrcNoise[c][i][j]->Draw();
	       } else {
		 hstCrcNoiseCanvas[c][i]->cd(1);
		 localHstCrcNoise[c][i][j]->SetFillColor(kRed);
		 localHstCrcNoise[c][i][j]->Draw("same");
	       }
	       */
	     }
	   }

	   hstCrcNoiseCanvas[c][i]->cd(1);
	   gPad->Modified();
	   hstCrcNoiseCanvas[c][i]->cd(2);
	   gPad->Modified();
	   hstCrcNoiseCanvas[c][i]->cd(3);
	   gPad->Modified();

	   //hstCrcNoiseCanvas[c][i]->Modified();
	   hstCrcNoiseCanvas[c][i]->Update();
	 }
       }
     }

     gSystem->Sleep(sleepMs);
   }
}

void HstCrcNoise(unsigned swi, unsigned crate, const unsigned slot, const unsigned sleepMs) {
  if(crate==0xec) crate=0;
  if(crate==0xac) crate=1;

  if(crate>1) return;
  if(slot>21) return;

  HstCrcNoise(swi,(1<<(crate+22))+(1<<slot),sleepMs);
}
