// Copyright (c) 2020 Metrolab Technology S.A., Geneva, Switzerland (www.metrolab.com)
// See the included file LICENSE.txt for the licensing conditions.

//////////////////////////////////////////////////////////////////////////
/// \file
/// \brief Type definitions for THM1176 Instrument Manager.
#pragma once

#include "THM1176.h"
#include <QtCore/QObject>

namespace MTL
{

/// \brief Operating modes used to initiate actions or provide status.
typedef enum
{
    kTHM1176NotConnected,           ///< Disconnect instrument.
    kTHM1176Reset,                  ///< Reset instrument.
    kTHM1176Idle,                   ///< Place the instrument in idle mode.
    kTHM1176Measure,                ///< Start a single measurement.
    kTHM1176MeasureContinuously,    ///< Start a continuous measurement.
    kTHM1176CalibrateZeroOffset,    ///< Initiate the zero-offset calibration procedure.
    kTHM1176RestoreZeroOffset       ///< Restore the factory zero-offset setting.
} eTHM1176OperatingMode;

/// \brief Enumeration of possible measurement units, including "ADC".
typedef enum
{
    kT      = MTL::Instrument::THM1176Types::kT,        ///< Tesla
    kmT     = MTL::Instrument::THM1176Types::kmT,		///< Milli-Tesla
    kuT     = MTL::Instrument::THM1176Types::kuT,		///< Micro-Tesla
    knT     = MTL::Instrument::THM1176Types::knT,		///< Nano-Tesla
    kGauss  = MTL::Instrument::THM1176Types::kGauss,    ///< Gauss
    kkGauss = MTL::Instrument::THM1176Types::kkGauss,   ///< Kilo-Gauss
    kmGauss = MTL::Instrument::THM1176Types::kmGauss,	///< Milli-Gauss
    kMHzp   = MTL::Instrument::THM1176Types::kMHzp,		///< Equivalent proton NMR resonant frequency, in Mega-Hertz
	kApm,												///< Equivalent H in a vacuum, in A/m
	kkApm,												///< Equivalent H in a vacuum, in kA/m
	kmApm,												///< Equivalent H in a vacuum, in mA/m
    kADC                                                ///< Raw ADC values
} eTHM1176Units;

/// \brief List of measurement units.
class CTHM1176UnitsList : public std::vector<eTHM1176Units>
{
};

/// \brief Data returned for one measurement.
class CMeasurement
{
public:
	// Measurement data retrieved from Instrument Driver.
    CFluxList						Bx;             ///< Bx value for each measurement.
    CFluxList						By;             ///< By value for each measurement.
    CFluxList						Bz;             ///< Bz value for each measurement.
    CTimestampList					TimestampList;  ///< Timestamp for each measurement.
	eTHM1176Units					Units;          ///< Measurement units for Bx, By, Bz.
    ushort							Temp;           ///< Temperature, in arbitrary units.

	// Active measurement parameters.
    sAveraging<uParm>				AveragingParms; ///< Averaging parameters used for measurement.
    sInputTrigger<uParm>			TriggerParms;   ///< Trigger parameters used for measurement.
    sRange<uParm>					RangeParms;     ///< Range parameters used for measurement.
    sArbitraryMeasurements			OutputSelect;   ///< Output selection parameters used for measurement.
    eCommunicationFormat			CommFormat;     ///< Communication parameters used for measurement.
    bool							SleepParm;      ///< Sleep parameters used for measurement.

	// Warnings.
    CErrorList						Warnings;       ///< Any warnings returned during the measurement.

    /// \brief Constructor.
    CMeasurement()
        : Units{}, Temp{}, CommFormat{}, SleepParm{}
    {
    }

    /// \brief Clear the data structure to default values.
	void clear()
	{
		Bx.clear();
		By.clear();
		Bz.clear();
		Units			= kT;
		Temp			= 0;
		TimestampList.clear();

		AveragingParms.clear();
		TriggerParms.clear();
		OutputSelect.clear();
		SleepParm		= false;
		RangeParms.clear();
		CommFormat		= kComFormatAscii;

		Warnings.clear();
	}

    /// \brief Equality operator.
	bool operator==(CMeasurement other) const
	{
		return (
					Bx						== other.Bx						&&
					By						== other.By						&&
					Bz						== other.Bz						&&
					Units					== other.Units					&&
					Temp					== other.Temp					&&
					TimestampList			== other.TimestampList			&&

					AveragingParms			== other.AveragingParms			&&
					TriggerParms			== other.TriggerParms			&&
					OutputSelect			== other.OutputSelect			&&
					SleepParm				== other.SleepParm				&&
					RangeParms				== other.RangeParms				&&
					CommFormat				== other.CommFormat				&&

					Warnings				== other.Warnings
					);
	}

    /// \brief Inequality operator.
	bool operator!=(CMeasurement other) const
	{
		return (!operator==(other));
	}
};

} // namespace
