#include "RQRawScanPools.h"
#include "RQRawScanInternal.h"
#include "RQMemoryBlockNodeInternal.h"
#include <memory.h>
#include <crtdbg.h>

/*
// Mark
#include <stdio.h>
#include <windows.h>
*/

struct
{
	unsigned long m_pMemoryBlockNodePool ;
	unsigned long m_pRawScanProtectedPool ;
	unsigned long m_pDataAHeaderPool ;
	unsigned long m_pDataBHeaderPool ;

	struct
	{
		unsigned long m_pAScanBodyPool[RQ_MAXIMUM_NUMBER_OF_ELEMENTS] ;
		unsigned long m_pBScanTrailerPool ;
		unsigned long m_pGateValuesBodyPool ;
		unsigned long m_pGateValuesTrailerPool ;
	} m_set[RQ_MAXIMUM_NUMBER_OF_CARDS] ;

} g_poolSizes ;

struct
{
	TPoolHandle m_pMemoryBlockNodePool ;
	TPoolHandle m_pRawScanProtectedPool ;
	TPoolHandle m_pDataAHeaderPool ;
	TPoolHandle m_pDataBHeaderPool ;

	struct
	{
		TPoolHandle m_pAScanBodyPool[RQ_MAXIMUM_NUMBER_OF_ELEMENTS] ;
		TPoolHandle m_pBScanTrailerPool ;
		TPoolHandle m_pGateValuesBodyPool ;
		TPoolHandle m_pGateValuesTrailerPool ;
	} m_set[RQ_MAXIMUM_NUMBER_OF_CARDS] ;

} g_poolHandles ;

NDTS_Boolean CALL_CONV RQ_InitRawScanMemoryPools()
{
	memset(&g_poolSizes, 0, sizeof g_poolSizes) ;
	memset(&g_poolHandles, 0, sizeof g_poolHandles) ;

	return NDTS_BTrue ;
}

// This function is called once by DllMain().
NDTS_Boolean CALL_CONV RQ_AllocRawScanStaticMemoryPools()
{
	NDTS_Boolean result = NDTS_BFalse;

	g_poolSizes.m_pMemoryBlockNodePool			= sizeof(RQ_MemoryBlockNode) ;
	g_poolHandles.m_pMemoryBlockNodePool		= RQ_AllocPool(g_poolSizes.m_pMemoryBlockNodePool) ;
	if(g_poolHandles.m_pMemoryBlockNodePool)
	{
		g_poolSizes.m_pRawScanProtectedPool		= sizeof(RQ_RawScanProtected) ;
		g_poolHandles.m_pRawScanProtectedPool	= RQ_AllocPool(g_poolSizes.m_pRawScanProtectedPool) ;
		if(g_poolHandles.m_pRawScanProtectedPool)
		{
			g_poolSizes.m_pDataAHeaderPool		= sizeof(RQ_DataAHeader) ;
			g_poolHandles.m_pDataAHeaderPool	= RQ_AllocPool(g_poolSizes.m_pDataAHeaderPool) ;
			if(g_poolHandles.m_pDataAHeaderPool)
			{
				g_poolSizes.m_pDataBHeaderPool	= sizeof(RQ_DataBHeader) ;
				g_poolHandles.m_pDataBHeaderPool= RQ_AllocPool(g_poolSizes.m_pDataBHeaderPool) ;

				result = NDTS_BTrue ;
			}
		}
	}

	return result;
}

NDTS_Boolean CALL_CONV RQ_AllocRawScanAScanBodyMemoryPool(unsigned long setIndex, unsigned long aScanIndex, unsigned long size)
{
	NDTS_Boolean result = NDTS_BTrue ;

	_ASSERTE(size > 0) ;

	if(g_poolSizes.m_set[setIndex].m_pAScanBodyPool[aScanIndex] != size)
	{
		g_poolSizes.m_set[setIndex].m_pAScanBodyPool[aScanIndex]	= size ;
		g_poolHandles.m_set[setIndex].m_pAScanBodyPool[aScanIndex]	= RQ_AllocPool(size) ;
	}
	return result ;
}

NDTS_Boolean CALL_CONV RQ_AllocRawScanAllAScanBodyMemoryPool(unsigned long setIndex, unsigned long size)
{
	NDTS_Boolean result = NDTS_BTrue ;
	int aScanIndex ;
	TPoolHandle pool ;
	const int numberOfElements = sizeof g_poolHandles.m_set[setIndex].m_pAScanBodyPool /  sizeof g_poolHandles.m_set[setIndex].m_pAScanBodyPool[0] ;
	
	/*
	// *** Mark
	char pChar[256] ;
	sprintf(pChar, "*Mark* Pool size: %d.\n", size) ;
	OutputDebugString(pChar) ;
	*/

	_ASSERTE(size > 0) ;

	pool = RQ_AllocPool(size) ;
	for(aScanIndex = 0; aScanIndex < numberOfElements; ++aScanIndex)
		if(g_poolSizes.m_set[setIndex].m_pAScanBodyPool[aScanIndex] != size)
		{
			g_poolSizes.m_set[setIndex].m_pAScanBodyPool[aScanIndex]	= size ;
			g_poolHandles.m_set[setIndex].m_pAScanBodyPool[aScanIndex]	= pool ;
		}
	return result ;
}

