#ifndef _HASH_H_
#define _HASH_H_

#include <stdlib.h>
#include <stddef.h>

#define E_BADINPUT 	-1
#define	E_NOTFOUND 	-2
#define E_END		-3
#define E_NOMEM		-4
#define E_NORESULT	-5

#define E_CANT_CALCULATE -100

#define HASH_SIZE	256

typedef struct{
	void* next;
	void* ptr;
} Node;

typedef int (*ThFn)(const void*, const void*);

typedef struct{
	Node* arr[HASH_SIZE];
	unsigned char curHash;	/* current element of arr */
	Node* curNode;		/* current node in arr[curHash] */
	unsigned char (* hFn)(const void*); 	/* hash function */
	void* (* newFn)();			/* operator new */
	int (* eqFn)(const void*, const void*); /* operator == */
	void (* cpFn)(void*, const void*); 	/* copy ctor */
} Hash;

typedef struct{
	Node* curNode;
	unsigned char curHash;
	void* ptr;
} Iterator;


/* Update the node satisfying the eqFn or insert if not*/
int upsertHash(Hash* h, const void* ptr);

/* Find first node with hash func like ptr and satisfying the eqFn */
int findFirstHash(Hash* h, const void* ptr, ThFn eqFn, Iterator* it);

/* Find next node with hash func like ptr and satisfying the eqFn */
int findNextHash(Hash* h, const void* ptr, ThFn eqFn, Iterator* it);

/* Return first node in the hash */
int getFirstHash(Hash* h, Iterator* it);

/* Return next node in the hash */
int getNextHash(Hash* h, Iterator* it);

#if 0
/* Return first node with next key in the hash */
int getFirstInNextHash(Hash* h, Iterator* it);
#endif

/* Find first node satisfying the flFn */
int getFirstHashFilter(Hash* h, const void* ptr, ThFn flFn, Iterator* it);

/* Find next node satisfying the flFn */
int getNextHashFilter(Hash* h, const void* ptr, ThFn flFn, Iterator* it);

/* Copy one hash to another */
int copyHash(Hash* src, Hash* trg);

#endif
