#include "ThreadInternal.h"
#include "DataCollectionErrorInternal.h"
#include <crtdbg.h>

#include "RawScanProtected.h"
 

DC_API NDTS_Boolean DC_CollectInitialise(DC_AssociatedSDK *pAssociatedSDK)
{
//	unsigned long bank;
	DC_State *pThreadState; 
	unsigned long cardIndex = 0;

	if (!DC_Initialise(pAssociatedSDK)) 
		return NDTS_BFalse;

	for (cardIndex=0; cardIndex < pAssociatedSDK->numberOfBoards; cardIndex++)
	{
		pThreadState = DC_ReturnThreadStatePointer(cardIndex) ;
		if (!pThreadState) 
			return NDTS_BFalse; 

		DC_Lock(cardIndex);

		pThreadState->collectState.readBank = 0;
		pThreadState->collectState.rawScansInitialised = 0;

		DC_Unlock(cardIndex);

		if (!DC_SetThreadState(cardIndex, DC_SMSCollect))
			return NDTS_BFalse;
	}
	return NDTS_BTrue;
}

DC_API NDTS_Boolean DC_CollectUninitialise()
{
	DC_AssociatedSDK *pAssociatedSDK = &(DC_ReturnThreadStatePointer(0)->associatedSDK);

	unsigned long cardIndex;
	for (cardIndex=0; cardIndex < pAssociatedSDK->numberOfBoards; cardIndex++)
	{
		//	unsigned long bank;
		DC_State *pThreadState = DC_ReturnThreadStatePointer(cardIndex) ;

		if (!pThreadState) 
			return NDTS_BFalse; 

		// Pause the thread down so it isn't accessing pRawScans below.
		DC_SetThreadState(cardIndex, DC_SMSPause) ;

		Sleep(100);
		if(pThreadState->collectState.rawScansInitialised == 1)
		{
			DC_FreeRawScanData(&(pThreadState->collectState.rawScans[0]), DC_FRSOAll) ;
			RawScan_UninitialiseRawScan(&(pThreadState->collectState.rawScans[0]));
			pThreadState->collectState.rawScansInitialised = 0 ;
		}
	}
	if (!DC_Uninitialise()) 
		return NDTS_BFalse;

	return NDTS_BTrue;
}

DC_API NDTS_Boolean DC_CollectReset(unsigned long cardIndex)
{
	DC_State *pThreadState = DC_ReturnThreadStatePointer(cardIndex) ;
	if (!pThreadState) 
		return NDTS_BFalse; 

	if(pThreadState->collectState.rawScansInitialised == 1)
	{
		DC_FreeRawScanData(&(pThreadState->collectState.rawScans[0]), DC_FRSOAll) ;
		RawScan_UninitialiseRawScan(&(pThreadState->collectState.rawScans[0]));
		RawScan_ClearRawScan(&(pThreadState->collectState.rawScans[0])) ;
		pThreadState->collectState.rawScansInitialised = 0 ;
	}

	return NDTS_BTrue;
}

DC_API NDTS_Boolean DC_GetRawScan(unsigned long cardIndex, NDTS_RawScan *pRawScan) 
{
	DC_State *pThreadState = DC_ReturnThreadStatePointer(cardIndex) ;

	if (!pThreadState) 
		return NDTS_BFalse; 

	_ASSERTE(pRawScan) ;

	// Must be called outside DC_Lock so thread can run
	if (!DC_BankSwapAndUpdate(cardIndex))	
		return NDTS_BFalse;

	DC_Lock(cardIndex);

	if(pThreadState->collectState.rawScans[0].numberOfBScans == 0)
//	if(pThreadState->collectState.pRawScans[pThreadState->collectState.readBank].numberOfBScans == 0)
	{
		// The raw scan in the read bank has not been filled. 
		DC_HandleError(DC_GetRawScan_NoDataAvailableOrBuffered);
		DC_Unlock(cardIndex);
		return NDTS_BFalse ;
	}

	// Copy the raw scan from the read bank.
	RawScan_CopyRawScan(pRawScan, &pThreadState->collectState.rawScans[0]) ;
//	DC_CopyRawScan(pRawScan, &pThreadState->collectState.pRawScans[pThreadState->collectState.readBank]) ;

	_ASSERTE(pThreadState->collectState.rawScans[0].pInternal) ;
	// Clear the raw scan as it as it's data now 'belongs' to pRawScan.
	RawScan_ClearRawScan(&pThreadState->collectState.rawScans[0]) ;
//	DC_ClearRawScan(&pThreadState->collectState.pRawScans[pThreadState->collectState.readBank]) ;

	// Flip banks.
//	pThreadState->collectState.readBank = pThreadState->collectState.readBank ? 0 : 1;

	DC_Unlock(cardIndex);

	return NDTS_BTrue;
}

