/*---------------------------------------------------------------
	FILE: CSerialPort_WIN.h
	USE: See doxygen doc.

   Part of the MRPT Library
   ISA - Universidad de Malaga - http://www.isa.uma.es
  ---------------------------------------------------------------*/

#ifndef CSERIALPORTWIN_H
#define CSERIALPORTWIN_H

#ifndef CSERIALPORT_H
#error Do not include this file directly: Include 'CSerialPort.h' instead!
#endif

#include <MRPT/config.h>
#include <MRPT/UTILS/CStream.h>

namespace HWDRIVERS
{

	/** An definition of a CStream actually representing a serial COM port.
	 * On communication errors (eg. the COM port does not exist, timeouts,...) methods will
	 * raise an exception of the class "std::exception"
	 *
	 *  Versions history:
	 *    - 1/DEC/2005:  First version (JLBC)
	 *    - 20/DEC/2006: Integration into the MRPT framework
	 *
	 */
	class CSerialPort : public CStream
	{
	public:
		/** Constructor
		 * \param COM_portNumber The port to open, i.e. "5" -> "COM5"
		 * \param openNow Whether to try to open the port now. If not selected, the port should be open later with "open()".
		 */
		CSerialPort( int COM_portNumber, bool openNow = true );

		/** Destructor
		*/
		virtual ~CSerialPort();

		/** Open the port. If is already open results in no action.
		* \exception std::exception On communication errors
		*/
		void  open();

		/** Close the port. If is already closed, results in no action.
		*/
		void  close();

		/** Returns if port has been correctly open.
		*/
		bool  isOpen();

		/** Purge tx and rx buffers.
 		  * \exception std::exception On communication errors
 		  */
		void  purgeBuffers();

		/** Changes the configuration of the port.
		*  \param parity  0:No parity, 1:Odd, 2:Even, 3:Mark, 4:Space
		*  \param baudRate The desired baud rate (eg. 9600, 115200,...)
		*  \param bits Bits per word (typ. 8)
		*  \param nStopBits Stop bits (typ. 0)
		* \exception std::exception On communication errors
		*/
		void  setConfig( int baudRate, int parity = 0, int bits = 8, int nStopBits = 0);

		/** Changes the timeouts of the port.
		* \exception std::exception On communication errors
		*/
		void  setTimeouts(
					int		ReadIntervalTimeout,
					int		ReadTotalTimeoutMultiplier,
					int		ReadTotalTimeoutConstant,
					int		WriteTotalTimeoutMultiplier,
					int		WriteTotalTimeoutConstant );


		/** Implements the virtual method responsible for reading from the stream.
		* \exception std::exception On communication errors
		 */
		size_t  Read(void *Buffer, size_t Count);

		/** Implements the virtual method responsible for writing to the stream.
		 *  Write attempts to write up to Count bytes to Buffer, and returns the number of bytes actually written.
		* \exception std::exception On communication errors
		 */
		size_t  Write(const void *Buffer, size_t Count);


		/** Introduces a pure virtual method for moving to a specified position in the streamed resource.
		 *   he Origin parameter indicates how to interpret the Offset parameter. Origin should be one of the following values:
		 *	- sFromBeginning	(Default) Offset is from the beginning of the resource. Seek moves to the position Offset. Offset must be >= 0.
		 *	- sFromCurrent		Offset is from the current position in the resource. Seek moves to Position + Offset.
		 *	- sFromEnd			Offset is from the end of the resource. Offset must be <= 0 to indicate a number of bytes before the end of the file.
		 * \return Seek returns the new value of the Position property.
		 */
		unsigned long  Seek(long Offset, CStream::TSeekOrigin Origin = sFromBeginning)
		{
			MRPT_UNUSED_PARAM(Origin); MRPT_UNUSED_PARAM(Offset);
			THROW_EXCEPTION("Method not applicable to COM port-based CStream!");
		}

		/** Returns the total amount of bytes in the stream.
		 */
		unsigned long  getTotalBytesCount()
		{
			THROW_EXCEPTION("Method not applicable to COM port-based CStream!");
		}

		/** Method for getting the current cursor position, where 0 is the first byte and TotalBytesCount-1 the last one.
		 */
		unsigned long  getPosition()
		{
			THROW_EXCEPTION("Method not applicable to COM port-based CStream!");
		}

	private:
		int			nCOM;
		void		*hCOM;
		int			m_baudRate;

	}; // end of class

} // end of namespace


#endif
