#ifndef HASHTBL_H
#define HASHTBL_H

#include <stdlib.h>

typedef struct
{
	char** entry;
	int* freq;
	int maxsize;
	int currsize;
	int maxFreq;
	char* maxFreqStr;
} HashTable;

int Hash (HashTable* hash, char* str)
{
	int hashval = 0, tablesize = hash->maxsize;
	int j;

	for (j = 0; j < 2; j++)
		hashval = 37 * hashval + str[j];

	hashval %= tablesize;
	if (hashval < 0)
		hashval += tablesize;

	return hashval;
}

int InitHashTable (HashTable* hash, int size)
{
	int j;

	hash->entry = (char**) malloc (size * sizeof(char*));
	hash->freq = (int*) malloc (size * sizeof(int));

	if (hash->entry == NULL || hash->freq == NULL)
		return -1;

	hash->maxsize = size;
	hash->currsize = 0;
	hash->maxFreq = 0;
	hash->maxFreqStr = NULL;

	/* initialize the pointers to NULL */
	for (j = 0; j < hash->maxsize; j++)
	{
		hash->entry[j] = NULL;
		hash->freq[j] = 0;
	}
	
	return 0;
}

void FreeHashTable (HashTable* hash)
{
	free (hash->entry);
	free (hash->freq);
}

int AddPtrEntry (HashTable* hash, char* str)
{
	int index, iter = 0;

	index = Hash (hash, str);

	/* deal with collisions: step through, until either the
	next empty slot is encountered, or the whole table is traversed */
	while (hash->entry[index] != NULL && iter < hash->maxsize)
	{
		index++; iter++;
		if (index == hash->maxsize)
			index = 0;
	}

	if (iter == hash->maxsize)
		return -1;

	hash->entry[index] = str;
	(hash->freq[index])++;

	if (hash->freq[index] > hash->maxFreq)
	{
		hash->maxFreq = hash->freq[index];
		hash->maxFreqStr = str;
	}

	hash->currsize++;
	return 0;
}

int FindIndex (HashTable* hash, char* str)
{
	int index, iter = 0;

	index = Hash (hash, str);

	/* deal with collisions: step through, until either the
	next empty slot is encountered, or the whole table is traversed */
	while (hash->entry[index] != NULL && 
		strncmp(hash->entry[index], str, 2) != 0 && 
		iter < hash->maxsize)
	{
		index++; iter++;
		if (index == hash->maxsize)
			index = 0;
	}

	if (iter == hash->maxsize || hash->entry[index] == NULL)
		return -1;

	return index;
}

void IncrFreq (HashTable* hash, int index)
{
	(hash->freq[index])++;

	if (hash->freq[index] > hash->maxFreq)
	{
		hash->maxFreq = hash->freq[index];
		hash->maxFreqStr = hash->entry[index];
	}
}

#endif


