#ifndef PAMVMC_DIGITIZER_H
#define PAMVMC_DIGITIZER_H
#include <iostream>
#include <fstream>
#include <TObject.h>
#include <TString.h>
#include <TFile.h>
#include <TTree.h>
#include <TMap.h>
#include <TObjString.h>
#include <TClonesArray.h>
#include <TDatabasePDG.h>
#include <TParticlePDG.h>
#include <TRandom3.h>
#include "PamVMCSQLMgr.h"
#include "PamVMCRawMgr.h"
#include "PamVMCDetectorHit.h"
#include "PamVMCRndMgr.h"


using namespace std;

class PamVMCDigitizer  : public TObject {

  
 protected:

  TString fdname;
  
  PamVMCSQLMgr * fsql;   //pointer to SQL Mgr
  PamVMCRawMgr * fraw;   //pointer to RAW Mgr
  PamVMCRndMgr * frnd;   //pointer to random object Mgr

  TRandom3 * frandom; //a random object. Class is an owner

  ifstream fcfile;     //binary file with calib data if any
  stringstream fquery;    //query ty mysql 
  Int_t fdberr;           //error index (check db)
  TString fpath;          //path to default calibration datafiles;
  TFile * fcrfile; //pointer to file with calibration  

  TMap fhitscolmap; //vector of hit collections (TClonesArray), given by SD to digitize
  

  USBuffer fData; //detector's data vector
  UCBuffer fDataPSCU; //detector's PSCU data

  UInt_t fPadding; //data padding
  UCBuffer fDataPadding; //detector's Padding data


 public:


  PamVMCDigitizer(const char *dname="dummy"): fdname(dname)
  {
    frandom = new TRandom3(0);
    frandom->SetName(dname);
    fsql = PamVMCSQLMgr::Instance();
    fraw = PamVMCRawMgr::Instance();
    frnd = PamVMCRndMgr::Instance();
    fdberr = fPadding = 0;
    fpath = fsql->GetDataPath();
    fquery.str("");
    frnd->RegisterRandom(fdname, frandom);
  }

  
  virtual ~PamVMCDigitizer() { 
    delete fcrfile;
    delete fraw;
    delete fsql;
    delete frandom;
    fhitscolmap.Clear("C");
  }
  
  /*This method calls from SD to pass pointers to it's collection(s)*/
  void RegisterCollections(const char* name, TClonesArray * hitcoll){ 
    fhitscolmap.Add(new TObjString(name), hitcoll); 
  }

  virtual void PrintCollections(){
    cout<<"HitCollections Map for: "<<fdname<<endl;
    fhitscolmap.Print();
  }

  /*Setting a pointer to random number if needed */
  virtual void SetRandom(TRandom3* random){
    *frandom = *random;
    frandom->SetName(fdname);
  }

  /*This method calls from application*/
  virtual void LoadCalib(){; };
 
  /*This method looks into SD map and take the pointer to
   hit collection of specific detector... For TOF it overriden
   (we have here 6 hits collections */
  virtual void Digitize()=0;

  /*This method calls by DigManager from it's digitize procedure.
   Method was created to force detectors push their data to main buffer
  according sequense of packet 0x10 organization*/
  virtual void WriteToBuff() { fraw->CopyUShortToBuff(&fData); }

  /*This method calls from application after all evens. Designed for RunTrailer*/
  virtual void FinishRun(){; };

  void DigitizePSCU(UInt_t len, UChar_t type)
    { fraw->DigitizePSCU(len, type, &fDataPSCU); }

  void AddPadding(){ fraw->AddPadding(fPadding,&fDataPadding); }

  void SetPadding(UInt_t pad){ fPadding = pad; }


  void ThrowCalFileUsage(const char* detname, const char* filename){
    cout<<"Use calibrations for "<<detname<<" from file: "<<filename<<endl;
  }

  void ThrowCalFileWarning(const char* detname){
    cout<<"!!!WARNING: No calibration for "<<detname<<" found... "
	<<" Calibration IMPOSSIBLE!!!"<<endl;
  }

  ClassDef(PamVMCDigitizer,1)
};


#endif //PAMVMC_DIGITIZER_H
