/*
 *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 *  SCR_Hash.h
 *  Scripts, Beaudet Christophe
 *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 */
 
#ifndef __SCR_Hash_h__Types
#define __SCR_Hash_h__Types
 
#ifndef __Only_Types__
#define __SCR_Hash_h__Undef
#define __Only_Types__
#endif /* !__Only_Types__ */
 
/*
 *=================================================================================================
 *  Includes.
 *=================================================================================================
 */
#include "SCR_DyAr.h"
 
#ifdef __SCR_Hash_h__Undef
#undef __Only_Types__
#undef __SCR_Hash_h__Undef
#endif /* __HSH_Hash_h__Undef */
 
/*
 *=================================================================================================
 *  Constants.
 *=================================================================================================
 */
 
/*
 *  To export code.
 */
#undef CPA_EXPORT
#if defined(CPA_WANTS_IMPORT)
#define CPA_EXPORT __declspec(dllimport)
#elif defined(CPA_WANTS_EXPORT)
#define CPA_EXPORT __declspec(dllexport)
#else /* CPA_WANTS_IMPORT */
#define CPA_EXPORT
#endif /* CPA_WANTS_IMPORT */
 
/*
 *  To define hash size.
 */
#define SCR_C_ui_Hash_Modulo        256
#define SCR_C_ui_Hash_Size          SCR_C_ui_Hash_Modulo
 
/*
 *=================================================================================================
 *  Types.
 *=================================================================================================
 */
 
/*
 *  Structure that describes a value associated to an hash key code
 */
typedef struct SCR_tdst_Hash_Value_
{
	SCR_tdst_DyAr_Header	stHeader;			/* Header of element */
    unsigned long			ulValue;            /* Hash value */
}  SCR_tdst_Hash_Value;
 
/*
 *  Type that describes an hash table.
 *  It's an array of entries.
 */
typedef SCR_tdst_DyAr_Description	SCR_tda_st_Hash_Table[SCR_C_ui_Hash_Size];
 
/*
 *  Type that describes an hash key. 
 *  It's a indice in a hash table.
 */
typedef unsigned int                SCR_tdx_Hash_Key;
 
#endif /* !__HSH_Hash_h__Types */
 
/*
 *=================================================================================================
 *  Macros.
 *=================================================================================================
 */
 
#if !defined(__SCR_Hash_h__Macros) && !defined(__Only_Types__)
#define __SCR_Hash_h__Macros
 
/*
 *	Simply pack an hash table by just adjusting its size.
 *	_Array	:	Array to realloc.
 */
#define SCR_M_Hash_SimplePackArray(_Array)\
{\
	unsigned int	_Hash_uiPos_;\
	for(_Hash_uiPos_ = 0; _Hash_uiPos_ < SCR_C_ui_Hash_Size; _Hash_uiPos_++)\
	{\
		SCR_M_DyAr_SimplePackArray(SCR_tdst_Hash_Value, _Array[_Hash_uiPos_]);\
	}\
}
 
/*
 *	A macro to reduce the size of an hash table.
 *	_Array		:	Hash table to reduce.
 *	_Cast		:	Cast of an element of linked array.
 *	_Array2		:	Linked array.
 */
#define SCR_M_Hash_PackArray(_Array, _Cast, _Array2, _Field1, _Field2)\
{\
	unsigned int	_Hash_uiPos_, _Hash_uiPos1_;\
	_Cast			*p_stPointer;\
	for(_Hash_uiPos_ = 0; _Hash_uiPos_ < SCR_C_ui_Hash_Size; _Hash_uiPos_++)\
	{\
		SCR_M_DyAr_PackArray\
		(\
			SCR_tdst_Hash_Value,\
			_Array[_Hash_uiPos_],\
			for(_Hash_uiPos1_ = 0; _Hash_uiPos1_ < (_Array2).uiNumValues; _Hash_uiPos1_++)\
			{\
				SCR_M_DyAr_GetElement(_Cast, _Hash_uiPos1_, p_stPointer, _Array2);\
				if(p_stPointer)\
				{\
					if\
					(\
						(p_stPointer->##_Field1 == _Hash_uiPos_)\
					&&	(p_stPointer->##_Field2 == (unsigned int) _DyAr_iEndPos_)\
					)\
						p_stPointer->##_Field2 = _DyAr_iBegPos_;\
				}\
			}\
		);\
	}\
}
 
/*
 *	A macro delete hash values depending on memory level.
 */
#define SCR_M_Hash_DeleteWithMemLevel(_Array, _ucMin, _ucMax)\
{\
	unsigned int	_Hash_uiPos_;\
	for(_Hash_uiPos_ = 0; _Hash_uiPos_ < SCR_C_ui_Hash_Size; _Hash_uiPos_++)\
	{\
		SCR_M_DyAr_DeleteElementWithMemLevel\
		(\
			SCR_tdst_Hash_Value,\
			_Array[_Hash_uiPos_],\
			;,\
			_ucMin,\
			_ucMax\
		);\
	}\
}
 
#endif /* !__SCR_Hash_h__Macros && !__OnlyTypes */
 
/*
 *=================================================================================================
 *  Protos.
 *=================================================================================================
 */
 
#if !defined(__SCR_Hash_h__Protos) && !defined(__Only_Types__)
#define __SCR_Hash_h__Protos
 
extern void                             fn_v_Hash_InitTable(SCR_tda_st_Hash_Table);
extern void                             fn_v_Hash_CloseTable(SCR_tda_st_Hash_Table);
 
CPA_EXPORT extern SCR_tdx_Hash_Key      SCR_fn_x_Hash_ComputeHashKeyForString(char *);
CPA_EXPORT extern SCR_tdx_Hash_Key      SCR_fn_x_Hash_ComputeHashKeyForLong(long);
 
extern SCR_tdst_Hash_Value              *fnp_st_Hash_AddValue(SCR_tdx_Hash_Key, SCR_tda_st_Hash_Table, unsigned long, unsigned int *);
 
#endif /* !__HSH_Hash_h__Protos && !__Only_Types__ */
