#ifndef DspCosmics3_HH
#define DspCosmics3_HH

#include <iostream>
#include <fstream>
#include <sstream>

#include "TROOT.h"
#include "TApplication.h"
#include "TCanvas.h"
#include "TLatex.h"
#include "TPaveLabel.h"
#include "TH1D.h"
#include "TH2D.h"
#include "TLine.h"
#include "TPolyLine.h"
#include "TBox.h"
#include "TPostScript.h"
#include "TEllipse.h"

#include "RcdRecord.hh"
#include "SubAccessor.hh"

#include "EmcEventEnergy.hh"
#include "BmlLc1176Alignment.hh"
#include "BmlLc1176Track.hh"


class DspCosmics3 {

public:
  DspCosmics3() : _application("Event Display Application",0,0), _track(_baln) {

    gROOT->Reset();
    gROOT->SetStyle("Plain");
    
    _canvas=new TCanvas("Event Display Canvas","Event Display Canvas",200,10,27*30,22*30);
    _canvas->Draw();
    
    gPad->Range(0.0,-1.0,27.0,21.0);
    
    Double_t space(0.2),epsi(1/30.0);
    
    for(unsigned x(0);x<18;x++) {
      for(unsigned y(0);y<12;y++) {
	bXY[0][x][y]=new TBox(8.0+x-epsi,8.0+y-epsi,9.0+x+epsi,9.0+y+epsi);
	bXY[1][x][y]=new TBox(8.0+x+epsi,8.0+y+epsi,9.0+x-epsi,9.0+y-epsi);
	bXY[0][x][y]->SetFillColor(1);
	bXY[0][x][y]->Draw("f");
	//bXY[1][x][y]->SetFillStyle(4000);
	bXY[1][x][y]->Draw("f");
      }
    }

    for(unsigned x(0);x<18;x++) {
      for(unsigned z(0);z<14;z++) {
	double os(0.5*(z%2));

	bXZ[0][x][z]=new TBox(8.0+x-epsi+os,7.0-2.0*z*space+epsi,9.0+x+epsi+os,7.0-(2.0*z+1.0)*space-epsi);
	bXZ[1][x][z]=new TBox(8.0+x+epsi+os,7.0-2.0*z*space-epsi,9.0+x-epsi+os,7.0-(2.0*z+1.0)*space+epsi);
	bXZ[0][x][z]->SetFillColor(1);
	bXZ[0][x][z]->Draw("f");
	bXZ[1][x][z]->Draw("f");
      }
    }

    for(unsigned y(0);y<12;y++) {
      for(unsigned z(0);z<14;z++) {
	bYZ[0][y][z]=new TBox(7.0-2.0*z*space+epsi,8.0+y-epsi,7.0-(2.0*z+1.0)*space-epsi,9.0+y+epsi);
	bYZ[1][y][z]=new TBox(7.0-2.0*z*space-epsi,8.0+y+epsi,7.0-(2.0*z+1.0)*space+epsi,9.0+y-epsi);
	bYZ[0][y][z]->SetFillColor(1);
	bYZ[0][y][z]->Draw("f");
	bYZ[1][y][z]->Draw("f");
      }
    }

    lXZ=new TLine(8.0,8.0,20.0,20.0);
    lXZ->SetLineColor(4);
    lXZ->SetLineWidth(5);
    lXZ->Draw();

    lYZ=new TLine(8.0,20.0,20.0,8.0);
    lYZ->SetLineColor(4);
    lYZ->SetLineWidth(5);
    lYZ->Draw();

    eXY=new TEllipse(17.0,11.0,0.2);
    eXY->SetLineColor(4);
    eXY->SetLineWidth(5);
    eXY->Draw();


    _canvas->Update();
  }

  virtual ~DspCosmics3() {
  }

