////////////////////////////////////////////////////////////////////
/// \class RAT:ReconstructClocks
///
/// \brief  Reconstruct the 10 and 50MHz clocks from one another
///
/// \author Tanner Kaptanoglu <tannerk@sas.upenn.edu>
///
/// \details Fetch the information about trigger clock jumps as
///          determined by TriggerClockJumpProc and correct any of
///          the clock jumps on the 10 or 50MHz clock. Also check
///          whether the 10MHz clock is working by comparing to the
///          time in the run header. If the difference is more than
///          a couple seconds the clock is probably not working, and we
///          reconstuct the 10MHz clock from the 50MHz clock, and we do
///          not attempt to fix any of the trigger clock jumps.
///
////////////////////////////////////////////////////////////////////

#ifndef __RAT__ReconstructClocks__
#define __RAT__ReconstructClocks__

#include <RAT/Processor.hh>
#include <RAT/DS/Entry.hh>
#include <RAT/DU/TrigBits.hh>

#include <stdint.h>
#include <time.h>

namespace RAT
{
  class ReconstructClocks : public Processor
  {
    public:

      ReconstructClocks();
      virtual ~ReconstructClocks(){};

      virtual void BeginOfRun(DS::Run& run);
      virtual Processor::Result DSEvent(DS::Run&, DS::Entry& ds);
      void CorrectClock(DS::EV& ev); // Correct 10 and 50MHz clocks
      int Check10MHzClock(DS::EV& ev); // Check 10MHz clock is working at first valid GTID

    protected:

      int validGTID; // the first valid GTID in the run
      uint64_t startTime; // Start time in run header
      uint64_t dateTime; // Date in run header
      int eventCount; // Counts events
      int foundRunStart; // Set to 1 after the first valid GTID
      int clockOnline; // Whether 10MHz clock is working
      time_t TZERO; // Time since Jan 1. 2010
      time_t theTime; // The start time of the run (UTC), not corrected for TZERO
      uint64_t runStartTime; // The start time of the run according to run header
      uint64_t currentTime; // The start time of the run according to 10MHz clock
      int correct50MHzClock; // Whether we shoud correct 50MHz clock jumps
      int correct10MHzClock; // Whether we should correct 10MHz clock jumps
      std::vector<uint64_t> clock50; // Keep track of 50MHz clock
      std::vector<uint64_t> clock10; // Keep track of 10MHz clock
      float timeAllowed; // Difference in time allowed between run header and 10MHz clock
      // Information below is detemined by TriggerClockJumpProc and written to ratdb
      std::vector<int> fGTID10MHz; // GTIDs of the 10MHz clock jumps
      std::vector<int> fGTID50MHz; // GTIDs of the 50MHz clock jumps
      std::vector<int> fBadGTID10MHz; // GTIDs associated with clock jumps that could not be corrected
      std::vector<int> fBadGTID50MHz; // GTIDs associated with clock jumps that could not be corrected
      std::vector<double> fDeltaTicks10MHz; // Size of the 10MHz clock jumps in clock ticks
      std::vector<double> fDeltaTicks50MHz; // Size of the 50MHz clock jumps in clock ticks
  };
}//namespace RAT
#endif