#pragma ident "$Id: Rinex3ClockData.hpp 3140 2012-06-18 15:03:02Z susancummins $"

/**
 * @file Rinex3Clockdata.hpp
 * Encapsulate RINEX3 clock data file, including I/O
 * See more at: ftp://igscb.jpl.nasa.gov/pub/data/format/rinex_clock.txt
 */

#ifndef GPSTK_RINEX3CLOCKDATA_HPP
#define GPSTK_RINEX3CLOCKDATA_HPP

//============================================================================
//
//  This file is part of GPSTk, the GPS Toolkit.
//
//  The GPSTk is free software; you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published
//  by the Free Software Foundation; either version 2.1 of the License, or
//  any later version.
//
//  The GPSTk is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with GPSTk; if not, write to the Free Software Foundation,
//  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
//
//  Octavian Andrei - FGI ( http://www.fgi.fi ). 2008
//
//============================================================================

//system
#include<map>
//GPSTk
#include "CommonTime.hpp"
#include "FFStream.hpp"
#include "Rinex3ClockBase.hpp"
#include "Rinex3ClockHeader.hpp"
#include "RinexSatID.hpp"

namespace gpstk
{
      /** @addtogroup Rinex3Clock */
      //@{

      /** This class models a RINEX3 clock data file.
       *
       * @sa gpstk::Rinex3ClockData and gpstk::Rinex3ClockStream.
       * @sa rinex_clk_test.cpp and rinex_clk_read_write.cpp for examples.
       */
   class Rinex3ClockData : public Rinex3ClockBase
   {
   public:

         /// A simple constructor
      Rinex3ClockData(): time(gpstk::CommonTime::BEGINNING_OF_TIME){}


         /// Destructor
      virtual ~Rinex3ClockData() {}

         ///< clock data type
      std::string type;
         ///< receiver or satellite name for which data are given
      std::string name;
         ///< the corresponding time to the clock data record
      CommonTime time;
         /// number of data values
      size_t numVal;
         ///< clock data
         ///< 0: clock bias (seconds).
         ///< 1: clock bias sigma[optional] (seconds).
         ///< 2: clock rate [optional] (dimensionless).
         ///< 3: clock rate sigma [optional] (dimensionless).
         ///< 4: clock acceleration [optional] (per second).
         ///< 5: clock acceleration sigma [optional] (per second).
      double data[6];

         // The next four lines is our common interface
         /// RinexObsData is a "data", so this function always returns true.
      virtual bool isData() const {return true;}

         /**
          * A Debug output function.
          * Dumps the time of observations and the IDs of the Sats
          * in the map.
          */
      virtual void dump(std::ostream& s) const;

   protected:
         /**
          * Writes a correctly formatted record from this data to stream \a s.
          * When printing comment records, you'll need to format them correctly
          * yourself.  This means making sure that "COMMENT" is at the end
          * of the line and that they're the correct length (<= 80 chrs).
          * Also make sure to correctly set the epochFlag to the correct
          * number for the type of header data you want to write.
          */
      virtual void reallyPutRecord(FFStream& s) const 
         throw(std::exception, FFStreamError,
               gpstk::StringUtils::StringException);
  
         /**
          * This functions obtains a RINEX Observation record from the given 
          * FFStream.
          * If there is an error in reading from the stream, it is reset
          * to its original position and its fail-bit is set.
          * Because of the Rinex Obs format, a RinexObsData record returned
          * might not have data in it.  Check the RinexSatMap for empty()
          * before using any data in it.
          * @throws StringException when a StringUtils function fails
          * @throws FFStreamError when exceptions(failbit) is set and
          *  a read or formatting error occurs.  This also resets the
          *  stream to its pre-read position.
          */
      virtual void reallyGetRecord(FFStream& s) 
         throw(std::exception, FFStreamError,
               gpstk::StringUtils::StringException);

   private:
         /// Writes the CommonTime object into RINEX format. If it's a bad time,
         /// it will return blanks.
      std::string writeTime(const CommonTime& dt) const
         throw(gpstk::StringUtils::StringException);

         /** This function constructs a CommonTime object from the given parameters.
          * @param line       the encoded time string found in the 
          *                   RINEX clock data record.
          */
      CommonTime parseTime(const std::string& line) const;

   }; // End of class Rinex3ClockData

      //@}

}  // End of namespace gpstk

#endif   // GPSTK_RINEX3CLOCKDATA_HPP
