#pragma once

namespace inertia
{

/** Default baudrate */
#define DEFAULT_BAUDRATE 460800


/** Types of Flow Control */
enum FlowControl : unsigned {
	FLOW_CONTROL_NONE = 0,    ///< No flow control.
	FLOW_CONTROL_HARDWARE = 1 ///< Hardware flow control.
};


/** Serial Protocol Versions */
enum ProtocolVersion : int {
	PROTOCOL_NONE = -1,            ///< Unspecified protocol version.
	PROTOCOL_V0 = 0,               ///< Protocol version 0 (obsolete).
	PROTOCOL_V1 = 1,               ///< Protocol version 1 (obsolete).
	PROTOCOL_V2 = 2,               ///< Protocol version 2 (obsolete).
	PROTOCOL_V3 = 3,               ///< Protocol version 3.
	PROTOCOL_V4 = 4,               ///< Protocol version 4.
	PROTOCOL_FIRST = PROTOCOL_V3,  ///< First supported protocol version.
	PROTOCOL_LAST = PROTOCOL_V4    ///< Last supported protocol version.
};


/** @brief Serial Settings
 *
 *  Class containing settings for serial port connection.
 */
struct INERTIA_API SerialSettings
{
	std::wstring portname;                 ///< The unique port identifier of the connection.
	unsigned baudrate;                     ///< The baudrate to use. Because serial-over-usb is used, this will generally not matter.
	FlowControl flowControl;               ///< Type of flow control to use. Because serial-over-usb is used, this will generally not matter.
	std::wstring devicename;               ///< An optional device name to simplify identifying a device.
	ProtocolVersion forcedProtocolVersion; ///< USe this protocol version instead of the version indicated by the device.

	/** Default constructor.
	 *  Without a port SerialSettings will be invalid.
	 */
	SerialSettings();

	/** Constructor with individual arguments.
	 *  @param portname the portname
	 *  @param baudrate the baudrate
	 *  @param flow_control the flow_control
	 *  @param devicename the devicename
	 *  @param forcedProtocolVersion the forcedProtocolVersion
	 */
	SerialSettings(std::wstring const& portname, const unsigned baudrate, const FlowControl flow_control = FLOW_CONTROL_HARDWARE,
		std::wstring const& devicename = std::wstring(), const ProtocolVersion forcedProtocolVersion = PROTOCOL_NONE);

	/** Constructor with string argument.
	 *  Creates SerialSettings from a string.
	 *  @param argString string with arguments
	 */
	SerialSettings(std::wstring const& argString);

#ifdef WITH_BOOST_PROGRAM_OPTIONS
	/** Get the possible command-line arguments for SerialSettings.
	 *  Only available when \a WITH_BOOST_PROGRAM_OPTIONS is defined.
	 *  @return the option description
	 */
	static const po::options_description GetOptionDescription();
#endif

	/** Get a string representation of this SerialSettings.
	 *  The string is compatible with GetOptionDescription() and SerialSettings(std::wstring const&).
	 *  @return the string
	 */
	std::wstring const ToString() const;
};

}
