#include "DataCollectionErrorInternal.h"
#include "ThreadInternal.h"
#include "DataCollectionError.h"
#include "NDTSError.h"


typedef struct  
{
	DC_ReturnCode	code ;
	char *			codeString ;
} DC_Errors ;

DC_Errors DC_ApiErrors[] = 
{
	{DC_OK											, "DC_OK"},
	{DC_OutOfMemory								, "DC_OutOfMemory"}, 
	{DC_NonFatalError								, "DC_NonFatalError"}, 
	{DC_FatalError									, "DC_FatalError"}, 
	{DC_ThreadHasShutdown							, "DC_ThreadHasShutdown"}, 
	{DC_NoDataAvailable							, "DC_NoDataAvailable "},
	{DC_Initialise_AlreadyInititialised			, "DC_Initialise_AlreadyInititialised"}, 
	{DC_Initialise_FailedToCreatePLXInterrupt		, "DC_Initialise_FailedToCreatePLXInterrupt"}, 
	{DC_SetThreadState_InvalidState				, "DC_SetThreadState_InvalidState"}, 
	{DC_SetThreadState_MustNotBeCalledInsideRQLock	, "DC_SetThreadState_MustNotBeCalledInsideRQLock"}, 
	{DC_SetThreadState_TimeoutWaitingForThread		, "DC_SetThreadState_TimeoutWaitingForThread"}, 
	{DC_SetThreadState_ThreadFailedToAcknowledgeNewState, "DC_SetThreadState_ThreadFailedToAcknowledgeNewState"}, 
	{DC_ThreadMain_ReleaseSemaphoreReturnedError	, "DC_ThreadMain_ReleaseSemaphoreReturnedError	"}, 
	{DC_BankSwapAndUpdate_TimeOutWaitingForBankSwap, "DC_BankSwapAndUpdate_TimeOutWaitingForBankSwap"},
	{DC_GetRawScan_NoDataAvailableOrBuffered		,  "DC_GetRawScan_NoDataAvailableOrBuffered"},
	
	{DC_SetRequestEarlySampleData_DataFullError,		"DC_SetRequestEarlySampleData_DataFullError"},
	{DC_SetRequestEarlySampleData_OneBankAlreadyFull,	"DC_SetRequestEarlySampleData_OneBankAlreadyFull"},
	{DC_SetRequestEarlySampleData_NoEarlySampleData, 	"DC_SetRequestEarlySampleData_NoEarlySampleData"},

	{DC_InternalDataFormatError,		"DC_InternalDataFormatError"},
	{DC_AScanDesynchronisation,		"DC_AScanDesynchronisation"},
	{DC_CScanDesynchronisation,		"DC_CScanDesynchronisation"},
	{DC_ReadRawScanBlocks_BadBlockCRC,		"DC_ReadRawScanBlocks_BadBlockCRC"},
	
	{DC_WaitForBankSwap_MissingTrigger,		"DC_WaitForBankSwap_MissingTrigger"},
	{DC_WaitForBankSwap_MissingTrigger,		"DC_WaitForBankSwap_MissingTrigger"},
	{DC_WaitForBankSwap_DataFull,		"DC_WaitForBankSwap_DataFull"},
	{DC_WaitForBankSwap_TriggerOccurredBeforeProcessComplete,		"DC_WaitForBankSwap_TriggerOccurredBeforeProcessComplete"},
	{DC_WaitForBankSwap_SampleIncomplete,		"DC_WaitForBankSwap_SampleIncomplete"},
	{DC_WaitForBankSwap_TimeOut,		"DC_WaitForBankSwap_TimeOut"},
	{DC_WaitForBankSwap_QueryTimerFail,			"DC_WaitForBankSwap_QueryTimerFail"},

	{DC_SetRequestEarlySampleData_DataFullError,		"DC_SetRequestEarlySampleData_DataFullError"},
	{DC_ReturnThreadStatePointer_InvalidCardIndex,		"DC_ReturnThreadStatePointer_InvalidCardIndex"},
	{DC_GetRawScan_NotAllBlocksDMAOK,		"DC_GetRawScan_NotAllBlocksDMAOK"},
	{DC_GetSamples_PerformDMATransferFail,		"DC_GetSamples_PerformDMATransferFail"},
	{DC_GetRawScan_InvalidNumberOfBScansInBank,		"DC_GetRawScan_InvalidNumberOfBScansInBank"},

	{DC_FreeRawScanData_MissingRawScan,		"DC_FreeRawScanData_MissingRawScan"},
	{DC_FreeRawScanData_InvalidMode,								"DC_FreeRawScanData_InvalidMode"},
	{DC_FreeRawScanData_MissingData,		"DC_FreeRawScanData_MissingData"},

	{DC_NotInDoFullACaptureMode,			"DC_NotInDoFullACaptureMode"},

	{DC_LastError,															"Unknown"}
} ;

