#pragma once

#include "data/config/GenericConfig.h"

namespace inertia
{

/** ADCDescriptorType */
enum ADCDescriptorType
{
	ADC_DESCRIPTOR_GROUP = 0,
	ADC_DESCRIPTOR_INPUT = 1
};

/** ADCInputMode */
enum ADCInputMode {
	MODE_SINGLE_ENDED = 0,
	MODE_DIFFERENTIAL,
	MODE_DIGITAL
};


struct INERTIA_API ADCGroupDescriptor
{
	ADCDescriptorType type;
	bool enableSampling;
	bool enableTransmit;
	bool enableLogging;
	bool adoptMod;
	uint8_t samplingChannel;
	uint16_t mod;
	uint8_t wordSize;
	uint16_t reserved;

	ADCGroupDescriptor();
	ADCGroupDescriptor(uint8_t const* in);
	ADCGroupDescriptor(std::wstring const& argString);

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

	void GetBytes(std::vector<uint8_t>& out) const;
	const std::wstring ToString() const;
	const std::wstring ToSimpleString(uint16_t const globalRate) const;
};


struct INERTIA_API ADCInputDescriptor
{
	ADCDescriptorType type;
	uint8_t samplingChannel;
	uint8_t channelPosition; // position in channel
	uint8_t inputADCIndex;
	int32_t offset;
	float scale;
	ADCInputMode mode;
	uint32_t reserved;
	bool adoptOffset, adoptScale;

	ADCInputDescriptor();
	ADCInputDescriptor(uint8_t const* in);
	ADCInputDescriptor(std::wstring const& argString);

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

	void GetBytes(std::vector<uint8_t>& out) const;
	const std::wstring ToString() const;
	const std::wstring ToSimpleString() const;
};


struct INERTIA_API ADC2Config
	: GenericConfig
{
	std::vector<ADCGroupDescriptor> groups;
	std::vector<ADCInputDescriptor> inputs;

	ADC2Config();
	ADC2Config(uint8_t const* in);
	ADC2Config(std::wstring const& argString);

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

	void GetBytes(std::vector<uint8_t>& out) const override;
	ConfigType GetConfigType() const override;
	const std::wstring ToString() const override;
	const ChannelMap GetChannelMap() const;
};

}
