/***************************************************************
 * PrLinkedList.h
 *
 * This class provides a linked list templete interface.
 *
 * Template class for a generic priority list (increasing order).
 *
 ****************************************************************/

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

#ifndef _PrLinkedList_h
#define _PrLinkedList_h

#include "PrGlobalDefn.h"
#include "PrLinkedListImpl.h"

#define PR_LINKEDLIST_SIZE_DEFAULT   PR_LINKEDLISTIMPL_SIZE_DEFAULT   
#define PR_LINKEDLIST_SIZE_UNLIMITED PR_LINKEDLISTIMPL_SIZE_UNLIMITED 

template <class T>
class PrLinkedList : public PrLinkedListImpl
{
public:
    //	   int Compare(T *x, T *y) 
    //		returns 1 if x > y
    //		returns 0 if x == y
    //		returns -1 if x < y

    PrLinkedList(int maxLength = PR_LINKEDLIST_SIZE_DEFAULT,
		 int (*Compare)(T *x,T *y) = NULL) 
      : PrLinkedListImpl(maxLength), Compare_(Compare) {}

    virtual int compare(void *x,void *y) const
      {
	  if (Compare_ == NULL) return 0;
	  else return Compare_((T *)x,(T *)y);
      }

    void newItem (T *m);    // add item to list
    T *deleteItem (T *m);     // delete item from list
    int items () const;     // return number of items in list

    // check if item is a item of list - returns item if found
    T *item (T *m) 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();
     *     }
     */
  private:
    int (*Compare_)(T *x,T *y);
};


/*
 * newItem: add new item to list                               
 */
template <class T> 
inline void 
PrLinkedList<T>::newItem (T *m)
{
    PrLinkedListImpl::newItem ((void *) m);
}

/*
 * deleteItem: delete item from list                           
 */
template <class T> 
inline T *
PrLinkedList<T>::deleteItem (T *m)
{
    return ((T *) PrLinkedListImpl::deleteItem ((void *) m));
}

/*
 * items: return number of items in list                    
 */
template <class T> 
inline int 
PrLinkedList<T>::items () const
{
    return (PrLinkedListImpl::items ());
}

/*
 * item: return item if in list                             
 */
template <class T> 
inline T *
PrLinkedList<T>::item (T *m) const
{
    return ((T *) PrLinkedListImpl::item ((void *) m));
}

/*
 * firstItem: return first item in list                        
 */
template <class T> 
inline T *
PrLinkedList<T>::firstItem () const
{
    return ((T *) PrLinkedListImpl::firstItem ());
}

/*
 * nextItem: return next item in list                          
 */
template <class T> 
inline T *
PrLinkedList<T>::nextItem () const
{
    return ((T *) PrLinkedListImpl::nextItem ());
}

#endif // _PrLinkedList_h

