/******************************************************************************
*
*	NDT Solutions Rapid Scan 2 Automated (RS2A) Software Development Kit v1.0
* (C) NDT Solutions 2007.  
*
******************************************************************************
*
*  File:        NDTSRS2A.h
*
*  Description: Primary header file for inclusion by C++ applications.  
*
*
******************************************************************************/

#pragma once
#include "PropertiesInterface.h"
#include "NDTSRS2ATypes.h"

#ifdef RS2A_EXPORTS
#define RS2A_API __declspec(dllexport)
#else
#define RS2A_API __declspec(dllimport)
#endif

#ifdef STDCALL
#define CALL_CONV __stdcall
#else
#define CALL_CONV
#endif

namespace NDTS
{
	namespace RS2A
	{
		typedef struct
		{
			int distanceMetric			: 15 ;
			int reserved1				: 1 ;
			int amplitudeMetric			: 12 ;
			int wasDistanceMeasured		: 1 ;
			int wasAmplitudeMeasured	: 1 ;
			int reserved2				: 2 ;
		} GateOutput ;

		// These classes are only to be accessed via the Factory class and not 
		// instantiated explicitly.  For example:-
		// Factory *pRs2Factory = Factory::getInstance();
		// Snapshot *pSnapshot = pRs2Factory->getSnapshot();
		// pSnapshot->getAScan(...);
		class Snapshot
		{
		public:
			// These functions all work on a snapshot of data, including GetEncoderValue
			//virtual bool takeSnapshot(int *pNumberOfBScans)=0;
			//virtual bool trigger() =0;
			virtual bool getAScan(int bScanIndex, int aScanIndex, short *pSamples, int numberOfBufferValues) =0;
			virtual bool getPackedGateData(int bScanIndex, int aScanIndex, GateOutput *pGateOutputs, int numberOfBufferValues) = 0;
			virtual bool getUnPackedGateData(int bScanIndex, int aScanIndex, GateOutput *pGateOutputs, int numberOfBufferValues) = 0;
			virtual bool getEncoderValue(int bScanIndex, int encoderIndex, int *pEncoderValue) =0;
			virtual bool getEncoderValues(int bScanIndex, int numberOfEncoders, int *pEncoderValue) = 0;
			virtual void resetEncoder(int encoderIndex) = 0;
			virtual unsigned long returnNumberOfSamples() = 0;
		};

		class ErrorLog
		{
		public:
			// The error log should be checked regularly.  There is an ErrorLog property group that contains
			// the number of items in the log and an event to clear the log.
			virtual bool getErrorLogLine(int lineNumber, char *pMessageBuffer, int numberOfBytesInMessageBuffer)=0;
		};

		class TCG
		{
		public:
			// TCG and gain normalisation

			// *pTCGCurve is an array of 32 bit numbers, one for each sample period.  
			// The TCG curve in the RapiDAQ is only 8 bits and each 32 bit number should be from 0..255.
			// 0 corresponds to 0dB of gain and 255 to 80dB.
			// numberOfPointsInCurve should match the A Scan range PIAScanRange.  It is used to prevent
			// a buffer overflow if the A Scan range of the application gets out of sync with the SDK

			virtual bool setCurve(int *pTCGCurve, int numberOfPointsInCurve)=0;
		};

		class FactoryInternal;
		class RS2A_API Factory
		{

		// The Factory is a singleton class which is used to obtain 
		// RS2A objects such as Gates, Snapshot etc.
		private:
			static FactoryInternal *pFactoryInternal;
		protected:
			Factory();
			~Factory();
		public:
			static Factory *getInstance();
			// Deletes all the instances - stops the hardware if it is still running
			static void deleteAllInstances();
			virtual Snapshot *getSnapshot()=0;
			virtual ErrorLog *getErrorLog()=0;
			virtual TCG *getTcg()=0;
			virtual SCO::Property *getRootProperty()=0;
			// Returns true if initialised, false if there is a problem
			virtual bool initialise()=0;
			// Stops the hardware but doesn't delete the factory instances
			virtual void uninitialise()=0;
		};
	////////////////////////////////////////////////////////////////////////
	// Functions for testing that will not be used by normal applications
	class Test
	{
	public:
		// Run some checks and write the results to the error log
		// Return true if all the checks pass
	RS2A_API static bool runUnitTests();
	};
	}
}

