#ifndef PAMELA_DB_OPERATIONS_H
#define PAMELA_DB_OPERATIONS_H

#include <iostream>
#include <list>

#include <TFile.h>
#include <TSQLServer.h>
#include <EventHeader.h>
#include <PscuHeader.h>
#include <mcmd/McmdEvent.h>
#include <mcmd/McmdRecord.h>
#include <RunHeaderEvent.h>
#include <RunTrailerEvent.h>
#include <CalibCalPedEvent.h>
#include <CalibS4Event.h>
#include <CalibTrk1Event.h>
#include <CalibTrk2Event.h>
#include <varDump/VarDumpEvent.h>
#include <varDump/VarDumpRecord.h>
#include <physics/S4/S4Event.h>
#include <endrun/PhysEndRunEvent.h>
#include <endrun/TBEndRun.h>

#include <GLTables.h>

#include <sgp4.h>

using namespace pamela;

/**
 * Collections of Pamela specific operations over a database
 */
class PamelaDBOperations {

 private:
    TSQLServer *conn;
    TFile *file;
    //
    RunHeaderEvent *runh;
    EventHeader *ehh;
    PscuHeader *phh;
    RunTrailerEvent *runt;
    EventHeader *eht;
    PscuHeader *pht;
    //
    GL_RUN *glrun;
    //
    TString filerawname;
    TString filerootname;
    //
    UInt_t tsync;
    UInt_t toffset;
    //
    //    Long64_t olderthan;
    UInt_t dworbit;
    //
    UInt_t BOOTNO;
    UInt_t obt0;
    UInt_t id;
    UInt_t idroot;
    UInt_t pktfirst;
    UInt_t obtfirst;
    UInt_t ppktfirst;
    UInt_t pobtfirst;
    Long64_t upperobt;
    Long64_t upperpkt;
    UInt_t upperentry;
    Int_t rtev;
    Int_t rhev;
    Int_t nrtev;
    Int_t nrhev;
    //
    // calibration variables
    //
    Int_t t1;
    Int_t t2;
    UInt_t fromtime;
    UInt_t obt1;
    UInt_t pkt1;
    UInt_t obt2;
    UInt_t pkt2;
    UInt_t valid;
    //
    //
    Bool_t NOBOOT;
    Bool_t debug;

    // Path to tle file
    TString tlefilename;
	
    // flag to control profiler actions
    Bool_t STATIC;
    Bool_t KEEPENV;
    Bool_t INSERT_RAW;
    Bool_t INSERT_ROOT;
    Bool_t VALIDATE;
    Bool_t NOFRAG;
    Bool_t AUTOBOOT;
    Bool_t PEDANTIC;

    // flags and variables for chewbacca
    Bool_t chewbacca;
    UInt_t chID;
    //
    TString tag;
    TString chiby;
    //
    UInt_t chpktinit;
    UInt_t chpktfinal;
    UInt_t chobtinit;
    UInt_t chobtfinal;
    Int_t nrhbef;
    Int_t nrhaf;
    Int_t nrtbef;
    Int_t nrtaf;
    //
    UInt_t chpktmin;
    UInt_t chpktmax;
    UInt_t chobtmin;
    UInt_t chobtmax;
    UInt_t chobtts;
    UInt_t chlastts;
    UInt_t chresursts;
    UInt_t chboot;
    UInt_t chminentry;

    TDatime *clean_time;
    
