/***************************************************************
 * PrHashTable.h
 *
 * This class provides a hash table templete interface.
 *
 * Template class for a generic hash table with chaining.
 *
 ****************************************************************/

/*
 * modification history
 *----------------------
 *
 * 02/19/98: K.C. Chang: created.
 */

#ifndef _PrHashTable_H
#define _PrHashTable_H

#include "PrGlobalDefn.h"
#include "PrHashTableImpl.h"

#define PR_HASHTABLE_SIZE_DEFAULT PR_HASHTABLEIMPL_SIZE_DEFAULT 
#define PR_HASHTABLE_NUM_ITEMS_DEFAULT PR_HASHTABLEIMPL_NUM_ITEMS_DEFAULT 
#define PR_HASHTABLE_NUM_ITEMS_UNLIMITED PR_HASHTABLEIMPL_NUM_ITEMS_UNLIMITED

template <class T, class Key>
class PrHashTable : public PrHashTableImpl
{
public:
    // Equal(x,y) returns (x==y); if (x==y), return 1
    PrHashTable(int (*Equal)(Key *key1,Key *key2), int (*Hash)(Key *key),
		int maxNumItems = PR_HASHTABLE_NUM_ITEMS_DEFAULT,
		int tableSize = PR_HASHTABLE_SIZE_DEFAULT)
      : PrHashTableImpl(maxNumItems,tableSize),Equal_(Equal),Hash_(Hash) {} 

    virtual int equal(void *key1,void *key2) const 
      { return Equal_((Key *)key1,(Key *)key2); }

    virtual int hash(void *key) const 
      { return Hash_((Key *)key); }

    // add item to list, in increasing order with priority
    void newItem (T *m, Key *);

    // delete item from list
    T *deleteItem (Key *key);

    // return number of items in list
    int items () const;

    // check if item is a item of list - returns item if found
    T *item (Key *key) const;

    // return first item in list - NULL if empty
    T *firstItem () const;

    // return next item in list - NULL if end
    T *nextItem () const;

    /*
     * iteration:
     *
     *   item = list.firstItem();
     *   while(item != NULL)
     *     {
     *        //do stuff with item
     *        item = list.nextItem();
     *     }
     */

    int tableSize() const;

  private:
    int (*Equal_)(Key *key1,Key *key2);
    int (*Hash_)(Key *key);
};


/*
 * newItem: add new item to list                               
 */
template <class T, class Key> 
inline void 
PrHashTable<T,Key>::newItem (T *m, Key *key)
{
    PrHashTableImpl::newItem ((void *) m, key);
}

/*
 * deleteItem: delete item from list                           
 */
template <class T, class Key> 
inline T *
PrHashTable<T,Key>::deleteItem (Key *key)
{
    return ((T *) PrHashTableImpl::deleteItem ((void *) key));
}

/*
 * items: return number of items in list                    
 */
template <class T, class Key> 
inline int 
PrHashTable<T,Key>::items () const
{
    return (PrHashTableImpl::items ());
}

/*
 * item: return item if in list                             
 */
template <class T, class Key> 
inline T *
PrHashTable<T,Key>::item (Key *key) const
{
    return ((T *) PrHashTableImpl::item ((void *) key));
}

/*
 * firstItem: return first item in list                        
 */
template <class T, class Key> 
inline T *
PrHashTable<T,Key>::firstItem () const
{
    return ((T *) PrHashTableImpl::firstItem ());
}

/*
 * nextItem: return next item in list                          
 */
template <class T, class Key> 
inline T *
PrHashTable<T,Key>::nextItem () const
{
    return ((T *) PrHashTableImpl::nextItem ());
}

template <class T, class Key> 
inline int 
PrHashTable<T,Key>::tableSize () const
{
  return (PrHashTableImpl::tableSize());
}

#endif // _PrHashTable_h

