#ifdef UEMF
	#include	"uemf.h"
#else
	#include	"basic/basicInternal.h"
#endif

static int		calcPrime(int size);

typedef struct {						
	int		inuse;						
	int		hash_size;					
	sym_t	**hash_table;				
} sym_tabent_t;

static int symMax;				
static int hashIndex(sym_tabent_t *tp, char_t *name);
static int htIndex;			
static sym_t *hash(sym_tabent_t *tp, char_t *name);
static sym_t *next;				
static sym_tabent_t **sym;				

sym_fd_t symOpen(int hash_size)
{
	sym_fd_t		sd;
	sym_tabent_t	*tp;

	a_assert(hash_size > 2);

	if ((sd = hAlloc((void***) &sym)) < 0) {
		return -1;
	}

	if ((tp = (sym_tabent_t*) balloc(B_L, sizeof(sym_tabent_t))) == NULL) {
		symMax = hFree((void***) &sym, sd);
		return -1;
	}
	memset(tp, 0, sizeof(sym_tabent_t));
	if (sd >= symMax) {
		symMax = sd + 1;
	}
	a_assert(0 <= sd && sd < symMax);
	sym[sd] = tp;

	tp->hash_size = calcPrime(hash_size);
	tp->hash_table = (sym_t**) balloc(B_L, tp->hash_size * sizeof(sym_t*));
	a_assert(tp->hash_table);
	if(tp->hash_table)
	memset(tp->hash_table, 0, tp->hash_size * sizeof(sym_t*));

	return sd;
}

void symClose(sym_fd_t sd)
{
	sym_tabent_t	*tp;
	sym_t			*sp, *forw;
	int				i;

	a_assert(0 <= sd && sd < symMax);
	tp = sym[sd];
	a_assert(tp);

	for (i = 0; i < tp->hash_size; i++) {
		for (sp = tp->hash_table[i]; sp; sp = forw) {
			forw = sp->forw;
			valueFree(&sp->name);
			valueFree(&sp->content);
			bfree(B_L, (void*) sp);
			sp = forw;
		}
	}
	bfree(B_L, (void*) tp->hash_table);

	symMax = hFree((void***) &sym, sd);
	bfree(B_L, (void*) tp);
}

sym_t* symFirst(sym_fd_t sd)
{
	sym_tabent_t	*tp;
	sym_t			*sp, *forw;
	int				i;

	a_assert(0 <= sd && sd < symMax);
	tp = sym[sd];
	a_assert(tp);

	for (i = 0; i < tp->hash_size; i++) {

#if 0	// KW 3 cov M
		for (sp = tp->hash_table[i]; sp; sp = forw) {
			forw = sp->forw;

			if (forw == NULL) {
				htIndex = i + 1;
				next = tp->hash_table[htIndex];
			} else {
				htIndex = i;
				next = forw;
			}
			return sp;
		}
#else
        sp = tp->hash_table[i];
        if(NULL != sp){
			forw = sp->forw;

			if (forw == NULL) {
				htIndex = i + 1;
				next = tp->hash_table[htIndex];
			} else {
				htIndex = i;
				next = forw;
			}
			return sp;
		}
			
#endif
	}
	return NULL;
}

sym_t* symNext(sym_fd_t sd)
{
	sym_tabent_t	*tp;
	sym_t			*sp, *forw;
	int				i;

	a_assert(0 <= sd && sd < symMax);
	tp = sym[sd];
	a_assert(tp);

	for (i = htIndex; i < tp->hash_size; i++) {

#if 0 // kw 3 cov M	
		for (sp = next; sp; sp = forw) {
			forw = sp->forw;

			if (forw == NULL) {
				htIndex = i + 1;
				next = tp->hash_table[htIndex];
			} else {
				htIndex = i;
				next = forw;
			}
			return sp;
		}
#else
        sp = next;
        if(NULL != sp) {
        	forw = sp->forw;
        
        	if (forw == NULL) {
        		htIndex = i + 1;
        		next = tp->hash_table[htIndex];
        	} else {
        		htIndex = i;
        		next = forw;
        	}
        	return sp;
        }

#endif
		next = tp->hash_table[i + 1];
	}
	return NULL;
}