    //
    typedef std::list<const char*> pcksList;
    static void getPacketsNames(pcksList &pcksNames){
	pcksNames.push_back("PhysEndRun");
	pcksNames.push_back("CalibCalPulse1");
	pcksNames.push_back("CalibCalPulse2");
	pcksNames.push_back("Physics");
	pcksNames.push_back("CalibTrkBoth");
	pcksNames.push_back("CalibTrk1");
	pcksNames.push_back("CalibTrk2");
	pcksNames.push_back("CalibTof");
	pcksNames.push_back("CalibS4");
	pcksNames.push_back("CalibCalPed");
	pcksNames.push_back("Calib1_Ac1");
	pcksNames.push_back("Calib2_Ac1");
	pcksNames.push_back("Calib1_Ac2");
	pcksNames.push_back("Calib2_Ac2");
	pcksNames.push_back("CalibCal");
	pcksNames.push_back("RunHeader");
	pcksNames.push_back("RunTrailer");
	pcksNames.push_back("CalibHeader");
	pcksNames.push_back("CalibTrailer");
	pcksNames.push_back("InitHeader");
	pcksNames.push_back("InitTrailer");
	pcksNames.push_back("EventTrk");
	pcksNames.push_back("Log");
	pcksNames.push_back("VarDump");
	pcksNames.push_back("ArrDump");
	pcksNames.push_back("TabDump");
	pcksNames.push_back("Tmtc");
	pcksNames.push_back("Mcmd");
	pcksNames.push_back("ForcedFECmd");
	pcksNames.push_back("Ac1Init");
	pcksNames.push_back("CalInit");
	pcksNames.push_back("TrkInit");
	pcksNames.push_back("TofInit");
	pcksNames.push_back("TrgInit");
	pcksNames.push_back("NdInit");
	pcksNames.push_back("S4Init");
	pcksNames.push_back("Ac2Init");
	pcksNames.push_back("CalAlarm");
	pcksNames.push_back("Ac1Alarm");
	pcksNames.push_back("TrkAlarm");
	pcksNames.push_back("TrgAlarm");
	pcksNames.push_back("TofAlarm");
	pcksNames.push_back("S4Alarm");
	pcksNames.push_back("Ac2Alarm");	    	
	pcksNames.push_back("TsbT");
	pcksNames.push_back("TsbB");
    };
    //
    // Functions
    //
    void HandleRun();
    void HandleRunFragments(Bool_t mishead, Bool_t mistrail, UInt_t firstev, UInt_t lastev);
    void HandleMissingHoT(Bool_t mishead, Bool_t mistrail, UInt_t firstev, UInt_t lastev);
    void HandleSuspiciousRun();
    void FillClass();
    void FillClass(Bool_t mishead, Bool_t mistrail, Int_t firstev, Int_t lastev);
    void HandleTRK_CALIB(Bool_t pk1, Bool_t pk2);
    void HandleTRK_CALIB(GL_TRK_CALIB*);
    //
    void RemoveCALIBS();
    void ValidationOFF();
    void ReArrangeRUNS();
    void RemoveRUNS();
    void RemoveFILES(UInt_t idtsy);
    //
    Bool_t IsDebug(){return(debug);};
    Bool_t IsRunAlreadyInserted();
    Bool_t IsRunConsistent(Bool_t mishead, Bool_t mistrail, UInt_t &firstev, UInt_t &lastev);
    Bool_t AutoBoot(){return(AUTOBOOT);};
    //
    Bool_t MissingTRK_CALIB(UInt_t t1,UInt_t t2);
    //
    Long64_t PKT(UInt_t pkt_num);
    //
    Long64_t OBT(UInt_t obt);
    //
    UInt_t AssignRunID();

    // GL_TLE related functions
    int insertTle(cTle*);
    bool isTlePresent(cTle*);

