#ifndef PPPMAIN_H
#define PPPMAIN_H

#include <sstream>
#include <vector>
#include "RTCM3/ephemeris.h"

namespace BNC {

class t_ephPool;
class t_obsPool;
class t_satObs;
class t_station;
class t_antex;
class t_filter;

class t_pppMain {
 public:
  t_pppMain();                                                      
  ~t_pppMain();                                                     
  void setOptions(const t_pppOpt* opt);                          
  void putGPSEphemeris(const t_ephGPS* eph);                  
  void putGloEphemeris(const t_ephGlo* eph);                  
  void putOrbCorrections(int numCorr, const t_pppOrbCorr* corr); 
  void putClkCorrections(int numCorr, const t_pppClkCorr* corr); 
  void putBiases(int numBiases, const t_pppSatBiases* biases);   
  void processEpoch(int numSatRover, const t_pppSatObs* satObsRover,
                    t_pppOutput* output);                        
  const t_ephPool* ephPool() const {return _ephPool;}
  const t_obsPool* obsPool() const {return _obsPool;}
  const t_antex*   antex() const {return _antex;}
  const t_station* staRover() const {return _staRover;}
  double offGG() const {return _offGG;}

  std::ostringstream* _log; 
  t_options*          _opt; 

 private:
  void initOutput(t_pppOutput* output);
  void finish(t_irc::irc irc);
  void clearObs();
  t_irc::irc prepareObs(int numSat, const t_pppSatObs* satObs,
                        std::vector<t_satObs*>& obsVector, t_time& epoTime);
  t_irc::irc cmpModel(t_station* station, const ColumnVector& xyzc,
                      std::vector<t_satObs*>& obsVector);
  t_irc::irc cmpBancroft(const t_time& epoTime, 
                         std::vector<t_satObs*>& obsVector, 
                         ColumnVector& xyzc, bool print);
  t_irc::irc createDifferences();
  double cmpOffGG(std::vector<t_satObs*>& obsVector);

  t_pppOutput*           _output;
  t_ephPool*             _ephPool;
  t_obsPool*             _obsPool;
  t_time                 _epoTimeRover;
  t_time                 _epoTimeBase;
  t_station*             _staRover;
  t_station*             _staBase;
  t_antex*               _antex;
  t_filter*              _filter;
  double                 _offGG;
  std::vector<t_satObs*> _obsRover;
  std::vector<t_satObs*> _obsBase;

};

}; // namespace BNC

/// Pointer to the main object
extern GPSS::t_pppMain* pppMain;

/// Log stream abbreviation
#define LOG (*pppMain->_log)

/// Options abbreviation
#define OPT (pppMain->_opt)

#endif
