/*
 *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 *  SCR_Link.h
 *  Link tables, Beaudet Christophe
 *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 */
 
#ifndef __SCR_Link_h__Types
#define __SCR_Link_h__Types
 
#ifndef __Only_Types__
#define __SCR_Link_h__Undef
#define __Only_Types__
#endif /* !__Only_Types__ */
 
/*
 *=================================================================================================
 *  Includes.
 *=================================================================================================
 */
#include "SCR_DyAr.h"
#include "SCR_Hash.h"
 
#ifdef __SCR_Link_h__Undef
#undef __Only_Types__
#undef __SCR_Link_h__Undef
#endif /* __SCR_Link_h__Undef */
 
/*
 *=================================================================================================
 *  Types.
 *=================================================================================================
 */
 
/*
 * Enum that describes a link state
 */
typedef enum SCR_tde_Link_State_
{
    SCR_ELS_Link_NotInitialized = 0,            /* Value not yet initialized */
    SCR_ELS_Link_Initialized,				    /* Value initialized */
} SCR_tde_Link_State;
 
/*
 *	An additional structure for link values.
 */
typedef struct SCR_tdst_Link_AdditionalInfos_
{
	unsigned long	ulLong1;
	unsigned long	ulLong2;
	unsigned long	ulLong3;
	unsigned long	ulLong4;
} SCR_tdst_Link_AdditionalInfos;
 
/*
 * Type to describe a value to link
 */
typedef struct SCR_tdst_Link_Value_
{
	SCR_tdst_DyAr_Header			stHeader;						/* Header of element */
    char							*p_szKey;						/* Character key */
    unsigned long					ulValue;						/* Value */
    SCR_tdx_Hash_Key				xHashKeyForKey;			        /* To save hash key code of szKey */
    unsigned int					uiIndexHashKeyKey;              /* Index of key hash key */
	SCR_tdx_Hash_Key				xHashKeyForValue;				/* To save hash key code of ulValue */ 
    unsigned int					uiIndexHashKeyValue;            /* Index of value hash key */
	SCR_tde_Link_State				eState;							/* State of this link, initialized or not */
	SCR_tdst_Link_AdditionalInfos	stInfos;						/* Additional informations */
} SCR_tdst_Link_Value;
 
/*
 *  Type to describe a link table.
 */
typedef struct SCR_tdst_Link_Table_
{
	SCR_tdst_DyAr_Header		stHeader;					/* Header of element */
	SCR_tdst_DyAr_Description	stLinkArray;				/* Array of links */
	SCR_tda_st_Hash_Table		a_stHashTableForValues;		/* Hash table to find link from value */
	SCR_tda_st_Hash_Table		a_stHashTableForKeys;		/* Hash table to find link from char key */
} SCR_tdst_Link_Table;
 
/*
 * Callback for loading a linktable.
 */
typedef void (* SCR_tdpfn_Link_Callback)(SCR_tdst_Link_Value *);
 
#endif /* !__SCR_Link_h__Types */
 
/*
 *=================================================================================================
 *  Global variables.
 *=================================================================================================
 */
 
#if !defined(__SCR_Link_h__Globals) && !defined(__Only_Types__)
#define __SCR_Link_h__Globals
 
CPA_EXPORT extern SCR_tdst_DyAr_Description     SCR_g_st_Link_Array;
 
#endif /* !__SCR_Link_h__Globals && !__OnlyTypes */
 
/*
 *=================================================================================================
 *  Macros.
 *=================================================================================================
 */
 
#if !defined(__SCR_Link_h__Macros) && !defined(__Only_Types__)
#define __SCR_Link_h__Macros
 
/*
 *  To access field of the link structure.
 *  _Struct :   Structure to access.
 */
#define SCR_M_ul_Link_GetValue(_Struct)\
    ((_Struct)->ulValue)
#define SCR_M_p_sz_Link_GetKey(_Struct)\
    ((_Struct)->p_szKey)
#define SCR_M_e_Link_GetState(_Struct)\
    ((_Struct)->eState)
#define SCR_M_uc_Link_GetMemLevel(_Struct)\
    ((_Struct)->stHeader.ucMemLevel)
 
/*
 *	For additional informations.
 */
#define SCR_M_v_Link_SetAdditionalLong(_Struct, _Num, _Long)\
	{(_Struct)->stInfos.ulLong##_Num = (_Long);}
#define SCR_M_ul_Link_GetAdditionalLong(_Struct, _Num)\
	((_Struct)->stInfos.ulLong##_Num)
 
/*
 *	To get a link table dynamic array
 */
#define SCR_M_st_Link_GetDynamicArray(_LinkTable)\
	((_LinkTable)->stLinkArray)
 
#endif /* __SCR_Link_h__Macros */
 
/*
 *=================================================================================================
 *  Protos.
 *=================================================================================================
 */
 
#if !defined(__SCR_Link_h__Protos) && !defined(__Only_Types__)
#define __SCR_Link_h__Protos
 
extern void								fn_v_Link_InitModule(void);
extern void								fn_v_Link_CloseModule(void);
 
CPA_EXPORT extern void                  SCR_fn_v_Link_InitTable(SCR_tdst_Link_Table *);
CPA_EXPORT extern void                  SCR_fn_v_Link_CloseTable(SCR_tdst_Link_Table *);
 
CPA_EXPORT extern SCR_tdst_Link_Value   *SCR_fnp_st_Link_AddEntry(SCR_tdst_Link_Table *, char *, unsigned long, SCR_tde_Link_State);
 
CPA_EXPORT extern SCR_tdst_Link_Value   *SCR_fnp_st_Link_CreateOrGetLinkFromKey(SCR_tdst_Link_Table *, char *);
CPA_EXPORT extern SCR_tdst_Link_Value   *SCR_fnp_st_Link_SetValue(SCR_tdst_Link_Table *, char *, unsigned long);
 
CPA_EXPORT extern SCR_tdst_Link_Value   *SCR_fnp_st_Link_SearchKey(SCR_tdst_Link_Table *, char *);
CPA_EXPORT extern SCR_tdst_Link_Value   *SCR_fnp_st_Link_SearchValue(SCR_tdst_Link_Table *, unsigned long);
 
CPA_EXPORT extern void					SCR_fn_v_Link_DeleteEntry(SCR_tdst_Link_Table *, SCR_tdst_Link_Value *);
 
CPA_EXPORT extern void					SCR_fn_v_Link_SaveOnDisk(char *_p_szName, SCR_tdst_Link_Table *_p_stLink);
CPA_EXPORT extern void					SCR_fn_v_Link_SaveOnDiskWithCallBack(char *_p_szName, SCR_tdst_Link_Table *_p_stLink, SCR_tdpfn_Link_Callback);
CPA_EXPORT extern void					SCR_fn_v_Link_LoadFromDisk(char *_p_szName, SCR_tdst_Link_Table *_p_stLink);
CPA_EXPORT extern void					SCR_fn_v_Link_LoadFromDiskWithCallBack(char *_p_szName, SCR_tdst_Link_Table *_p_stLink, SCR_tdpfn_Link_Callback);
 
extern void								fn_v_Link_ReduceMemory(void);
extern void								fn_v_Link_DeleteWithMemLevel(unsigned char, unsigned char);
 
#endif /* !__SCR_Link_h__Protos && !__Only_Types__ */
