#pragma once

#include "data/config/SensorSpecificSettings.h"
#include "data/config/SamplerConfig.h"

namespace inertia
{

/** GPSSampleSize */
enum GPSSampleSize {
	GPS_SAMPLE_SIZE_VALID = 1,
	GPS_SAMPLE_SIZE_UTC_DATE_TIME = 8,
	GPS_SAMPLE_SIZE_LAT_LON = 8,
	GPS_SAMPLE_SIZE_ALT_ELLIPSOID = 4,
	GPS_SAMPLE_SIZE_ALT_MSL = 4,
	GPS_SAMPLE_SIZE_SOG = 2,
	GPS_SAMPLE_SIZE_COG = 2,
	GPS_SAMPLE_SIZE_SVS_IN_FIX = 1,
	GPS_SAMPLE_SIZE_HDOP = 1,
	GPS_SAMPLE_SIZE_EHPE = 4,
	GPS_SAMPLE_SIZE_EVPE = 4,
	GPS_SAMPLE_SIZE_ETE = 4,
	GPS_SAMPLE_SIZE_EHVE = 2,
	GPS_SAMPLE_SIZE_ELNPE = 4,
	GPS_SAMPLE_SIZE_ELTPE = 4
};


/** GPSConfigVersion */
enum GPSConfigVersion {
	GPS_V0 = 0,
	GPS_V1,
	GPS_V2,
	GPS_V3
};


/** GPSType */
enum GPSType {
	GPS_ORG1410 = 0,
	GPS_ORG1510,
	GPS_UBLOX_CAMM8Q,
	GPS_DETECTING = 0xFF
};


struct INERTIA_API GPSConfiguration
	: SpecificSensorSettings
	, SamplerConfig
{
	GPSConfigVersion gpsVersion;
	GPSType gpsType;

	int32_t onTime;
	uint32_t maxOffTime;
	uint32_t maxSearchTime;
	int16_t elevationMask;
	uint8_t powerMask;
	uint32_t pushToFixPeriod;

	bool enableAdaptiveTricklePower;
	bool enablePushToFix;
	bool enableStaticNavigation;
	bool enableTrackSmoothing;

	bool enableSystemGPS;
	bool enableSystemGlonass;
	bool enableSystemGalileo;
	bool enableSystemBeidou;

	bool enableUTC;
	bool enableLatLon;
	bool enableAltEllipsoid;
	bool enableAltMSL;
	bool enableSOG;
	bool enableCOG;
	bool enableSvsInFix;
	bool enableHDOP;

	bool enableEHPE;
	bool enableEVPE;
	bool enableETE;
	bool enableEHVE;

	GPSConfiguration();
	GPSConfiguration(uint8_t const* in, const unsigned offset, const unsigned _length);
	GPSConfiguration(std::wstring const& argString);

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

	void GetBytes(std::vector<uint8_t>& out, const size_t bitfieldOffset) const override;
	const std::pair<unsigned, Channel> GetChannel() const override;
	const std::wstring ToString() const override;
	const std::wstring ToSimpleString(uint16_t const globalRate) const;
	double GetRangeFactor() const override;
	unsigned GetResolution() const override;
	unsigned GetMaxRate() const override;
};

}
