#ifndef HLPRXSTRUCTS_H
#define HLPRXSTRUCTS_H

#define HLPRX_MAXIMUM_NUMBER_OF_GATES	10
#define SEQUENCE_TABLE_BLOCKS 32
#define HLPRX_MAXIMUM_NUMBER_OF_ERROR_LOG_STRINGS 64
#define HLPRX_MAXIMUM_ERROR_STRING_LENGTH 128

// In these structures we have the option to use user-preferred units rather than internal ones.
// Converions is done in the high-level API (that's what it's for)

typedef struct 
{
	HLPRX_GateIndex index ;
	float startDepth_userUnits;
	float stopDepth_userUnits;
	//long startCount ;
	//long stopCount ;
	unsigned long threshold ;
	HLPRX_GateTrigger triggerGate ;
	HLPRX_GateThresholdPolarity thresholdPolarity ;
	HLPRX_GateTriggerMode triggerMode ;
	HLPRX_GateDistanceMetric distanceMetric ;
	NDTS_Boolean isEnabled ;
	HLPRX_GateAmplitudePeakSelect amplitudePeakSelect ;
	HLPRX_GateDistancePeakSelect distancePeakSelect ;
} HLPRX_Gate ;
	
typedef struct
{
	unsigned long numberOfPRXAttached;

	// All the RapiDAQ card settings go here
	unsigned long SamplingFrequency_Hz;
	//unsigned long SystemIOBank0;
	unsigned long SystemFirmwareVersion;
	//unsigned short CurvedGateData [];
	HLPRX_Rectification RectificationMode;
	float StartDelay_sec;
	unsigned long NumberOfSamples;
	unsigned long DropNumberOfSamples;
	HLPRX_SampleSize SampleStorageMode;
	HLPRX_TCGTriggerEvent TCGTrigEvent;
	NDTS_Boolean TCGEnable;
	HLPRX_ScanStorageOptions ScanStorage;
	unsigned long NumberOfBScansPerBank;
	unsigned long numberOfAScansPerBScan;
	unsigned long SamplingFirmwareVersion;
	HLPRX_InputCoupling inputCoupling;
	HLPRX_InputImpedance inputImpedance;
	HLPRX_AnalogueInput analogueInput;
	HLPRX_AnalogueInputRange analogueInputRange;
	HLPRX_AuxInput auxInput;
	HLPRX_TriggerSelect triggerSelect;
	float TransducerPulseWidth_sec;
	unsigned long RepetitionRate_Hz;
	unsigned long NumberOfAScansToInterleave;
	NDTS_Boolean IsBScanModeEnabled;
	unsigned long NumberOfEncoderClicksPerBScan;
	unsigned long EncoderNumber;
	unsigned long NumberOfEnabledGates;
	HLPRX_Gate gates[HLPRX_MAXIMUM_NUMBER_OF_GATES];
	unsigned long PeripheralFirmwareVersion;
	unsigned long RQ_SerialNumber;
} HLPRX_GlobalValues;

typedef enum
{
	coarse0dB,
	coarse20dB,
	coarse40db,
	coarse60dB
} COARSE_GAIN_RANGES;

typedef struct
{
	unsigned long receiveChannelNumber;
	unsigned long transmitChannelFlags;
	unsigned long externalTCGTriggerEnable;
	float fineGain_dB;
	float backendLowpassFilterCutoffFrequency;
	float backendHighpassFilterCutoffFrequency;
	float frontendLowpassFilterCutoffFrequency;
	float frontendHighpassFilterCutoffFrequency;
	float inputImpedance;
	COARSE_GAIN_RANGES coarseGain_dB;
	unsigned long oversamplingFineDelayTime_ns;
	unsigned long pulseWidth_ns;
	unsigned long preTriggerDelay_ns;
	unsigned long repetitionDelay_ns;
} HLPRXscanSequenceEntry;

typedef struct
{
	unsigned long globalCardNumber;
	unsigned long pulseEchoFlags;
	unsigned long externalTriggerSelect;
	unsigned long highVoltageEnable;
	unsigned long highVoltageMagnitude;
	HLPRXscanSequenceEntry sequence[SEQUENCE_TABLE_BLOCKS];
} PRX_CardSettings;

// This structure contains the settings for one functional group (i.e. DAQ card and all connected PRX cards)
// It contains an array of pointers to sequence block entries
// This allows us to have an arbitary number of PRX cards
typedef struct
{
	HLPRX_GlobalValues globalValues; // which loosely corresponds to StoreValues
	PRX_CardSettings **ppPRXCardSettingsTable; // pointer to an array of pointers to parameters that are specific to each PRX card
} HLPRXgroupSettings;

// This is a 'flattened' data structure that we exchange with the user.  This simplifies memory allocation issues
// by putting all settings in one structure.  Since the data size depened on the number of PRX cards, the PRXCardSettings
// array size is deemed to be as large as necessary, not just the single element that is declared.
// When allocating storage space the user should use HLPRXgetSerialisedSettingsSize() to determine the true
// size of the data structure.

typedef struct
{
	HLPRX_GlobalValues globalValues;
	PRX_CardSettings PRXCardSettings[1];
} HLPRXserialisedSettings;

#endif