#ifndef HstSlwMonLm82_catherine_HH
#define HstSlwMonLm82_catherine_HH

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>

#include "TROOT.h"
#include "TApplication.h"
#include "TCanvas.h"
#include "TH1D.h"
#include "TH2D.h"
#include "TGraphErrors.h"
#include "TPostScript.h"

#include "UtlAverage.hh"
#include "RcdRecord.hh"
#include "CrcFeEventData.hh"
#include "CrcLocationData.hh"
#include "CrcLm82SlowReadoutData.hh"
#include "CrcLm82StartupData.hh"
#include "DaqEvent.hh"
#include "HstBase.hh"
#include "HstTGraph.hh"
#include "SubAccessor.hh"


class HstSlwMonLm82_catherine : public HstBase {

public:
  HstSlwMonLm82_catherine(CrcLocationData<CrcLm82SlowReadoutData> d, bool i=true) : 
    HstBase(i), _cld(d), _firstRecordTime(0) {
    for(unsigned crc(0);crc<2;crc++){
      for(unsigned lm82(0);lm82<10;lm82++){
	std::ostringstream sout0;
	sout0 << "Lm82Canvas[0][" << crc << "]" << "[" << lm82 << "]";
	std::ostringstream sout1;
	sout1 << "Lm82Canvas[1][" << crc << "]" << "[" << lm82 << "]";
	std::ostringstream sout2;
	sout2 << "Lm82Canvas[2][" << crc << "]" << "[" << lm82 << "]";
	_canvas[0][crc][lm82]=new TCanvas(sout0.str().c_str(),"Local temp",400,20,600,400);
	_canvas[1][crc][lm82]=new TCanvas(sout1.str().c_str(),"Remote temp",420,40,600,400);
	_canvas[2][crc][lm82]=new TCanvas(sout2.str().c_str(),"Status",440,60,600,400);
      }
    }
  }

