#ifndef RQINTERNAL_H
#define RQINTERNAL_H

#ifdef __cplusplus
extern "C" {
#endif

#ifndef	RQ_EXPORTS
#error RQInternal.h should not be included outside the DLL - use RQProtected.h instead
#endif

#include <stdarg.h>
#include "Inc\PlxApi.h"
#include "Inc\Reg9056.h"

#include "RQMemorySpaceInternal.h"
#include "RQ.h"
#include "RQProtected.h"
#include "RQRawScanInternal.h"
#include "RQMemoryFactoryInternal.h"

	// #defines moved from here to RQProtected.h
	// since they might reasonably be of use outside the DLL

	typedef struct 
	{
		unsigned long numberOfRapiDAQBoards ;
		//unsigned long numberOfPRXBoards ;
		//unsigned long numberOfUninitialisedBoards ;
	} RQ_PCIState ;


	typedef struct 
	{
		NDTS_Boolean isEnumerated ;
		void (*pfnInitStatusCallback)(RQ_InitialisationStep step, RQ_InitialisationStepStatus isOK) ;
		RQ_PCIState pciState ;
		char iniFileName[256];
	} RQ_GlobalState ;

	typedef enum
	{
		// These should be integer powers of 2.
		RQ_CBDCRCCheckIsPresent = 1
	} RQ_CardBlockDescriptionFlags ;


	extern RQ_GlobalState globalState ;

	void CALL_CONV RQ_DLLInitialise() ;
	void CALL_CONV RQ_DLLUninitialise() ;

	//  PciState *pciStateArray;
	//  RQ_State *pBoardStates;
	//extern pciState *pciStateArray; // dynamically allocated array for RapiDAQ descriptors
	//extern RQ_State *pBoardStates;

	// RQ_ functions below are for multi-cardIndex systems
	// The above RQ_ functions are now wrappers for legacy single-cardIndex apps

	NDTS_Boolean CALL_CONV RQ_OpenDMAChannel(unsigned long cardIndex) ;
	NDTS_Boolean CALL_CONV RQ_CloseDMAChannel(unsigned long cardIndex) ;
	NDTS_Boolean CALL_CONV RQ_SystemRAMTest(unsigned long cardIndex) ;
	NDTS_Boolean CALL_CONV RQ_SystemFPGAInversionTest(unsigned long cardIndex) ;
	NDTS_Boolean CALL_CONV RQ_Calibrate(unsigned long cardIndex, RQ_AnalogueInputRange inp) ;
	NDTS_Boolean CALL_CONV RQ_SetCalibrationGain(unsigned long cardIndex, unsigned long dToAWord) ;
	NDTS_Boolean CALL_CONV RQ_SetCalibrationOffset(unsigned long cardIndex, unsigned long dToAWord) ;
	NDTS_Boolean CALL_CONV RQ_GetIsCalibrationWriteComplete(unsigned long cardIndex, NDTS_Boolean *pIsComplete) ;
	NDTS_Boolean CALL_CONV RQ_SetCalibrationVoltage(unsigned long cardIndex, RQ_CalibrationVoltage calibrationVoltage) ;
	NDTS_Boolean CALL_CONV RQ_GetCalibrationVoltage(unsigned long cardIndex, RQ_CalibrationVoltage *pCalibrationVoltage) ;
	NDTS_Boolean CALL_CONV RQ_SetSensorArrayNumberOfElements(unsigned long cardIndex, unsigned long numberOfElements) ;
	NDTS_Boolean CALL_CONV RQ_GetSensorArrayNumberOfElements(unsigned long cardIndex, unsigned long *pNumberOfElements) ;
	NDTS_Boolean CALL_CONV RQ_AddDiagnosticString(unsigned long cardIndex, unsigned long registerOffset, unsigned long registerValue) ;/*
																																	   NDTS_Boolean CALL_CONV RQ_PerformScatteredDMAReadRecover(unsigned long cardIndex, 
																																	   unsigned long sourceBlocksOffset, 
																																	   RQ_CardBlockDescription* pSourceBlockDescriptionBegin, 
																																	   RQ_CardBlockDescription* pSourceBlockDescriptionEnd, 
																																	   unsigned char **ppDestinationBlocks, 
																																	   const unsigned long *pCRCTable, 
																																	   unsigned long *pSourceBlocksRead) ; */
	/*NDTS_Boolean CALL_CONV RQ_PerformScatteredDMAReadNoRecover(unsigned long cardIndex, 
		RQ_RawScan *pRawScan,
		unsigned long sourceBlocksOffset, 
		RQ_CardBlockDescription* pSourceBlockDescriptionBegin, 
		RQ_CardBlockDescription* pSourceBlockDescriptionEnd, 
		RQ_MemoryHandle *pDestinationBlocks, 
		const unsigned long *pCRCTable, 
		unsigned long *pSourceBlocksRead) ; */
	NDTS_Boolean CALL_CONV RQ_ReadRawScanBlocks(unsigned long cardIndex, 
		unsigned long sourceByteOffset, 
		RQ_CardBlockDescription* pSourceBlockDescriptionBegin, 
		RQ_CardBlockDescription* pSourceBlockDescriptionEnd, 
		RQ_MemoryHandle *pDestinationBlocks, 
		const unsigned long *pCRCTable, 
		unsigned long *pSourceBlocksRead) ; 
	NDTS_Boolean CALL_CONV RQ_FetchRawScanBytes(unsigned long cardIndex, 
		unsigned long begin, 
		unsigned long end, 
		unsigned long *pTransferCount) ;


	//System FPGA Registers

	NDTS_Boolean CALL_CONV RQ_SetCheckData(unsigned long cardIndex, unsigned long data) ;
	NDTS_Boolean CALL_CONV RQ_GetCheckData(unsigned long cardIndex, unsigned long *pValue) ;
	NDTS_Boolean CALL_CONV RQ_SetProgramFPGAs(unsigned long cardIndex) ;
	NDTS_Boolean CALL_CONV RQ_SetWriteEEPROM(unsigned long cardIndex) ;
	NDTS_Boolean CALL_CONV RQ_SetReadEEPROM(unsigned long cardIndex) ;
	NDTS_Boolean CALL_CONV RQ_GetFPGAProgramStatus(unsigned long cardIndex, NDTS_Boolean *pIsSuccess) ;
	NDTS_Boolean CALL_CONV RQ_SetDDSRegister(unsigned long cardIndex, unsigned long dataRegister, unsigned long addressBus) ;
	NDTS_Boolean CALL_CONV RQ_SetDDSReset(unsigned long cardIndex) ;
	NDTS_Boolean CALL_CONV RQ_GetDDSReset(unsigned long cardIndex, NDTS_Boolean *pReset) ;
	NDTS_Boolean CALL_CONV RQ_DDSWait(unsigned long cardIndex) ;
	NDTS_Boolean CALL_CONV RQ_SetResetTCGLoadCounter(unsigned long cardIndex) ;

	//Peripheral FPGA Registers

	NDTS_Boolean CALL_CONV RQ_SetDDSKEY(unsigned long cardIndex, unsigned long dDSKEY) ;
	NDTS_Boolean CALL_CONV RQ_GetDDSKEY(unsigned long cardIndex, unsigned long *pDDSKEY) ;
	NDTS_Boolean CALL_CONV RQ_SetDDSFSK(unsigned long cardIndex, unsigned long dDSFSK) ;
	NDTS_Boolean CALL_CONV RQ_GetDDSFSK(unsigned long cardIndex, unsigned long *pDDSFSK) ;

	NDTS_Boolean CALL_CONV RQ_SetSensorArrayDIUnitEnableOutputs(unsigned long cardIndex, NDTS_Boolean isEnabled) ;
	NDTS_Boolean CALL_CONV RQ_GetSensorArrayDIUnitEnableOutputs(unsigned long cardIndex, NDTS_Boolean *pIsEnabled) ;

	NDTS_Boolean CALL_CONV RQ_SetNumberOfPeriodsBetweenAScanTriggers(unsigned long cardIndex, unsigned long numberOfPeriods) ;
	NDTS_Boolean CALL_CONV RQ_GetNumberOfPeriodsBetweenAScanTriggers(unsigned long cardIndex, unsigned long *pNumberOfPeriods) ;

	NDTS_Boolean CALL_CONV RQ_GetGateInternalIndex(unsigned long cardIndex, RQ_GateIndex gateIndex, unsigned long *pGateIndex) ;

	NDTS_Boolean CALL_CONV RQ_CheckSRAM(unsigned long cardIndex,
		RQ_ScanStorage scanStorage, unsigned long numberOfAScanSamples,
		RQ_SampleSize sampleSize, unsigned long numberOfAScanPerBScan,
		unsigned long numberOfBScans, unsigned long numberOfGates) ;
	NDTS_Boolean CALL_CONV RQ_HandleSRAM(unsigned long cardIndex) ;

	NDTS_Boolean CALL_CONV RQ_SetSystemRegister(unsigned long cardIndex, unsigned long offset, unsigned long value) ;
	NDTS_Boolean CALL_CONV RQ_GetSystemRegister(unsigned long cardIndex, unsigned long offset, unsigned long *value) ;

	NDTS_Boolean CALL_CONV RQ_SetPeripheralRegister(unsigned long cardIndex, unsigned long offset, unsigned long value) ;
	NDTS_Boolean CALL_CONV RQ_GetPeripheralRegister(unsigned long cardIndex, unsigned long offset, unsigned long *value) ;

	NDTS_Boolean CALL_CONV RQ_GetSRAMLong(unsigned long cardIndex, unsigned long offset, unsigned long *value) ;
	NDTS_Boolean CALL_CONV RQ_SetSRAMLong(unsigned long cardIndex, unsigned long offset, unsigned long value) ;

	void CALL_CONV RQ_CreateCriticalSection(unsigned long cardIndex) ;
	void CALL_CONV RQ_DeleteCriticalSection(unsigned long cardIndex) ;

	void CALL_CONV RQ_GenerateCRCTable(unsigned long *pCRCTable) ;
	unsigned long CALL_CONV RQ_CalculateCRC32(unsigned long seed, const unsigned long *pCRCTable, const char *pData, unsigned long numberOfBytes) ;

	NDTS_Boolean CALL_CONV RQ_GetAScanNoBankSwap(unsigned long cardIndex, short *pData, unsigned long numberOfBufferValues, unsigned long aScanIndex, unsigned long bScanIndex);

	// These functions have been added to give a fine grained access to the initialise process.
	// They are not designed for general use.
	// After calling RQ_StructuresInitialise() it is up to the caller to call RQ_Unlock() when
	// the initialisation is complete.

	// pci Initiailise has been removed from the main init function 
	// so the Hardware Test Script app can just initialise the pci without
	// doing a full init

	NDTS_Boolean CALL_CONV RQ_GetReadEEPROM(unsigned long cardIndex, unsigned long *flag);
	NDTS_Boolean CALL_CONV RQ_CalibrateGetMean(unsigned long cardIndex, unsigned long numSamples, short *samples, short dToAValue, short *mean, NDTS_Boolean isOffset);
	NDTS_Boolean CALL_CONV RQ_GetCalibrationDToAWord(unsigned long cardIndex, unsigned long *dToAWord);

	void CALL_CONV RQ_ExtractStringFromWhitespaceOrBrackets(char *inputString, char *outputString);
	int CALL_CONV RQ_LoadFPGAFromFile(unsigned long cardIndex, HANDLE fileHandle);
	int CALL_CONV RQ_LoadGatesFromFile(unsigned long cardIndex, HANDLE fileHandle);
	int CALL_CONV RQ_LoadTCGCurveFromFile(unsigned long cardIndex, HANDLE fileHandle);
	int CALL_CONV RQ_LoadPingPongSequenceFromFile(unsigned long cardIndex, HANDLE fileHandle);
	int CALL_CONV RQ_LoadCurvedGateDataFromFile(unsigned long cardIndex, HANDLE fileHandle);

	void RQ_UpdateSampleParameters(unsigned long cardIndex);
	NDTS_Boolean CALL_CONV RQ_CheckAScanHeader(unsigned long aScanHeader, unsigned long expectedAScanIndex, NDTS_Boolean *pIsIdentifierPresent) ;
	NDTS_Boolean CALL_CONV RQ_CheckCScanHeader(unsigned long cScanHeader, unsigned long expectedCScanIndex, NDTS_Boolean *pIsIdentifierPresent) ;

	/*RQ_API*/ NDTS_Boolean CALL_CONV RQ_SetPingPongElementRegister(unsigned long cardIndex, unsigned long sequencePosition, unsigned long unFlippedElement) ;

	NDTS_Boolean RQ_RawWriteGates(unsigned long cardIndex, unsigned long gateIndex);

	NDTS_Boolean RQ_IsInternalTrigger(RQ_Trigger triggerSelect) ;

	NDTS_Boolean CALL_CONV RQ_SetMaximumNumberOfBScansPerBank(unsigned long cardIndex) ;
	NDTS_Boolean CALL_CONV RQ_SetNumberOfBScansPerBankInternal(unsigned long cardIndex, unsigned long numberOfScans) ;
	NDTS_Boolean CALL_CONV RQ_VerifyRawScanAScanHeaders(unsigned long cardIndex, RQ_RawScan *pRawScan) ;
	NDTS_Boolean CALL_CONV RQ_ReturnDataSamplingStatusFlagSet(unsigned long cardIndex, unsigned long mask) ;
	unsigned long RQ_ReturnMaxBScanRepRate(unsigned long cardIndex);

	void RQ_HandleRQError(RQ_ReturnCode errorCode)  ;
	void RQ_HandlePCIError(RQ_ReturnCode errorCode);

	int RQ_GetDefaultValueInt(RQdefaultEnum index);
	void RQ_GetDefaultValueString(RQdefaultEnum index, char *pDest);
	NDTS_Boolean RQ_SetTCGStartInternal(unsigned long cardIndex, unsigned long tCGModeMask);
	NDTS_Boolean RQ_SetTCGPointRatio(unsigned long cardIndex, unsigned long tCGPointRatio);
	NDTS_Boolean RQ_GetTCGPointRatio(unsigned long cardIndex, unsigned long *tCGPointRatio);
	NDTS_Boolean RQ_SetTCGDecimation(unsigned long cardIndex);

	NDTS_Boolean RQ_WriteEEPROMifDrifted(unsigned long cardIndex, unsigned long offset, unsigned long value, int drift);
	NDTS_Boolean RQ_CommitEEPROM(unsigned long cardIndex);
	unsigned short RQ_ReturnGateSubtractValue(const RQ_Gate *pGate);
	// Bug 838
	void RQ_AdjustGateDepths(RQ_Gate *pGates, unsigned char *pOurCScanRecordAddress);

	RQ_API NDTS_Boolean CALL_CONV RQ_SetOnlyRespondToInRangeAccess(unsigned long cardIndex);

#ifdef __cplusplus
}
#endif


#endif