const char * CALL_CONV DC_GetCodeString(int errorCode)
{
	int i = 0 ;

	while (DC_ApiErrors[i].code != errorCode && DC_ApiErrors[i].code != DC_LastError)
		i++ ;

	return DC_ApiErrors[i].codeString ;
}

DC_ErrorSummary DC_GetLastErrorSummary(void)
{
	switch(DC_GetLastError())
	{
	case 	DC_OK:
		return DCES_OK;

/*	Daniel summer 08 - out of memory can be handled in the same way as any other fatal error
	case DC_Calibrate_OutOfMemory:
	case DC_SetCurvedGateData_OutOfMemory:
	case DC_SetTCGValues_OutOfMemory:
	case DC_SetPingPongSequenceElement_OutOfMemory:
	case DC_GetRawScan_MemoryAllocationFail:
	case DC_GetRawScan_OutOfMemory:
	case DC_StructuresInitialise_OutOfMemory:
	case DC_Alloc_OutOfMemory:
	case RawScanOffline_ExtractCScan_OutOfMemory	:
		return DCES_OutOfMemory;
		break;
		*/
//	case DC_GetRawScan_CRCSubSystemInternalError:  - error code not currently in use
	case DC_InternalDataFormatError:
	case DC_AScanDesynchronisation:
	case DC_CScanDesynchronisation:
	case DC_ReadRawScanBlocks_BadBlockCRC:
//	case DC_GetRawScan_RawScanNotLargeEnoughForData:  - error code not currently in use
	case DC_WaitForBankSwap_MissingTrigger:
	case DC_WaitForBankSwap_SampleIncomplete:
	case DC_SetRequestEarlySampleData_DataFullError:
		return DCES_NonFatalError;
		break;
	default:
		return DCES_FatalError;
		break;
	}
}

// Was DC_HandleRQError - checks if the last error is fatal or recoverable.
NDTS_Boolean DC_IsErrorNonFatal()
{
	switch(DC_GetLastErrorSummary())
	{
	case DCES_OK:
	case DCES_NonFatalError:
		return NDTS_BTrue;

	case DCES_OutOfMemory:
		DC_HandleError(DC_OutOfMemory);
		return NDTS_BFalse;

	case DCES_FatalError:
	default:
		DC_HandleError(DC_FatalError);
		return NDTS_BFalse;
	}
}

DC_API DC_ReturnCode  DC_GetLastError()
{
	return NDTS_GetLastError() ;
}

DC_API unsigned long DC_ReturnNumberOfErrorLogLines()
{
	return NDTS_ReturnNumberOfErrorLogLines() ;
}

NDTS_Boolean DC_GetErrorLogLine(unsigned long lineNumber, char *pMessageBuffer, unsigned long numberOfBytesInMessageBuffer)
{
	return NDTS_GetErrorLogLine(lineNumber, pMessageBuffer, numberOfBytesInMessageBuffer) ;
}

DC_API NDTS_Boolean DC_ClearErrorLog() 
{
	return NDTS_ClearErrorLog() ;
}

void DC_HandleError(DC_ReturnCode errorCode) 
{
	NDTS_HandleError(errorCode);
}


