#pragma once

namespace inertia
{

/** Interface for callback writer. */
struct INERTIA_API ExternalConnWriter
	: std::enable_shared_from_this<ExternalConnWriter>
{
	/** Destructor */
	virtual ~ExternalConnWriter();

	/** Override this function to handle writing data to a device.
	 *  @param data the data that needs to be written
	 */
	virtual void Write(std::vector<uint8_t> const& data) = 0;
};


/** Interface for callback reader. */
struct INERTIA_API ExternalConnReader
	: std::enable_shared_from_this<ExternalConnReader>
{
	/** Destructor */
	virtual ~ExternalConnReader();

	/** Call this function with data received from the device.
	 *  @param data the received data
	 */
	virtual void Receive(std::vector<uint8_t> const& data) = 0;
};


/** @brief External Connection Settings
 *
 *  Class containing settings for an external connection.
 */
struct INERTIA_API ExternalConnSettings
{
	std::wstring name; ///< The name of the connection.

	/** Used by the library to write data to external connection.
	 *  Should be created before ExternalConnection is started.
	 *  The library takes ownership and resets pointer once disconnected.
	 *  DO NOT use the writer after a connection has been removed.
	 */
	mutable std::shared_ptr<ExternalConnWriter> writer;

	/** Used by the library to receive data from external connection.
	 *  The reader is created by the library when the connection is created.
	 *  The library has ownership and resets pointer once disconnected.
	 *  DO NOT use the writer after a connection has been removed.
	 */
	mutable std::shared_ptr<ExternalConnReader> reader;

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

	/** Constructor with individual arguments.
	 *  @param name a name for the external connection
	 *  @param writer an ExternalConnWriter
	 */
	ExternalConnSettings(std::wstring const& name, std::shared_ptr<ExternalConnWriter> const& writer);

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

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

}
