//-----------------------------------------------------------------------------
// Copyright (c) 1994,1995 Southeastern Universities Research Association,
//                         Continuous Electron Beam Accelerator Facility
//
// This software was developed under a United States Government license
// described in the NOTICE file included as part of this distribution.
//
//-----------------------------------------------------------------------------
// 
// Description:
//	 Single Linked List for pointers void *
//
//       Note: remove and clean operations on the list
//             will only remove link nodes without removal of
//             the content inside the nodes. It is callers' 
//             responsiblity to clean up those contents
//
//       This is unsafe C++ practice, use this list at you own risk
//       
//       Reason for this list: It is very difficult to instantiate
//       a template class in a stand alone shared library
//	
// Author:  Jie Chen
//       CEBAF Data Acquisition Group
//
//
//
//
#ifndef _RSVC_SLIST_H
#define _RSVC_SLIST_H

#include <stdio.h>
#include <string.h>

#if defined (RSVC_USE_THREAD) && defined (_REENTRANT)
#include <cpSynch.h>
#endif

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>


typedef void*  rsvcSlistItem;

//======================================================================
//	class rsvcSlist
//        Single Linked List for void* pointer
//======================================================================
class rsvcSlistLink;
class rsvcSlistIterator;
class rsvcSlistCursor;
class rsvcHash;

class rsvcSlist
{
public:
  // constructors
  rsvcSlist          (void);
  rsvcSlist          (const rsvcSlist & source);
  virtual ~rsvcSlist (void);

  // operations

  // add list item to the beginning of the list
  virtual void        add               (rsvcSlistItem value);
  // add item to the end of list
  virtual void        addToEnd          (rsvcSlistItem value);

  // remove a list item from the list
  // return 0: nothing to remove
  // return 1: remove success
  virtual int         remove            (rsvcSlistItem value);

  // clean up the list. 
  virtual void        deleteAllValues   (void);

  // return first element of the list
  virtual rsvcSlistItem  firstElement  (void);

  // return last element of the list
  virtual rsvcSlistItem    lastElement (void);

  // duplicate ths whole list
  virtual rsvcSlist*       duplicate   (void);
  
  // check whether this list contains a particular item
  // return 1: yes. return 0: no
  virtual int              includes     (rsvcSlistItem value);

  // Is list empty
  // return 1: yes. return 0: no
  virtual int              isEmpty      (void);

  // remove first element of the list
  virtual void             removeFirst  (void);

  // return number of elements inside the list
  virtual int              count        (void);

protected:
  // data field
  rsvcSlistLink*           ptrToFirstLink;

  // number elements in the list
  int                      count_;

#if defined (RSVC_USE_THREAD) && defined (_REENTRANT)
  cpMutex                  lock_;
#endif

  // some internal functions which must be called with lock held
  virtual void           add_i              (rsvcSlistItem value); 
  virtual int            isEmpty_i          (void) const;
  virtual void           deleteAllValues_i  (void);
  virtual void           removeFirst_i      (void);
  virtual rsvcSlistItem  firstElement_i     (void);
  virtual rsvcSlistItem  lastElement_i      (void);

  // friends
  friend class  rsvcSlistIterator;
  // cannot modify list in anyways
  friend class  rsvcSlistCursor;
  friend class  rsvcHash;

private:
  // deny access to assignment operation
  rsvcSlist&   operator = (const rsvcSlist& list);
};

//======================================================================
//	class rsvcSlistLink
//        Single linked list link node
//======================================================================
class rsvcSlistLink
{
public:
  // constructor
  rsvcSlistLink         (rsvcSlistItem linkValue, rsvcSlistLink * nextPtr);

  // insert a new element following the current value
  rsvcSlistLink* insert (rsvcSlistItem val);
  // return data value
  rsvcSlistItem  data   (void);

  // return next data item
  rsvcSlistLink* next   (void);


private:

  // duplicate
  rsvcSlistLink* duplicate (void);

  // data areas
  rsvcSlistItem      value;
  rsvcSlistLink*     ptrToNextLink;

  // friends
  friend class       rsvcSlist;
  friend class       rsvcSlistIterator;
  friend class       rsvcSlistCursor;
};

