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


using namespace std;

class PamVMCDigitizer  : public TObject {

  TString fdname;
  
 protected:
  
  PamVMCSQLMgr * fsql;   //pointer to SQL Mgr
  PamVMCRawMgr * fraw;   //pointer to RAW Mgr

  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

  TRandom3 *rnd;

 public:


  PamVMCDigitizer(char *dname="dummy"): fdname(dname)
  {
    fsql = PamVMCSQLMgr::Instance();
    fraw = PamVMCRawMgr::Instance();
    fdberr = fPadding = 0;
    fpath = fsql->GetDataPath();
    fquery.str(""); 
  }

  
  virtual ~PamVMCDigitizer() { 
    delete fcrfile;
    delete fraw;
    delete fsql;
    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();
  }

  /*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,2)
};


#endif //PAMVMC_DIGITIZER_H
