#ifndef _steve_hash_h
#define _steve_hash_h

#include "lt-defs.h"

#ifdef __cplusplus
/* The standard template library uses these names as types */
#define hash xxx_hash
#define list xxx_list
#endif

/* Maps keys (which are sequences of Char) to void *.
 * Functions ending X take a length argument which is length of key in Chars.
 */

typedef struct HashList
{
    struct HashList  *next;	  /* next element in hash */
    const Char *word;		  /* key of the element */
    int length;                   /* length of hash key used */
    void * index;		  /* the actual hash entry. NB this is
                                     a (void *), when using one should 
                                     cast into whatever type of pointer
                                     or scalar you want. */
} HashList;

/*--------   PUBLIC INTERFACE -------------*/
typedef struct HashTab
{
    HashList **table;  /* hash table */
    int size;          /* size of hash table */
    int n_items;		/* number of distinct items */
} HashTab;

/*  creates new HASH structure with HASHTABLESIZE 3000 table size */
extern STD_API HashTab * EXPRT NewHashStruct( );

/*  creates new HASH structure with HASHTABLESIZE n table size */
extern STD_API HashTab * EXPRT NewSizedHashStruct( int );

/* creates  HASH of n TABLESIZE and stores keys */
extern STD_API HashTab * EXPRT HashNLabels(int n, const Char **list);

/* finds element with key key in HASH tab */
extern STD_API HashList * EXPRT FindWordInTable(const HashTab *tab, const Char *key);
extern STD_API HashList * EXPRT FindWordInTableX(const HashTab *hash,
				  const Char *word, int length);
extern STD_API HashList * EXPRT WordEntryInList(HashList *list,const Char *word,
			  int length, HashTab *hash);

/* adds element with key word to HASH hash. The word's memory is NOT  copied */
extern STD_API HashList * EXPRT AddWordToTable(HashTab *hash, const Char *word);
extern STD_API HashList * EXPRT AddWordToTableX(HashTab *hash, const Char *word, int length);
extern STD_API HashList * EXPRT AddWordToTableXM(HashTab *hash, const Char *word, int length);

extern STD_API HashList * EXPRT WordEntryInTableX(HashTab *hash,
				  const Char *word,int length);

extern STD_API boolean  EXPRT MapHashLists(HashTab *hash,boolean(*fn)(const HashList*));
extern STD_API boolean  EXPRT MapHashLists1(HashTab *hash,boolean(*fn)(const HashList*, void*), void *arg);

/*  Free all allocated by HASH memeory */
extern STD_API int  EXPRT FreeHashStruct( HashTab *hash );
extern STD_API int  EXPRT FreeHashStructM( HashTab *hash, int free_values );

/*  Deletes hashed element but doesn't free it,
    so it can be reused for another */
extern STD_API void  EXPRT FreeHashListEl(HashTab *hash,HashList* hle);

#ifdef __cplusplus
#undef hash
#undef list
#endif

#define _steve_hash_h

#endif
