#pragma once

namespace inertia
{

/** Available configuration types */
enum ConfigType : unsigned {
	CONFIG_RADIO = 0,       ///< Radio Configuration, see RadioConfig
	CONFIG_GLOBAL_SAMPLING, ///< Global Sampling Configuration, see GlobalSamplingConfig
	CONFIG_ACCEL,           ///< Acceleration Configuration, see AccelConfig
	CONFIG_COMPASS,         ///< Compass Configuration, see CompassConfig
	CONFIG_TRIPLE_AXIS,     ///< Triple Axis Configuration, see TripleAxisConfig
	CONFIG_STATUS,          ///< Status Configuration, see StatusConfig
	CONFIG_HEARTBEAT,       ///< Heartbeat Configuration, see HeartBeatConfig
	CONFIG_TEMPERATURE,     ///< Temperature Configuration, see TemperatureConfig
	CONFIG_CORR,            ///< Correlation Configuration, see CorrelationConfig
	CONFIG_LOGGING,         ///< Logging Configuration, see LoggingConfig
	CONFIG_IMA,             ///< IMA Configuration, see IMAConfig
	CONFIG_RTC,             ///< RTC Configuration, see RTCConfig
	CONFIG_SINGLE_AXIS,     ///< Single Axis Configuration, see SingleAxisConfig
	CONFIG_GYRO,            ///< Gyroscope Configuration, see GyroConfig
	CONFIG_QUAD_AXIS,       ///< Quad Axis Configuration, see QuadAxisConfig
	CONFIG_ADC,             ///< ADC Configuration, see ADCConfig
	CONFIG_DETECTION,       ///< Detection Configuration, see DetectionConfig
	CONFIG_ADC2,            ///< ADC2 Configuration, see ADC2Config
	CONFIG_ACCEL_EXT,       ///< Extended Acceleration Configuration, see AccelConfigExt
	CONFIG_COMPASS_EXT,     ///< Extended Compass Configuration, not used
	CONFIG_DUAL_AXIS,       ///< Dual Axis Configuration, see DualAxisConfig
	CONFIG_VMON_BOARD,      ///< V-Mon Board Configuration, see VmonBoardConfig
	CONFIG_OTHER_AXIS,      ///< Other Axis Configuration, see OtherAxisConfig
	CONFIG_LAST,            ///< Valid sensor configurations before this
	CONFIG_CUSTOM,          ///< Custom Configuration
	CONFIG_IGNORE = 0xff    ///< Ignore Configuration
};


/** Channel data types for custom configuration */
enum ChannelDataType {
	CHANNEL_SIGNED = 0,     ///< Signed
	CHANNEL_UNSIGNED = 1,   ///< Unsigned
	CHANNEL_FIXEDPOINT = 2  ///< Fixed floating point
};


/** Data Channel */
struct INERTIA_API Channel
{
	uint8_t wordSize;
	unsigned nValues;
	ConfigType configType; // type of config, independent of channel
	uint8_t instanceMask; // instanceMask bitfield (0 when not used)
	uint8_t sensorID; // sensorID (e.g. accel or gyro for TripleAxisConfig), or group (for ADC2Config)
	uint8_t disabledAxes; // mask to indicate which axes are disabled
	uint32_t modulo; // can be set for custom channels
	uint8_t sensorResolution;

	ChannelDataType dataType;
	unsigned fixedPointQ;
	std::vector<double> conversionFactors;

	Channel(uint8_t const _wordSize = 16, unsigned const _nValues = 0, ConfigType const _configType = CONFIG_IGNORE,
		uint8_t const _instanceMask = 0, uint8_t const _sensorID = 0, uint8_t const disabledAxes = 0);
	Channel(std::wstring const& argString);

	bool operator== (Channel const& rhs) const;

#ifdef WITH_BOOST_PROGRAM_OPTIONS
	static const po::options_description GetOptionDescription();
#endif

	int Size() const;
	const std::wstring ToString() const;
};

}