  virtual ~HstSlwMonLm82_catherine() {
  }

  
  bool record(const RcdRecord &r) {

    if(_firstRecordTime==0) {
      _firstRecordTime=r.recordTime().seconds();

      for(unsigned i(0);i<3;i++) {
	for(unsigned crc(0);crc<2;crc++){
	  for(uint lm82(0);lm82<10;lm82++){
	    std::ostringstream sout;
	    sout << "Crate " << (unsigned)_cld.crateNumber() << ", Slot ";
	    if(crc==0) sout << "12, ";
	    if(crc==1) sout << "17, ";
	    if(lm82==0) sout << "CRC FE0,";
	    if(lm82==1) sout << "CRC FE1,";
	    if(lm82==2) sout << "CRC FE2,";
	    if(lm82==3) sout << "CRC FE3,";
	    if(lm82==4) sout << "CRC FE4,";
	    if(lm82==5) sout << "CRC FE5,";
	    if(lm82==6) sout << "CRC FE6,";
	    if(lm82==7) sout << "CRC FE7,";
	    if(lm82==8) sout << "CRC BE,";
	    if(lm82==9) sout << "CRC VME,";
	    sout << " LM82 ";
	    if(i==0) sout << "Local Temperature";
	    if(i==1) sout << "Remote Temperature";
	    if(i==2) sout << "Status";	    
	    sout << " vs Time (Days) since " << r.recordTime();
	    _graph[i][crc][lm82].SetTitle(sout.str().c_str());
	    _graph[i][crc][lm82].SetMarkerColor(crc+2);
	    _graph[i][crc][lm82].SetMarkerStyle(22);
	  }
	}
      }
    }

    double deltat((r.recordTime().seconds()-_firstRecordTime)/(24.0*3600.0));

    SubAccessor extracter(r);

    if(r.recordType()==RcdHeader::slowReadout) {
      std::vector<const CrcLocationData<CrcLm82SlowReadoutData>*>
	c(extracter.extract< CrcLocationData<CrcLm82SlowReadoutData> >());
      
      //if(_printLevel>2)

 c[0]->print(std::cout);
      
      // read in data
      int crc(0);
      int lm82(0);
      for(unsigned st(0);st<c.size();st++){
	if(c[st]->slotNumber()==8){
	  crc=0;
	  if(c[st]->crcComponent()==CrcLocation::fe0){
	    lm82=0;
	    _graph[0][crc][lm82].AddPoint(deltat,c[st]->data()->localTemperature());
	    _graph[1][crc][lm82].AddPoint(deltat,c[st]->data()->remoteTemperature());
	    _graph[2][crc][lm82].AddPoint(deltat,c[st]->data()->status());
	  }
	  if(c[st]->crcComponent()==CrcLocation::fe1){
	    lm82=1;
	    _graph[0][crc][lm82].AddPoint(deltat,c[st]->data()->localTemperature());
	    _graph[1][crc][lm82].AddPoint(deltat,c[st]->data()->remoteTemperature());
	    _graph[2][crc][lm82].AddPoint(deltat,c[st]->data()->status());
	  }
	  if(c[st]->crcComponent()==CrcLocation::fe2){
	    lm82=2;
	    _graph[0][crc][lm82].AddPoint(deltat,c[st]->data()->localTemperature());
	    _graph[1][crc][lm82].AddPoint(deltat,c[st]->data()->remoteTemperature());
	    _graph[2][crc][lm82].AddPoint(deltat,c[st]->data()->status());
	  }
	  if(c[st]->crcComponent()==CrcLocation::fe3){
	    lm82=3;
	    _graph[0][crc][lm82].AddPoint(deltat,c[st]->data()->localTemperature());
	    _graph[1][crc][lm82].AddPoint(deltat,c[st]->data()->remoteTemperature());
	    _graph[2][crc][lm82].AddPoint(deltat,c[st]->data()->status());
	  }
	  if(c[st]->crcComponent()==CrcLocation::fe4){
	    lm82=4;
	    _graph[0][crc][lm82].AddPoint(deltat,c[st]->data()->localTemperature());
	    _graph[1][crc][lm82].AddPoint(deltat,c[st]->data()->remoteTemperature());
	    _graph[2][crc][lm82].AddPoint(deltat,c[st]->data()->status());
	  }
	  if(c[st]->crcComponent()==CrcLocation::fe5){
	    lm82=5;
	    _graph[0][crc][lm82].AddPoint(deltat,c[st]->data()->localTemperature());
	    _graph[1][crc][lm82].AddPoint(deltat,c[st]->data()->remoteTemperature());
	    _graph[2][crc][lm82].AddPoint(deltat,c[st]->data()->status());
	  }
	  if(c[st]->crcComponent()==CrcLocation::fe6){
	    lm82=6;
	    _graph[0][crc][lm82].AddPoint(deltat,c[st]->data()->localTemperature());
	    _graph[1][crc][lm82].AddPoint(deltat,c[st]->data()->remoteTemperature());
	    _graph[2][crc][lm82].AddPoint(deltat,c[st]->data()->status());
	  }
	  if(c[st]->crcComponent()==CrcLocation::fe7){
	    lm82=7;
	    _graph[0][crc][lm82].AddPoint(deltat,c[st]->data()->localTemperature());
	    _graph[1][crc][lm82].AddPoint(deltat,c[st]->data()->remoteTemperature());
	    _graph[2][crc][lm82].AddPoint(deltat,c[st]->data()->status());
	  }
	  if(c[st]->crcComponent()==CrcLocation::be){
	    lm82=8;
	    _graph[0][crc][lm82].AddPoint(deltat,c[st]->data()->localTemperature());
	    _graph[1][crc][lm82].AddPoint(deltat,c[st]->data()->remoteTemperature());
	    _graph[2][crc][lm82].AddPoint(deltat,c[st]->data()->status());
	  }
	  if(c[st]->crcComponent()==CrcLocation::vmeLm82){
	    lm82=9;
	    _graph[0][crc][lm82].AddPoint(deltat,c[st]->data()->localTemperature());
	    _graph[1][crc][lm82].AddPoint(deltat,c[st]->data()->remoteTemperature());
	    _graph[2][crc][lm82].AddPoint(deltat,c[st]->data()->status());
	  }
	}
	if(c[st]->slotNumber()==16){
	  crc=1;
	  if(c[st]->crcComponent()==CrcLocation::fe0){
	    lm82=0;
	    _graph[0][crc][lm82].AddPoint(deltat,c[st]->data()->localTemperature());
	    _graph[1][crc][lm82].AddPoint(deltat,c[st]->data()->remoteTemperature());
	    _graph[2][crc][lm82].AddPoint(deltat,c[st]->data()->status());
	  }
	  if(c[st]->crcComponent()==CrcLocation::fe1){
	    lm82=1;
	    _graph[0][crc][lm82].AddPoint(deltat,c[st]->data()->localTemperature());
	    _graph[1][crc][lm82].AddPoint(deltat,c[st]->data()->remoteTemperature());
	    _graph[2][crc][lm82].AddPoint(deltat,c[st]->data()->status());
	  }
	  if(c[st]->crcComponent()==CrcLocation::fe2){
	    lm82=2;
	    _graph[0][crc][lm82].AddPoint(deltat,c[st]->data()->localTemperature());
	    _graph[1][crc][lm82].AddPoint(deltat,c[st]->data()->remoteTemperature());
	    _graph[2][crc][lm82].AddPoint(deltat,c[st]->data()->status());
	  }
	  if(c[st]->crcComponent()==CrcLocation::fe3){
	    lm82=3;
	    _graph[0][crc][lm82].AddPoint(deltat,c[st]->data()->localTemperature());
	    _graph[1][crc][lm82].AddPoint(deltat,c[st]->data()->remoteTemperature());
	    _graph[2][crc][lm82].AddPoint(deltat,c[st]->data()->status());
	  }
	  if(c[st]->crcComponent()==CrcLocation::fe4){
	    lm82=4;
	    _graph[0][crc][lm82].AddPoint(deltat,c[st]->data()->localTemperature());
	    _graph[1][crc][lm82].AddPoint(deltat,c[st]->data()->remoteTemperature());
	    _graph[2][crc][lm82].AddPoint(deltat,c[st]->data()->status());
	  }
	  if(c[st]->crcComponent()==CrcLocation::fe5){
	    lm82=5;
	    _graph[0][crc][lm82].AddPoint(deltat,c[st]->data()->localTemperature());
	    _graph[1][crc][lm82].AddPoint(deltat,c[st]->data()->remoteTemperature());
	    _graph[2][crc][lm82].AddPoint(deltat,c[st]->data()->status());
	  }
	  if(c[st]->crcComponent()==CrcLocation::fe6){
	    lm82=6;
	    _graph[0][crc][lm82].AddPoint(deltat,c[st]->data()->localTemperature());
	    _graph[1][crc][lm82].AddPoint(deltat,c[st]->data()->remoteTemperature());
	    _graph[2][crc][lm82].AddPoint(deltat,c[st]->data()->status());
	  }
	  if(c[st]->crcComponent()==CrcLocation::fe7){
	    lm82=7;
	    _graph[0][crc][lm82].AddPoint(deltat,c[st]->data()->localTemperature());
	    _graph[1][crc][lm82].AddPoint(deltat,c[st]->data()->remoteTemperature());
	    _graph[2][crc][lm82].AddPoint(deltat,c[st]->data()->status());
	  }
	  if(c[st]->crcComponent()==CrcLocation::be){
	    lm82=8;
	    _graph[0][crc][lm82].AddPoint(deltat,c[st]->data()->localTemperature());
	    _graph[1][crc][lm82].AddPoint(deltat,c[st]->data()->remoteTemperature());
	    _graph[2][crc][lm82].AddPoint(deltat,c[st]->data()->status());
	  }
	  if(c[st]->crcComponent()==CrcLocation::vmeLm82){
	    lm82=9;
	    _graph[0][crc][lm82].AddPoint(deltat,c[st]->data()->localTemperature());
	    _graph[1][crc][lm82].AddPoint(deltat,c[st]->data()->remoteTemperature());
	    _graph[2][crc][lm82].AddPoint(deltat,c[st]->data()->status());
	  }
	} 
      }
    }
    
    return true;
  }
  
  bool update() {
    for(unsigned i(0);i<3;i++) {
      for(unsigned crc(0);crc<2;crc++){
	for(unsigned lm82(0);lm82<10;lm82++){
	  _canvas[i][crc][lm82]->Clear();
	  _graph[i][crc][lm82].Draw("AP");
	  _canvas[i][crc][lm82]->Update();
	}
      }
    }
    
    return true;
  }

  bool postscript(std::string file) {
    std::cout << "HstSlwMonLm82_catherine::postscript()  Writing to file "
              << file << std::endl;

    TPostScript ps(file.c_str(),112);
    update();
    ps.Close();

    return true;
  }

private:
  CrcLocationData<CrcLm82SlowReadoutData> _cld;
  unsigned _firstRecordTime;
  TCanvas *_canvas[3][2][10];
  HstTGraph _graph[3][2][10]; // 3 variables, 2 crcs, 10 locations per crc
};

#endif