 public: 
    //
    PamelaDBOperations(TString host, TString user, TString password, TString filerawname, TString filerootname, UInt_t boot, UInt_t tsync, UInt_t obt0, Bool_t debug, TString tlefilename,UInt_t dwinput, Bool_t staticp, Bool_t gpamela, Bool_t keepenv); // constructor
    //
    void Close(); // destructor
    //
    //
    // Setters
    //
    void SetConnection(TString host, TString user, TString password);
    void SetBOOTnumber(UInt_t boot);
    void SetBOOTnumber(UInt_t boot, Bool_t gpamela);
    void SetRawName(TString str);
    void SetRootName(TString str);
    void SetDebugFlag(Bool_t debug);
    void SetID_RAW(UInt_t idr);
    void SetID_ROOT(UInt_t idr);
    void SetTsync(UInt_t ts);
    void SetTsync(UInt_t ts, Bool_t gpamela);
    void SetObt0(UInt_t ts); 
    void SetCommonGLRUN(UInt_t absth, UInt_t abstt);
    void SetNOBOOT(Bool_t noboot);
    void SetOlderThan(Long64_t oldthan);
    void SetTLEPath(TString str);
    void SetOrbitNo(UInt_t dwinput);
    void SetNoFrag(Bool_t nf);
    void SetAutoBoot(Bool_t nf);
    void SetPedantic(Bool_t pd);
    void SetPhysEndRunVariables();
    //
    void SetTag(TString ntag){tag=ntag;};
    //
    Bool_t SetID_RAW();
    //
    Int_t SetUpperLimits();
    void OpenL0File(TString filerootname);
    //
    // Getters
    //
    Bool_t GetNOBOOT(){return(NOBOOT);};
    //
    UInt_t GetID_RAW(){return(id);};     
    UInt_t GetID_ROOT(){return(idroot);};
    UInt_t GetBOOTnumber(){return(BOOTNO);};
    //
    UInt_t GetAbsTime(UInt_t obt);
    UInt_t GetTsync(){return(tsync);};
    //
    const PacketType* GetPacketType(const char* type);
    //
    TString GetRawFile(){return((TString)gSystem->BaseName(filerawname.Data()));};
    TString GetRootFile(){return((TString)gSystem->BaseName(filerootname.Data()));};
    TString GetRootName(){return((TString)gSystem->ExpandPathName(filerootname.Data()));};
    TString GetRawName(){return(filerawname);};
    TString GetRawPath();
    TString GetRootPath();
	
    const char*  GetCleanTime(){return clean_time->AsSQLString();};
    //
    // Functions
    //
    Int_t assignBOOT_NUMBER();
    Int_t insertPamelaRootFile();
    Int_t insertPamelaRootFile(GL_ROOT*);
    Int_t insertPamelaRawFile();
    Int_t insertPamelaRawFile(GL_RAW*);
    Int_t insertPamelaGL_TIMESYNC(); 
    Int_t insertPamelaRUN(); 
    Int_t insertCALO_CALIB(); 
    Int_t insertCALOPULSE_CALIB(); 
    Int_t insertTRK_CALIB(); 
    Int_t insertS4_CALIB(); 
    Int_t CleanGL_RUN_FRAGMENTS();
    Int_t CleanGL_RUN_FRAGMENTS(TString fcleanfile);
    Int_t CleanGL_RUN_FRAGMENTS(TString fcleanfile, Bool_t runpieces);
    Int_t CleanGL_RUN_FRAGMENTS(Bool_t runpieces);
    Int_t ValidateRuns();
    Int_t ValidateRuns(TString valfile);
    Int_t assignVALIDATION(UInt_t ,Bool_t );
    Int_t removeFile(TString rootfilename);
    //
    Bool_t IsChewbacca(){return chewbacca;};
    //    void OpenFile();
    void CheckValidate(Long64_t olderthan);
    void CheckConnection();
    void CheckFile();
    //
    void LockTables();
    void UnLockTables();
    //
	
    Bool_t NoFrag(){return(NOFRAG);};
    Bool_t InsertRoot(){return(INSERT_ROOT);};
    Bool_t InsertRaw(){return(INSERT_RAW);};
    Bool_t Validate(){return(VALIDATE);};

    // Functions for TLE
    Int_t populateTLE();

    UInt_t ValidateTrkCalib( CalibTrk1Event* calibtrk , EventHeader* h, TFile* file);
    UInt_t ValidateTrkCalib( CalibTrk2Event* calibtrk , EventHeader* h, TFile* file){return ValidateTrkCalib((CalibTrk1Event*)calibtrk,h,file); };

    UInt_t ValidateTrkCalib( CalibTrk1Event* calibtrk , EventHeader* h){return ValidateTrkCalib((CalibTrk1Event*)calibtrk,h,file); };
    UInt_t ValidateTrkCalib( CalibTrk2Event* calibtrk , EventHeader* h){return ValidateTrkCalib((CalibTrk1Event*)calibtrk,h,file); };

    UInt_t Check();
    UInt_t Check(UInt_t from, UInt_t to);
	
};
#endif /* PAMELA_DB_OPERATIONS_H */