#include <windows.h>
#include <crtdbg.h>
#include <stdio.h>
#include "PingPongTable.h"

#include "NDTSError.h"
#include "RQ.h"
#include "Collect.h"

#include "NDTSRS2AInternal.h"
#include "PropertiesInterface.h"
#include "SDKPropertiesCollection.h"
#include "GroupPropertyInternal.h"
#include "TCG.h"

using namespace NDTS::RS2A;

FactoryInternal *Factory::pFactoryInternal = 0;

Factory::Factory()
{
}
Factory::~Factory()
{
}

void Factory::deleteAllInstances()
{
	// Call Unint to stop the SDK and free the memory - doesn't seem to work from IW when in a destructor
	delete pFactoryInternal;
	pFactoryInternal = 0;
}

// The Factory class is initially created empty and initialisation is done on the first call
// of getInstance().  This prevents the problems associated with starting the SDK in a DLL_Initialise
Factory *Factory::getInstance()
{
	printf("getUInstance");
	if (!pFactoryInternal)
		pFactoryInternal = new FactoryInternal();
	return pFactoryInternal;
}


bool Test::runUnitTests()
{
	if (!NDTS::RS2A::rs2aGlobalState.isInitialised)
	{
		RS2A_HandleRS2AError(RS2A_NotInitialised) ;
		return false ;
	}

	// If more tests are added, make a unit tests class
	// and add the tests to the class

	// Test the ping pong tables
	// A file has been generated by WinRS - read this file and check our ping pong table against it.
	char fullPath[1000];
	sprintf(fullPath, "%s\\RapiDAQ\\sw\\rs2a\\PingPongUnitTests.txt", getenv("svnroot") );
	FILE *fp = fopen(fullPath, "r");
	if (!fp)
		goto errorBadFile;

	int physicalElements, apertureSize, pitchMultiplier, doPingPong, effectiveElements;
	while(!feof(fp))
	{
		if (fscanf(fp, " physicalElements %d, apertureSize %d, pitchMultiplier %d, doPingPong %d\n",
			&physicalElements, &apertureSize, &pitchMultiplier, &doPingPong)
			!= 4)
			goto errorBadFile;
		if (fscanf(fp, " effectiveElements %d\n",
			&effectiveElements)
			!= 1)
			goto errorBadFile;
		NDTS::RS2A::PingPongTable table(physicalElements, apertureSize, pitchMultiplier, (doPingPong == 1));
		if (effectiveElements != table.getAScansPerBScan())
		{
			NDTS_LogLine(NDTS_LLErr, "effectiveElements %d != table.effectiveElements() %d", effectiveElements,  table.getAScansPerBScan());
			goto errorFailedTest;
		}

		for (int aScanIndex = 0; aScanIndex < effectiveElements; aScanIndex++)
		{
			int e, x, reverse;
			if (fscanf(fp, " %d, %d, %d\n",
				&e, &x, &reverse)
				!= 3)
				goto errorBadFile;

			/* isOK = RQ_SetPingPongSequenceElement(boardIndex, e, x, reverse); 
			RQ_SetPingPongSequenceElement(unsigned long cardIndex, unsigned long elementNumber, unsigned long sequencePosition, unsigned long effectiveElement) ;
			isOK = RQ_SetPingPongSequenceElement(rs2aGlobalState.cardIndex, 
			table.getSequencePosition(aScanIndex), 
			aScanIndex,
			table.getEffectivePosition(aScanIndex));  */
			if (aScanIndex != x)
				goto errorBadFile;

			// It is likely that pingPong was not correct in WinRS
			if (e != table.getSequencePosition(aScanIndex) && !doPingPong)
			{
				NDTS_LogLine(NDTS_LLErr, "e %d != table.getSequencePosition() %d", e,  table.getSequencePosition(aScanIndex));
				goto errorFailedTest;
			}

			if (reverse != table.getEffectivePosition(aScanIndex) && !doPingPong)
			{
				NDTS_LogLine(NDTS_LLErr, "reverse %d != table.getEffectivePosition() %d", reverse,  table.getEffectivePosition(aScanIndex));
				goto errorFailedTest;
			}
		}
	}

	return true;
errorBadFile:
	NDTS_LogLine(NDTS_LLErr, "pingpong.txt is corrupted");
errorFailedTest:
	fclose (fp);
	return false;
}
