//============================================================================
//
//  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 BLQDataReader.hpp
 * File stream for ocean tides harmonics data in BLQ file format.
 */

#ifndef GPSTK_BLQDATAREADER_HPP
#define GPSTK_BLQDATAREADER_HPP

#include <string>
#include <map>

#include "FFTextStream.hpp"
#include "StringUtils.hpp"
#include "Matrix.hpp"


namespace gpstk
{
      /// @ingroup formattedfile 
      //@{

      /** This is a class to read and parse ocean tides harmonics data
       *  in BLQ file format.
       *
       * Ocean loading displacement models usually use the ocean tide
       * harmonics in order to compute station biases due to this effect.
       *
       * A common format to encode such information is the so-called BLQ
       * format, where each station name is associated to a matrix with
       * 11 columns (corresponding to the most important harmonics) and
       * six rows: Three for amplitudes (radial, west, south), and three
       * for phases (radial, west, south).
       *
       * You may find this data using the "Ocean tide loading provider" at:
       *
       * http://www.oso.chalmers.se/~loading/
       *
       * A typical way to use this class follows:
       *
       * @code
       *   BLQDataReader blqread;
       *
       *   blqread.open("EBRE.GOT00.2");
       *
       *   Matrix<double> tides(6,11,0.0);
       *
       *   tides = blqread.getTideHarmonics("EBRE");
       * @endcode
       *
       * The eleven tide harmonics used are:
       *
       * - M2:  Principal lunar semidiurnal
       * - S2:  Principal solar semidiurnal
       * - N2:  Larger lunar elliptic semidiurnal
       * - K2:  Lunisolar semidiurnal
       * - K1:  Lunar diurnal
       * - O1:  Lunar diurnal
       * - P1:  Solar diurnal
       * - Q1:  Larger lunar elliptic diurnal
       * - MF:  Lunisolar fortnightly
       * - MM:  Lunar monthly
       * - SSA: Solar semiannual
       *
       * @warning Be aware that you may select several different tide models
       * to generate tide harmonics. It is advised to use the latest
       * models such as GOT00.2, FES99, TPXO.6.2, etc.
       */
   class BLQDataReader : public FFTextStream
   {
   public:

         /// Default constructor
      BLQDataReader()
      {};

         /** Common constructor. It will always open file a for read and will
          *  load ocean tide harmonics data in one pass.
          *
          * @param fn   BLQ data file to read
          *
          */
      BLQDataReader(const char* fn)
         : FFTextStream(fn, std::ios::in)
      { loadData(); };


         /** Common constructor. It will always open file for read and will
          *  load ocean tide harmonics data in one pass.
          *
          * @param fn   BLQ data file to read
          *
          */
      BLQDataReader(const std::string& fn)
         : FFTextStream(fn.c_str(), std::ios::in)
      { loadData(); };

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Woverloaded-virtual"
         /// Method to open AND load ocean tide harmonics data file. It doesn't
         /// clear data previously loaded.
      virtual void open(const char* fn);


         /// Method to open AND load ocean tide harmonics data file. It doesn't
         /// clear data previously loaded.
      virtual void open(const std::string& fn);

#pragma clang diagnostic pop
         /// Method to clear all previously loaded ocean tide harmonics data.
      virtual BLQDataReader& clearData()
      { OceanTidesData.clear(); return (*this); };


         /** Method to get the ocean tide harmonics corresponding to a
          *  given station.
          *
          * @param station   Station name (case is NOT relevant).
          *
          * @return A Matrix<double> of siw rows and eleven columns
          * containing tide harmonics M2, S2, N2, K2, K1, O1, P1, Q1, MF,
          * MM and SSA for amplitudes (radial, west, south, in meters) and
          * phases (radial, west, south, in degrees). If station is 
          * not found, this method will return a matrix full of zeros.
          */
      virtual Matrix<double> getTideHarmonics(const std::string& station);


         /// Destructor
      virtual ~BLQDataReader() {};


   private:


         /// A structure used to store ocean tide harmonics data.
      struct tideData
      {
            // Default constructor initializing the data in the structure
         tideData() : harmonics(6,11,0.0) {};

         Matrix<double> harmonics;   ///< Tide harmonics data
      };


         /// Handy iterator type
      typedef std::map<std::string, tideData>::const_iterator tideDataIt;


         /// Map holding the information regarding ocean tide harmonics
      std::map<std::string, tideData> OceanTidesData;


         /** Method to store ocean tide harmonics data in this class'
          *  data map
          *
          * @param stationName String holding station name.
          * @param data        tideData structure holding the harmonics data
          */
      void setData( const std::string& stationName,
                    const tideData& data )
      { OceanTidesData.insert(make_pair(stationName, data)); };


         /// Method to store ocean tide harmonics data in this class' data map
      virtual void loadData(void)
         throw( FFStreamError, gpstk::StringUtils::StringException );


   }; // End of class 'BLQDataReader'


      //@}

}  // End of namespace gpstk

#endif  // GPSTK_BLQDATAREADER_HPP
