/*
 * hash.c
 * (C) Christian Magnusson 1999, Email: d1mag@dtek.chalmers.se
 * This program is copyright, and covered by the Gnu Public License.
 * The Q bot.
 */
#ifndef HASH_H
#define HASH_H

#include "settings.h"

/*
  This identifies a ListElem type... (filled in at List and HashTable)
*/
#define H_AUSER_NICK    1
#define H_AUSER_YXX     2
#define H_DBUSER_NICK   3
#define H_DBUSER_YXX    4
#define H_DBUSER_USERID 5
#define H_CHANNEL_NAME  6
#define L_AUSER         7
#define L_DBUSER        8
#define L_CHANNEL       9
#define L_GLINE         11
#define H_COMMAND_NAME  12
#define L_CHANTYPE      13
#define L_NICKCHANGE    14
#define L_TRUSTED       15

#define H_MEMBLOCK     100
#define H_MEMSIZE      101
#define L_MEMSTAT      102

typedef struct ListElem
{
  void *data;
  struct ListElem *next;
  struct ListElem *prev;
  struct List *list;
} ListElem;

typedef struct List
{
  int type;
  ListElem *head;
  ListElem *tail;
} List;

typedef struct HashTable
{
  unsigned int sz;
  int hash_type;
#ifdef DMALLOC
  int filler1;
  int filler2;
  int filler3;
#endif
  List *(* list)[];
} HashTable;

extern HashTable *auser_yxx;
extern HashTable *auser_nick;
extern HashTable *channels;
extern HashTable *dbusers_nick;
extern HashTable *dbusers_lastyxx;
extern HashTable *dbusers_userid;
extern HashTable *commands;
extern List *auser_list;
extern List *channel_list;
extern List *dbuser_list;
extern List *gline_list;
extern List *chantype_list;
extern List *nickchange_list;
extern List *trusted_list;

extern HashTable *NewHashTable(int sz, int hash_type);
extern void FreeHashTable(HashTable *); /* free up a list and all the nodes */
void AddElem(HashTable *, ListElem *);
unsigned int Hash(void *, int, int);
unsigned int HashElem(ListElem *, int, int);

ListElem *Find(HashTable *hash, void *data,
	       int (*compare)(const void *, const void *));
extern int compare_strcasecmp(const void *i, const void *j);
extern int compare_strcmp(const void *i, const void *j);
extern int compare_int(const void *i, const void *j);
extern int compare_pointer(const void *i, const void *j);


extern List *NewList(int);   /* initialize a new list */
extern void FreeList(List *); /* free up a list and all the nodes in it */

extern ListElem *NewElem(void *val);
extern void FreeElem(ListElem *);
extern ListElem *GetHead(List *);
extern ListElem *GetTail(List *);
extern ListElem *RemTail(List *);
extern ListElem *GetPred(ListElem *);       /* get predecessor */
extern ListElem *GetSucc(ListElem *);       /* get successor */
extern void Remove(ListElem *);             /* removes node from list */
extern void AddHead(List *list, ListElem *node);
extern void AddTail(List *list, ListElem *node);
extern ListElem *RemHead(List *list); /* remove and return the head */


/*
  some ugly functions to travers a hash! table
*/
ListElem *GetFirstH(HashTable *hash);
ListElem *GetSuccH(HashTable *hash, ListElem *el);

#endif
