/* +---------------------------------------------------------------------------+
   |          The Mobile Robot Programming Toolkit (MRPT) C++ library          |
   |                                                                           |
   |                   http://mrpt.sourceforge.net/                            |
   |                                                                           |
   |   Copyright (C) 2005-2008  University of Malaga                           |
   |                                                                           |
   |    This software was written by the Perception and Robotics               |
   |      research group, University of Malaga (Spain).                        |
   |    Contact: Jose-Luis Blanco  <jlblanco@ctima.uma.es>                     |
   |                                                                           |
   |  This file is part of the MRPT project.                                   |
   |                                                                           |
   |     MRPT is free software: you can redistribute it and/or modify          |
   |     it under the terms of the GNU General Public License as published by  |
   |     the Free Software Foundation, either version 3 of the License, or     |
   |     (at your option) any later version.                                   |
   |                                                                           |
   |   MRPT 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 General Public License for more details.                          |
   |                                                                           |
   |     You should have received a copy of the GNU General Public License     |
   |     along with MRPT.  If not, see <http://www.gnu.org/licenses/>.         |
   |                                                                           |
   +---------------------------------------------------------------------------+ */

#ifndef CGPSInterface_H
#define CGPSInterface_H

#include <MRPT/MRML/CObservationGPS.h>
#include <lib_hwdrivers/CSerialPort.h>
#include <MRPT/UTILS/CDebugOutputCapable.h>

namespace MRML {}
class MRML::CObservationGPS;

namespace HWDRIVERS
{
	/** A parser of NMEA commands, for connecting to a GPS by a serial port.
	  *  VERSIONS HISTORY:
	  *		-9/JUN/2006: First version (JLBC)
	*/
	class CGPSInterface : public UTILS::CDebugOutputCapable
	{
	public:
		/** Constructor
		*  \param serialPortName The name of a valid serial port (See HWDRIVERS::CSerialPort for more details).
		*  \param COM_baudrate The baudrate of the communications (typ. 4800 bauds)
		*  \param BUFFER_LENGTH The size of the communications buffer (default value should be fine always)
		*/
		CGPSInterface(
			const std::string serialPortName,
			int			COM_baudrate = 4800,
			int			BUFFER_LENGTH = 500);

		/** Destructor
		  */
		~CGPSInterface();

		/** This method should be called periodically (at least at 1Hz to capture ALL the real-time data)
		*  It is thread safe, i.e. you can call this from one thread, then to other methods from other threads.
		*  This method processes data from the GPS and update the object state accordingly.
		*/
		void  doProcess();

		/** Returns true if communications work.
		*/
		bool  isGPS_connected();

		/** Returns true if the last message from the GPS indicates that the signal from sats has been acquired.
		*/
		bool  isGPS_signalAcquired();

		/** Returns the last GPS datum if available, true if OK, false on error or no new data available.
		 * Notice that one or more of the GPS data messages may be filled out in the returned object.
		 * However, remember that the user calling this method MUST set the "sensorPose" field.
		 */
		void  getLastData(
			bool					&out_thereIsData,
			MRML::CObservationGPS	&out_data
			);

	private:
		/* This will be NULL on any error opening the com port:
		*/
		CSerialPort		*m_COM;
		std::string 	m_COMname;
		int				m_COMbauds;
		bool			m_GPS_comsWork;
		bool			m_GPS_signalAcquired;
		int				m_BUFFER_LENGTH;

		char			*m_buffer;
		size_t			m_bufferLength;
		size_t			m_bufferWritePos;

		/** Returns true if the COM port is already open, or try to open it in other case.
		  * \return true if everything goes OK, or false if there are problems opening the port.
		  */
		bool  tryToOpenTheCOM();

		/** Process data in "m_buffer" to extract GPS messages, and remove them from the buffer.
		  */
		void  processBuffer();

		/** Process a complete string from the GPS:
		  */
		void  processGPSstring( const std::string &s);

		/** Tokenize a string "str" into commas separated tokens
		  */
		void  getNextToken(
			const std::string	&str,
			std::string			&token,
			unsigned int		&parserPos);

		/* A private copy of the last received gps datum:
		 */
		MRML::CObservationGPS	m_latestGPS_data;

	}; // end class

} // end namespace

#endif
