//============================================================================
//
//  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 3.0 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
//  
//  Copyright 2004, The University of Texas at Austin
//
//============================================================================

//============================================================================
//
//This software developed by Applied Research Laboratories at the University of
//Texas at Austin, under contract to an agency or agencies within the U.S. 
//Department of Defense. The U.S. Government retains all rights to use,
//duplicate, distribute, disclose, or release this software. 
//
//Pursuant to DoD Directive 523024 
//
// DISTRIBUTION STATEMENT A: This software has been approved for public 
//                           release, distribution is unlimited.
//
//=============================================================================

/**
 * @file AlmOrbit.hpp
 * Encapsulate almanac data, and compute satellite orbit, etc.
 */

#ifndef GPSTK_ALMORBIT_HPP
#define GPSTK_ALMORBIT_HPP

#include <map>
#include "CommonTime.hpp"
#include "SatID.hpp"
#include "Xvt.hpp"

namespace gpstk
{
      /// @ingroup GNSSEph
      //@{

      /** Encapsulation of almanac SV orbital parameters (page 5,
       * subframes 1-24). */
   class AlmOrbit
   {
   public:
         /// Default constructor, initialize to 0.
      AlmOrbit() throw();

         /// Fill constructor for all fields.
      AlmOrbit(short prn, double aEcc, double ai_offset, double aOMEGAdot,
               double aAhalf, double aOMEGA0, double aw, double aM0,
               double aAF0, double aAF1, long aToa, long axmit_time,
               short aweek, short aSV_health);

      Xvt svXvt(const CommonTime& t) const throw(InvalidRequest);

      short getPRNID() const throw()
      { return PRN; }

         /// returns full week of TRANSMIT TIME
      short getFullWeek() const throw();
      CommonTime getTransmitTime() const throw();
      CommonTime getToaTime() const throw();
      CommonTime getTimestamp() const throw() { return getToaTime(); }
      short getSVHealth() const throw() { return SV_health; }

      void dump(std::ostream& s = std::cout, int verbosity=1) const;

      short getPRN() const;
      double getecc() const;
      double geti_offset() const;
      double getOMEGAdot() const;
      double getAhalf() const;
      double getOMEGA0() const;
      double getw() const;
      double getM0() const;
      double getAF0() const;
      double getAF1() const;
      long   getToaSOW() const;
      long   getxmit_time() const;
      short  getToaWeek() const;

   protected:
      short PRN;              /**< PRN identifier for this SV */
      double ecc;             /**< eccentricity  */
      double i_offset;        /**< i offset from 54 deg. in rads. */
      double OMEGAdot;        /**< Right Ascention rate in rad/sec */
      double Ahalf;           /**< sqrt of semi-major axis in m**1/2 */
      double OMEGA0;          /**< Right Asc. of Ascending node in rads. */
      double w;               /**< arguement of perigee in rads. */
      double M0;              /**< mean anomoly in rads */
      double AF0;             /**< clock model coeff in sec */
      double AF1;             /**< clock model coeff in sec/sec */
      long Toa;               /**< Time of epoch in GPS sec */
      long xmit_time;         /**< Transmission time */
      short week;             /**< week of Toa (full week) */
      short SV_health;        /**< health of SV */

   private:
      friend class EngAlmanac;
   }; // class AlmOrbit

      /// Map from SatID to AlmOrbit.
   typedef std::map<SatID, AlmOrbit> AlmOrbits;

   std::ostream& operator<<(std::ostream& s, const AlmOrbit& ao);

   inline short  AlmOrbit::getPRN() const {return(PRN);}
   inline double AlmOrbit::getecc() const {return(ecc);}
   inline double AlmOrbit::geti_offset() const {return(i_offset);}
   inline double AlmOrbit::getOMEGAdot() const {return(OMEGAdot);}
   inline double AlmOrbit::getAhalf() const {return(Ahalf);}
   inline double AlmOrbit::getOMEGA0() const {return(OMEGA0);}
   inline double AlmOrbit::getw() const {return(w);}
   inline double AlmOrbit::getM0() const {return(M0);}
   inline double AlmOrbit::getAF0() const {return(AF0);}
   inline double AlmOrbit::getAF1() const {return(AF1);}
   inline long   AlmOrbit::getToaSOW() const {return(Toa);}
   inline long   AlmOrbit::getxmit_time() const {return(xmit_time);}
   inline short  AlmOrbit::getToaWeek() const {return(week);}

      //@}

} // namespace

#endif
