#pragma once

namespace inertia
{
enum ConfigType : unsigned;

/** @brief Calibration Results
 *
 *  Class containing calibration results.
 */
struct INERTIA_API CalibrationResults
{
	ConfigType configType; ///< The configuration type these results apply to.
	unsigned sensorID;     ///< The sensorID these results apply to, or -1.

	double target;  ///< The used calibration target.
	double error;   ///< Calibration error.

	double scaleX;  ///< New X scale.
	double scaleY;  ///< New Y scale.
	double scaleZ;  ///< New Z scale.

	double offsetX; ///< New X offset.
	double offsetY; ///< New Y offset.
	double offsetZ; ///< New Z offset.

	/** Default constructor.
	 */
	CalibrationResults();
};


/** @brief Calibration Settings
 *
 *  Class containing calibration settings.
 */
struct INERTIA_API CalibrationSettings
{
	std::wstring logfile;   ///< The logfile with calibration data.
	unsigned maxBurst;      ///< Number of samples to read from the logfile and parse at once.
	bool accelFilter;       ///< Enable a filter for fast movements in the accelerometer data.
	bool compassFilter;     ///< Enable a filter for fast movements in the compass data.
	bool gyroFilter;        ///< Enable a filter for fast movements in the gyroscope data.
	double accelThresh;     ///< Variance threshold for filtering acceleration data.
	double compassThresh;   ///< Variance threshold for filtering compass data.
	double gyroThresh;      ///< Variance threshold for filtering gyroscope data.
	double accelTarget;     ///< Target magnitude for acceleration data, e.g. 9.81 m/s2.
	double compassTarget;   ///< Target magnitude for compass data, e.g. 0.4905 gauss.
	double gyroTarget;      ///< Target magnitude for gyroscope data, e.g. 360.0 deg/s.
	bool accelZeroOffset;   ///< Calculate the zero-offset of the average acceleration data.
	bool compassZeroOffset; ///< Calculate the zero-offset of the average compass data.
	bool gyroZeroOffset;    ///< Calculate the zero-offset of the average gyroscope data.

	/**
	*  Default constructor
	*/
	CalibrationSettings()
		: CalibrationSettings(std::wstring(), 100)
	{
	}

	/** Constructor with individual arguments.
	 *  @param logfile the logfile
	 *  @param maxBurst set the number of samples to read at once
	 *  @param accelFilter enable the accelerometer Filter
	 *  @param compassFilter enable the compass filter
	 *  @param gyroFilter enable the gyroscope filter
	 *  @param accelThresh set the accelerometer threshold
	 *  @param compassThresh set the compass threshold
	 *  @param gyroThresh set the gyroscope threshold
	 *  @param accelTarget set the accelerometer target
	 *  @param compassTarget set the compass target
	 *  @param gyroTarget set the gyroscope target
	 *  @param accelZeroOffset enable zero-offset from average accelerometer data
	 *  @param compassZeroOffset enable zero-offset from average compass data
	 *  @param gyroZeroOffset enable zero-offset from average gyroscope data
	 */
	CalibrationSettings(std::wstring const& logfile, const unsigned maxBurst,
		const bool accelFilter = true, const bool compassFilter = false, const bool gyroFilter = true,
		const double accelThresh = 2.0, const double compassThresh = .1, const double gyroThresh = 50.0,
		const double accelTarget = 9.80665, const double compassTarget = .4905, const double gyroTarget = 360.0,
		const bool accelZeroOffset = false, const bool compassZeroOffset = false, const bool gyroZeroOffset = true);

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

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

}
