#pragma once

#include "dll/SerialSettings.h"
#include "dll/EthernetSettings.h"
#include "dll/ExternalConnSettings.h"
#include "dll/BLEConnSettings.h"

namespace inertia
{

/** Available connection types. */
enum ConnectionType : unsigned {
	CONNECTION_USB_SERIAL = 0, ///< USB Serial Connection, see SerialSettings.
	CONNECTION_ETHERNET = 1,   ///< Ethernet Connection, see EthernetSettings
	CONNECTION_EXTERNAL = 2,   ///< External Connection, see ExternalConnSettings.
	CONNECTION_BLE = 3,        ///< Bluetooth Low Energy, see BLEConnSettings.
	CONNECTION_UNKNOWN = 4
};


/** @brief Connection Settings
 *
 *  Class containing settings for a connection with an Inertia device.
 */
struct INERTIA_API ConnectionSettings
{
private:
	std::wstring connectionName;
	mutable ConnectionType connectionType;

public:
	bool reliableUnrouted;       ///< Use the reliability protocol when sending data to unrouted devices (directly connected to a PC).
	bool logThread;              ///< When logging data of this connection, do this in a separate thread.
	unsigned sourceID;           ///< The ID to identify in the network, like gateway and nodeIDs.
	unsigned maxDataBuffer;      ///< Maximum number of samples to buffer.
	std::wstring lastOpenedTime; ///< The last time the connection was (tried to) opened. Can be set by the user, it has no function inside the library.
	unsigned paddingMultiple;    ///< When writing raw data, pad the bytes with '0' to a multiple of this value.
	unsigned reconnectInterval;  ///< Interval in seconds after which to automatically try to reconnect after an error, 0 to disable.
	bool reconnectFirst;         ///< Use the reconnectInterval when first opening the connection (default false).
	unsigned keepAliveInterval;  ///< Interval in seconds for broadcasting a ping-message, 0 to disable.

	SerialSettings serialSettings;             ///< Use a Serial USB Connection, see SerialSettings.
	EthernetSettings ethernetSettings;         ///< Use an Ethernet Connection, see EthernetSettings.
	ExternalConnSettings externalConnSettings; ///< Use an External Connection, see ExternalConnSettings.
	BLEConnSettings bleConnSettings;           ///< Use and Bluetooth LE Connection, see BLEConnSettings.

	/** Default constructor.
	 */
	ConnectionSettings();

	/** Constructor with connection name and type.
	 *  @param name the name of the connection
	 *  @param connType the ConnectionType
	 */
	ConnectionSettings(std::wstring const& name, ConnectionType const connType);

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

	/** Get the name of the connection.
	 *  @return the name
	 */
	const std::wstring GetName() const;

	/** Get the type of the connection.
	 *  @return the type
	 */
	ConnectionType GetConnectionType() const;

#ifdef WITH_BOOST_PROGRAM_OPTIONS
	/** Get the possible command-line arguments for ConnectionSettings.
	 *  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 ConnectionSettings.
	 *  The string is compatible with GetOptionDescription() and ConnectionSettings(std::wstring const&).
	 *  @return the string
	 */
	const std::wstring ToString() const;
};

}