sym_t *symEnter(sym_fd_t sd, char_t *name, value_t v, int arg)
{
	sym_tabent_t	*tp;
	sym_t			*sp, *last;
	char_t			*cp;
	int				hindex;

	a_assert(name);
	a_assert(0 <= sd && sd < symMax);
	tp = sym[sd];
	a_assert(tp);

	last = NULL;
	hindex = hashIndex(tp, name);
	if ((sp = tp->hash_table[hindex]) != NULL) {
		for (; sp; sp = sp->forw) {
			cp = sp->name.value.string;
			if (cp[0] == name[0] && gstrcmp(cp, name) == 0) {
				break;
			}
			last = sp;
		}
		if (sp) {

			if (sp->content.valid) {
				valueFree(&sp->content);
			}
			sp->content = v;
			sp->arg = arg;
			return sp;
		}

		sp = (sym_t*) balloc(B_L, sizeof(sym_t));
		if (sp == NULL) {
			return NULL;
		}
		sp->content = v;
		sp->forw = (sym_t*) NULL;
		sp->name = valueString(name, VALUE_ALLOCATE);
		sp->arg = arg;
		last->forw = sp;

	} else {
		sp = (sym_t*) balloc(B_L, sizeof(sym_t));
		if (sp == NULL) {
			return NULL;
		}
		tp->hash_table[hindex] = sp;
		tp->hash_table[hashIndex(tp, name)] = sp;

		sp->arg = arg;
		sp->content = v;
		sp->name = valueString(name, VALUE_ALLOCATE);
		sp->forw = (sym_t*) NULL;
	}
	return sp;
}

sym_t *symLookup(sym_fd_t sd, char_t *name)
{
	sym_tabent_t	*tp;
	sym_t			*sp;
	char_t			*cp;

	a_assert(0 <= sd && sd < symMax);
	if ((tp = sym[sd]) == NULL) {
		return NULL;
	}

	if (name == NULL || *name == '\0') {
		return NULL;
	}


	for (sp = hash(tp, name); sp; sp = sp->forw) {
		cp = sp->name.value.string;
		if (cp[0] == name[0] && gstrcmp(cp, name) == 0) {
			break;
		}
	}
	return sp;
}

int symDelete(sym_fd_t sd, char_t *name)
{
	sym_t			*last = NULL;
	int				hindex;
	char_t			*cp;
	sym_t			*sp;
	sym_tabent_t	*tp;

	a_assert(name && *name);
	a_assert(0 <= sd && sd < symMax);
	tp = sym[sd];
	a_assert(tp);

	hindex = hashIndex(tp, name);
	if ((sp = tp->hash_table[hindex]) != NULL) {
		for ( ; sp; sp = sp->forw) {
			cp = sp->name.value.string;
			if (cp[0] == name[0] && gstrcmp(cp, name) == 0) {
				break;
			}
			last = sp;
		}
	}
	if (sp == (sym_t*) NULL) {				
		return -1;
	}

	if (last) {
		last->forw = sp->forw;
	} else {
		tp->hash_table[hindex] = sp->forw;
	}
	valueFree(&sp->name);
	valueFree(&sp->content);
	bfree(B_L, (void*) sp);

	return 0;
}



static int hashIndex(sym_tabent_t *tp, char_t *name)
{
	unsigned int	sum;
	int				i;

	a_assert(tp);

	i = 0;
	sum = 0;
	while (*name) {
		sum += (((int) *name++) << i);
		i = (i + 7) % (BITS(int) - BITSPERBYTE);
	}
	return sum % tp->hash_size;
}

static int isPrime(int n)
{
	int		i, max;

	a_assert(n > 0);

	max = n / 2;
	for (i = 2; i <= max; i++) {
		if (n % i == 0) {
			return 0;
		}
	}
	return 1;
}

static sym_t *hash(sym_tabent_t *tp, char_t *name)
{
	a_assert(tp);

	return tp->hash_table[hashIndex(tp, name)];
}

static int calcPrime(int size)
{
	int count;

	a_assert(size > 0);

	for (count = size; count > 0; count--) {
		if (isPrime(count)) {
			return count;
		}
	}
	return 1;
}

