/* ======================================================================== *\
!
! *
! * This file is part of MARS, the MAGIC Analysis and Reconstruction
! * Software. It is distributed to you in the hope that it can be a useful
! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
! * It is distributed WITHOUT ANY WARRANTY.
! *
! * Permission to use, copy, modify and distribute this software and its
! * documentation for any purpose is hereby granted without fee,
! * provided that the above copyright notice appear in all copies and
! * that both that copyright notice and this permission notice appear
! * in supporting documentation. It is provided "as is" without express
! * or implied warranty.
! *
!
!   Author(s): Javier Rico     05/2004 <mailto:jrico@ifae.es>
!
!   Copyright: MAGIC Software Development, 2000-2004
!
!
\* ======================================================================== */

//////////////////////////////////////////////////////////////////////////////
//
// MDisplay
//
// Class to display camera events (MCamEvent)
// You can set an event-by-event display with pause between two consecutive 
// events. You can set an output PS file.
//
// Input containers (to be provided to the constructor):
//
//  MCamEvent
//  MGeomCam
//
// Output containers:
//
//
//////////////////////////////////////////////////////////////////////////////

#include <fstream>
#include <math.h>

#include "TCanvas.h"
#include "TPostScript.h"

#include "MParList.h"
#include "MDisplay.h"
#include "MCamEvent.h"
#include "MGeomCam.h"
#include "MHCamera.h"
#include "MRawRunHeader.h"
#include "MRawEvtHeader.h"

#include "MLog.h"
#include "MLogManip.h"

ClassImp(MDisplay);

using namespace std;

static const TString gsDefName       = "MDisplay";
static const TString gsDefTitle      = "Camera display task";
static const TString gsDefPSFileName = "display.ps";

// -------------------------------------------------------------------------
//
// Constructor. Need to provide the MCamEvent container to be displayed <event>
// and camera geometry <geom>. Also the display type <type> can be specified
// (see the MHCamera documentation for more details)
//
MDisplay::MDisplay(MCamEvent* event, MGeomCam* geom, Int_t type, const char* name, const char* title) 
  :  fGeomCam(geom), fCamEvent(event),  fCanvas(NULL), fPSFile(NULL), fDisplayType(type), fCreatePSFile(kFALSE), fPause(kTRUE)
{
  fName  = name  ? name  : gsDefName.Data();
  fTitle = title ? title : gsDefTitle.Data();

  fDisplay = new MHCamera(*geom);
  fDisplay->SetPrettyPalette();
  
  fPSFileName = gsDefPSFileName;
}
// -------------------------------------------------------------------------
//
// Destructor
//
MDisplay::~MDisplay()
{
  delete fDisplay;
  if(fCanvas)
    delete fCanvas;
  if(fPSFile)
    delete fPSFile;
}

// -------------------------------------------------------------------------
//
// Create the canvas, eventually set the batch mode and open ps file
//
Int_t MDisplay::PreProcess(MParList* pList)
{ 
  fCanvas = new TCanvas("myCanvas","Event Display",600,600);
  if(fCreatePSFile) 
    fPSFile = new TPostScript(fPSFileName,111);
  if(!fPause)
    fCanvas->SetBatch();
  fCanvas->cd(1);
  fDisplay->Draw();

  //look for the run and event headers
  fEvtHeader = (MRawEvtHeader*)pList->FindObject("MRawEvtHeader");
  if (!fEvtHeader)
    {
      *fLog << err << "MRawEvtHeader not found... aborting." << endl;
      return kFALSE;
    }
  
  fRunHeader = (MRawRunHeader*)pList->FindObject(AddSerialNumber("MRawRunHeader"));
  if (!fRunHeader)
    {
      *fLog << err << AddSerialNumber("MRawRunHeader") << " not found... aborting." << endl;
      return kFALSE;
    }

  return kTRUE;
}

// -------------------------------------------------------------------------
//
// Set the new containt of the camera event and update the display.
// Set new page if ps file is requested
// Pause execution if event-by-event display is chosen
//
Int_t MDisplay::Process()
{  
  // new page in ps file
  if(fPSFile)
    fPSFile->NewPage();

  // update the display contents
  fDisplay->SetCamContent(*fCamEvent,fDisplayType);
  fCanvas->GetPad(1)->Modified();
  fCanvas->GetPad(1)->Update();
  
  *fLog << all << "Run: " << fRunHeader->GetRunNumber() << ", Event: " << fEvtHeader->GetDAQEvtNumber() << endl;

  // pause execution
  if(fPause)
    {
      cout << "Type 'q' to exit, 'p' to print event into ps file, <return> to go on: ";      
      TString input;
      input =cin.get(); 
      
      if (input=='q')
	return kFALSE;
      if(input=='p')
	{
	  Char_t psfile[200];
	  sprintf(psfile,"Run%06dEvent%07d.ps", fRunHeader->GetRunNumber(), fEvtHeader->GetDAQEvtNumber());
	  fCanvas->Print(psfile);
	}
    }

  return kTRUE;
}

// -------------------------------------------------------------------------
//
// Close ps file if it was open
//
Int_t MDisplay::PostProcess()
{
  if(fPSFile) fPSFile->Close();
  return kTRUE;
}
