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

void HstCrcFeNoise(const unsigned *bits=0, 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();
  
  // Allow either crate numbering scheme
  // Create a new canvas and 3 pads
  TCanvas *hstCrcNoiseCanvas[2][22][8];
  
   // Create pointers to the objects in shared memory.
  TH1F *hstCrcNoiseNumber[2][22][8];
  TH1F *hstCrcNoisePedestal[2][22][8];
  TH1F *hstCrcNoiseNoise[2][22][8];
  std::ostringstream sout[2][22][8];
  
  for(unsigned c(0);c<2;c++) {
    for(unsigned i(0);i<22;i++) {
      for(unsigned f(0);f<8;f++) {
	hstCrcNoiseCanvas[c][i][f]=0;
      }
    }
    
    //if((bits&(1<<(30+c)))!=0) {
    //if(c==crate) {
      
      for(unsigned i(2);i<22;i++) {
	//if((bits&(1<<(8+i)))!=0) {
	//if(i==slot) {
	  
	  for(unsigned f(0);f<8;f++) {
	    unsigned bit(8*((i-2)%4)+f);
	    if(bits==0 || (bits[5*c+(i-2)/4]&(1<<bit))!=0) {
	    //if((bits&(1<<f))!=0) {
	    //if(f==fe) {
	      
	      sout[c][i][f] << "HstCrcFeNoiseCrate" << c << "Slot";
	      if(i<10) sout[c][i][f] << "0";
	      sout[c][i][f] << i << "Fe" << f;

	      std::cout << sout[c][i][f].str() << std::endl;
	      
	      std::string temp=sout[c][i][f].str();
	      hstCrcNoiseNumber[c][i][f]=(TH1F*)mfile->Get((temp+"Number").c_str());
	      
	      if(hstCrcNoiseNumber[c][i][f]!=0) {
		hstCrcNoiseCanvas[c][i][f]=new 
		  TCanvas(temp.c_str(),temp.c_str(),
			  200+10*i,10+10*i,700,780);
		hstCrcNoiseCanvas[c][i][f]->Divide(1,3);
	      }
	    }
	    //	  }
	    //	}
      }
    }
  }
  
  // Create pointers to the objects in shared memory.
  TH1F *localHstCrcNoise[2][22][8][3];
  for(unsigned c(0);c<2;c++) {
    for(unsigned i(0);i<22;i++) {
      for(unsigned f(0);f<8;f++) {
	if(hstCrcNoiseCanvas[c][i][f]!=0) {

	  std::cout << c << " " << i << " " << f << std::endl;

	  if(hstCrcNoiseNumber[c][i][f]!=0) localHstCrcNoise[c][i][f][0]=new TH1F(*hstCrcNoiseNumber[c][i][f]);
	  hstCrcNoiseCanvas[c][i][f]->cd(1);
	  localHstCrcNoise[c][i][f][0]->Draw();
	  
	  if(hstCrcNoisePedestal[c][i][f]!=0) localHstCrcNoise[c][i][f][1]=new TH1F(*hstCrcNoisePedestal[c][i][f]);
	  hstCrcNoiseCanvas[c][i][f]->cd(2);
	  localHstCrcNoise[c][i][f][1]->Draw();
	  
	  if(hstCrcNoiseNoise[c][i][f]!=0) localHstCrcNoise[c][i][f][2]=new TH1F(*hstCrcNoiseNoise[c][i][f]);
	  hstCrcNoiseCanvas[c][i][f]->cd(3);
	  localHstCrcNoise[c][i][f][2]->Draw();
	}
      }
    }
  }
  
  // Loop displaying the histograms. Once the producer stops this
  // script will break out of the loop.
  while (gSystem->ProcessEvents()) {
    for(unsigned c(0);c<2;c++) {
      for(unsigned i(0);i<22;i++) {
	for(unsigned f(0);f<8;f++) {
	  if(hstCrcNoiseCanvas[c][i][f]!=0) {
	  std::cout << c << " " << i << " " << f << std::endl;

	    hstCrcNoiseCanvas[c][i][f]->Modified();
	    hstCrcNoiseCanvas[c][i][f]->Update();
	    
	  std::cout << c << " " << i << " " << f << std::endl;

	    std::string temp=sout[c][i][f].str();
	    hstCrcNoiseNumber[c][i][f]  =(TH1F*)mfile->Get((temp+"Number").c_str(),hstCrcNoiseNumber[c][i][f]);
	    hstCrcNoisePedestal[c][i][f]=(TH1F*)mfile->Get((temp+"Average").c_str(),hstCrcNoisePedestal[c][i][f]);
	    hstCrcNoiseNoise[c][i][f]   =(TH1F*)mfile->Get((temp+"Rms").c_str(),hstCrcNoiseNoise[c][i][f]);
	    
	  std::cout << c << " " << i << " " << f << std::endl;

	    hstCrcNoiseCanvas[c][i][f]->cd(1);
	    if(hstCrcNoiseNumber[c][i][f]!=0) hstCrcNoiseNumber[c][i][f]->Draw();
	  std::cout << c << " " << i << " " << f << std::endl;

	    hstCrcNoiseCanvas[c][i][f]->cd(2);
	    if(hstCrcNoisePedestal[c][i][f]!=0) hstCrcNoisePedestal[c][i][f]->Draw();
	  std::cout << c << " " << i << " " << f << std::endl;

	    hstCrcNoiseCanvas[c][i][f]->cd(3);
	    //if(hstCrcNoiseNoise[c][i][f]!=0) hstCrcNoiseNoise[c][i][f]->GetXaxis()->SetRange(6*18+1,8*18);
	    if(hstCrcNoiseNoise[c][i][f]!=0) hstCrcNoiseNoise[c][i][f]->Draw();
	    
	  std::cout << c << " " << i << " " << f << std::endl;
	  }
	}
      }
    }
    gSystem->Sleep(sleepMs);
  }
}

void HstCrcFeNoise(unsigned crate, const unsigned slot, const unsigned fe, const unsigned sleepMs=1000) {
   if(crate==0xec) crate=0;
   if(crate==0xac) crate=1;
   if(crate>1) return;
   if(slot>21) return;
   if(fe>7) return;

   unsigned bits[10];
   for(unsigned i(0);i<10;i++) bits[i]=0;

   unsigned abit(8*((slot-2)%4)+fe);
   bits[5*crate+(slot-2)/4]=1<<abit;

   std::cerr << "abit = " << abit << std::endl;

   HstCrcFeNoise(bits,sleepMs);
}