//===================================================================
//	class rsvcSlistIterator
//		implements iterator protocol for linked lists
//		also permits removal and addition of elements
//===================================================================

class rsvcHashIterator;

class rsvcSlistIterator
{
public:
  // constructor
  rsvcSlistIterator        (rsvcSlist& aList);

  // iterator protocol
  virtual int              init (void);
  virtual rsvcSlistItem    operator () (void);
  virtual int              operator !  (void);
  virtual int              operator ++ (void);
  virtual void             operator =  (rsvcSlistItem value);

  // new methods specific to list iterators

  // remove current item pointed by the iterator from the list
  void                     removeCurrent(void);
  
  // add an item to the list before the position pointed by the iterator
  void                     addBefore(rsvcSlistItem  newValue);

  // add an item to the list after the position pointed by the iterator
  void                     addAfter(rsvcSlistItem   newValue);

  // search an item and move the iterator to that position
  int                      searchSame(rsvcSlistItem &value);

protected:
  // some internal functions which must be called with lock held
  virtual int              init_i (void);
  // move cursor forward
  virtual int              forward_i (void);
  // internal remove current
  void                     removeCurrent_i (void);
  // data areas
  rsvcSlistLink *    currentLink;
  rsvcSlistLink *    previousLink;
  rsvcSlist&         theList;
#if defined (RSVC_USE_THREAD) && defined (_REENTRANT)
  cpMutex             lock_;
#endif

private:
  // friend class
  friend class rsvcHashIterator;

  // deny access of copy and assignment
  rsvcSlistIterator (const rsvcSlistIterator& ir);
  rsvcSlistIterator& operator = (const rsvcSlistIterator& ir);
};

//===================================================================
//	class rsvcSlistCursor
//		implements cursor protocol for linked lists
//===================================================================
class rsvcSlistCursor
{
public:
  // constructor
  rsvcSlistCursor           (const rsvcSlist& aList);

  // iterator protocol
  virtual int               init        (void);
  virtual rsvcSlistItem     operator () (void);
  virtual int               operator !  (void);
  virtual int               operator ++ (void);
  virtual void              operator =  (rsvcSlistItem value);

  int                       searchSame  (rsvcSlistItem &value);

protected:
  // internal functions which must be called with lock 
  virtual int               init_i      (void);  
  // data areas
  rsvcSlistLink *          currentLink;
  rsvcSlistLink *          previousLink;
  const rsvcSlist&         theList;
#if defined (RSVC_USE_THREAD) && defined (_REENTRANT)
  cpMutex             lock_;
#endif

private:
  // deny access to copy and assignment operations
  rsvcSlistCursor (const rsvcSlistCursor &);
  rsvcSlistCursor& operator = (const rsvcSlistCursor &);
};

//======================================================================
//      class doubleEndedList
//           Not only keeps a pointer to first node
//           but also keeps a pointer to last node
//======================================================================
class rsvcDoubleEndedSlist: public rsvcSlist{
public:
  //constructor
  rsvcDoubleEndedSlist   (void);
  rsvcDoubleEndedSlist   (const rsvcDoubleEndedSlist &v);
  
  // override the following methods from the rsvcSlist
  virtual void      add             (rsvcSlistItem value);
  virtual void      deleteAllValues (void);
  virtual void      removeFirst     (void);

  // add new element to the end of the list
  virtual void      addToEnd        (rsvcSlistItem value);

protected:
  rsvcSlistLink    *ptrToLastLink;

private:
  // deny access to assignment operation
  rsvcDoubleEndedSlist& operator = (const rsvcDoubleEndedSlist);
};

class rsvcQueue: public rsvcDoubleEndedSlist
{
public:
  // constructor and destructor
  rsvcQueue        (void);

  // operations
  rsvcSlistItem    dequeue (void);
  void             enqueue (rsvcSlistItem value);
  rsvcSlistItem    front   (void);

private:
  // deny access to assignment and copy operations
  rsvcQueue             (const rsvcQueue& queue);
  rsvcQueue& operator = (const rsvcQueue& queue);
};
#endif
