#pragma once

#include "data/config/InertialConfig.h"

namespace inertia
{

/** AccelType */
enum AccelType {
	ACCEL_LIS3LV02 = 0,
	ACCEL_LIS3DH = 1,
	ACCEL_RESERVED = 2,
	ACCEL_RESERVED2 = 3
};

/** AccelRateLis3LV02 */
enum AccelRateLis3LV02 {
	ACCEL_RATE_40 = 0,
	ACCEL_RATE_160 = 1,
	ACCEL_RATE_640 = 2,
	ACCEL_RATE_2560 = 3
};

/** AccelRateLis3DH */
enum AccelRateLis3DH {
	ACCEL_RATE_DOWN = 0,
	ACCEL_RATE_DOWN_LP = 1,
	ACCEL_RATE_1 = 2,
	ACCEL_RATE_1_LP = 3,
	ACCEL_RATE_10 = 4,
	ACCEL_RATE_10_LP = 5,
	ACCEL_RATE_25 = 6,
	ACCEL_RATE_25_LP = 7,
	ACCEL_RATE_50 = 8,
	ACCEL_RATE_50_LP = 9,
	ACCEL_RATE_100 = 10,
	ACCEL_RATE_100_LP = 11,
	ACCEL_RATE_200 = 12,
	ACCEL_RATE_200_LP = 13,
	ACCEL_RATE_400 = 14,
	ACCEL_RATE_400_LP = 15,
	ACCEL_RATE_RESERVED1 = 16,
	ACCEL_RATE_1600_LP = 17,
	ACCEL_RATE_1250 = 18,
	ACCEL_RATE_5000_LP = 19
};

/** AccelRangeLis3DH */
enum AccelRangeLis3DH {
	ACCEL_RANGE_2G = 0,
	ACCEL_RANGE_4G = 1,
	ACCEL_RANGE_8G = 2,
	ACCEL_RANGE_16G = 3
};


struct INERTIA_API AccelConfig
	: InertialConfig
{
	AccelRateLis3LV02 hardwareRate0;
	AccelRateLis3DH	hardwareRate1;
	bool hardwareScale0; // for Lis3LV02
	AccelRangeLis3DH hardwareScale1; // for Lis3DH
	AccelType hardwareType;

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

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

	static unsigned GetLength();
	void GetBytes(std::vector<uint8_t>& out) const override;
	ConfigType GetConfigType() const override;
	const std::wstring ToString() const override;
	const std::wstring ToSimpleString(uint16_t const globalRate) const;
	double GetRangeFactor() const override;
	uint16_t GetMaxRate() const override;
};

}