NDTS_Boolean CALL_CONV RQ_AllocRawScanBScanTrailerMemoryPool(unsigned long setIndex, unsigned long size)
{
	NDTS_Boolean result = NDTS_BTrue ;

	_ASSERTE(size > 0) ;

	if(g_poolSizes.m_set[setIndex].m_pBScanTrailerPool != size)
	{
		g_poolSizes.m_set[setIndex].m_pBScanTrailerPool		= size ;
		g_poolHandles.m_set[setIndex].m_pBScanTrailerPool	= RQ_AllocPool(size) ;
	}
	return result ;
}

NDTS_Boolean CALL_CONV RQ_AllocRawScanGateValuesBodyMemoryPool(unsigned long setIndex, unsigned long size)
{
	NDTS_Boolean result = NDTS_BTrue ;

	_ASSERTE(size > 0) ;

	if(g_poolSizes.m_set[setIndex].m_pGateValuesBodyPool != size)
	{
		g_poolSizes.m_set[setIndex].m_pGateValuesBodyPool	= size ;
		g_poolHandles.m_set[setIndex].m_pGateValuesBodyPool	= RQ_AllocPool(size) ;
	}
	return result ;
}

NDTS_Boolean CALL_CONV RQ_AllocRawScanGateValuesTrailerMemoryPool(unsigned long setIndex, unsigned long size)
{
	NDTS_Boolean result = NDTS_BTrue ;

	_ASSERTE(size > 0) ;

	if(g_poolSizes.m_set[setIndex].m_pGateValuesTrailerPool != size)
	{
		g_poolSizes.m_set[setIndex].m_pGateValuesTrailerPool	= size ;
		g_poolHandles.m_set[setIndex].m_pGateValuesTrailerPool	= RQ_AllocPool(size) ;
	}
	return result ;
}

// Functions used to retrieve the memory pools that are used to allocate memory for raw scans.
TPoolHandle CALL_CONV RQ_ReturnRawScanMemoryBlockNodeMemoryPool()
{
	if(g_poolHandles.m_pMemoryBlockNodePool == 0)
		RQ_AllocRawScanStaticMemoryPools() ;

	return g_poolHandles.m_pMemoryBlockNodePool ;
}

TPoolHandle CALL_CONV RQ_ReturnRawScanProtectedMemoryPool()
{
	if(g_poolHandles.m_pRawScanProtectedPool == 0)
		RQ_AllocRawScanStaticMemoryPools() ;

	return g_poolHandles.m_pRawScanProtectedPool ;
}

TPoolHandle CALL_CONV RQ_ReturnRawScanDataAHeaderMemoryPool()
{
	if(g_poolHandles.m_pDataAHeaderPool == 0)
		RQ_AllocRawScanStaticMemoryPools() ;

	return g_poolHandles.m_pDataAHeaderPool ;
}

TPoolHandle CALL_CONV RQ_ReturnRawScanDataBHeaderMemoryPool()
{
	if(g_poolHandles.m_pDataBHeaderPool == 0)
		RQ_AllocRawScanStaticMemoryPools() ;

	return g_poolHandles.m_pDataBHeaderPool ;
}

TPoolHandle CALL_CONV RQ_ReturnRawScanAScanBodyMemoryPool(unsigned long setIndex, unsigned long aScanIndex) 
{
	_ASSERTE(g_poolHandles.m_set[setIndex].m_pAScanBodyPool[aScanIndex]) ;
	return g_poolHandles.m_set[setIndex].m_pAScanBodyPool[aScanIndex] ;
}

TPoolHandle CALL_CONV RQ_ReturnRawScanBScanTrailerMemoryPool(unsigned long setIndex)
{
	_ASSERTE(g_poolHandles.m_set[setIndex].m_pBScanTrailerPool) ;
	return g_poolHandles.m_set[setIndex].m_pBScanTrailerPool ;
}

TPoolHandle CALL_CONV RQ_ReturnRawScanGateValuesBodyMemoryPool(unsigned long setIndex) 
{
	_ASSERTE(g_poolHandles.m_set[setIndex].m_pGateValuesBodyPool) ;
	return g_poolHandles.m_set[setIndex].m_pGateValuesBodyPool ;
}

TPoolHandle CALL_CONV RQ_ReturnRawScanGateValuesTrailerMemoryPool(unsigned long setIndex) 
{
	_ASSERTE(g_poolHandles.m_set[setIndex].m_pGateValuesTrailerPool) ;
	return g_poolHandles.m_set[setIndex].m_pGateValuesTrailerPool ;
}