  void event(const RcdRecord &r, const EmcEventEnergy &energy, bool doPs=false) {

    if(r.recordType()==RcdHeader::runStart) {
      SubAccessor accessor(r);

      unsigned rnum(100111); // HARDCODED!!!
      std::ostringstream oss;
      oss << "data/aln/AlnBml" << rnum << ".txt";
      _baln.read(oss.str());

      std::vector<const EmcStageStartupData*> vc(accessor.extract<EmcStageStartupData>());
      assert(vc.size()==1);
      _baln.stageData(*vc[0]);
      _baln.print(std::cout);
    }



    if(r.recordType()!=RcdHeader::event) return;

    /*
    TPostScript *pps(0);
    if(doPs) {
      pps=new TPostScript("display.ps",112);
    }
    */

    SubAccessor extracter(r);

    std::ostringstream oss;
    r.RcdHeader::print(oss);

    _canvas->cd(3);
    TPaveLabel label(0.5,-0.5,13.0,0.5,oss.str().c_str());
    label.Draw();

    std::ostringstream oss2;
    std::vector<const DaqEvent*> w(extracter.extract<DaqEvent>());
    if(w.size()>0) w[0]->print(oss2);

    TPaveLabel label2(14.0,-0.5,26.5,0.5,oss2.str().c_str());
    label2.Draw();

    //r.print(std::cout);

    double thresh(25.0);

    for(unsigned x(0);x<18;x++) {
      for(unsigned y(0);y<12;y++) {
	unsigned colour(0);
	for(unsigned z(0);z<14;z++) {

	  //if(z==0 && y==0 && x==0)cout << "X,Y,Z = " << x << " " << y+6 << " " << z << " Energy = "
	  //     << energy.energy(EmcPhysicalPad(x,y+6,z)) << endl;

	  if(energy.energy(EmcPhysicalPad(x,y+6,z))>thresh) {
	    if(z==0) colour=2;
	    //if(z>0 && colour==0) colour=102;
	  }
	}

	bXY[1][x][y]->SetFillColor(colour);
	//bXY[x][y]->Draw("f");
      }
    }

    for(unsigned x(0);x<18;x++) {
      for(unsigned z(0);z<14;z++) {
	unsigned colour(0);
	for(unsigned y(0);y<12;y++) {
	  if(energy.energy(EmcPhysicalPad(x,y+6,z))>thresh) colour=2;
	}
	bXZ[1][x][z]->SetFillColor(colour);
        //bXZ[x][z]->Draw("f");
      }
    }

    for(unsigned y(0);y<12;y++) {
      for(unsigned z(0);z<14;z++) {
	unsigned colour(0);
	for(unsigned x(0);x<18;x++) {
	  if(energy.energy(EmcPhysicalPad(x,y+6,z))>thresh) colour=2;
	}
	bYZ[1][y][z]->SetFillColor(colour);
        //bYZ[y][z]->Draw("f");
      }
    }


    if(_track.record(r)) {
      lXZ->SetX1(17.0+_track.xZero());
      lXZ->SetY1(7.5);
      lXZ->SetX2(17.0+_track.xZero()+10.0*_track.xTangent());
      lXZ->SetY2(1.0);
 
      lYZ->SetX1(7.5);
      lYZ->SetY1(11.0+_track.yZero());
      lYZ->SetX2(1.0);
      lYZ->SetY2(11.0+_track.yZero()+10.0*_track.xTangent());

      eXY->SetX1(17.0+_track.xZero());
      eXY->SetY1(11.0+_track.yZero());

      eXY->Draw();
      lXZ->Draw();
      lYZ->Draw();
    } else {
      lXZ->SetX1(999.0);
      lXZ->SetY1(999.0);
      lXZ->SetX2(999.0);
      lXZ->SetY2(999.0);

      lYZ->SetX1(999.0);
      lYZ->SetY1(999.0);
      lYZ->SetX2(999.0);
      lYZ->SetY2(999.0);

      eXY->SetX1(999.0);
      eXY->SetY1(999.0);

      eXY->Draw();
      lXZ->Draw();
      lYZ->Draw();
    }


    //std::cout << "Updating" << std::endl;

    _canvas->Update();

    if(doPs) {
      /*
      pps->Close();
      delete pps;
    */

      _canvas->Print("display.ps");
      _canvas->Print("display.eps");
    }
  }
  
private:
  TApplication _application;
  TCanvas *_canvas;
  //TPaveLabel *_label;
  TBox *bXY[2][18][12],*bXZ[2][18][14],*bYZ[2][12][14];
  TLine *lXZ,*lYZ;
  TEllipse *eXY;

  BmlLc1176Alignment _baln;
  BmlLc1176Track _track;
};

#endif
