//
//  NAME
//    plist.h
//
//  DESCRIPTION
//    This file contains the type definitions and function prototypes
//    exported by the Person-List module.
//

#ifndef _plist_h_
#define _plist_h_

//
//  Include files.
//

#include <stdlib.h>
#include <iostream.h>
#include "bool.h"
#include "person.h"


//
//  NAME
//    plistElem
//
//  DESCRIPTION
//    This structure models an element in a person-list.
//

struct plistElem;


//
//  NAME
//    plist
//
//  DESCRIPTION
//    This class models a person-list.
//
//  DATA MEMBERS
//    head     (private) - pointer to the head of the list.
//    current  (private) - pointer to the "current position".
//
//  PUBLIC FUNCTION MEMBERS
//
//    plist()
//        Default constructor.
//        Parameters:  (none)
//        Returns:     (none)
//
//    plist(const plist& otherList)
//        Copy constructor.
//        Parameters:  otherList  (in) - source list.
//        Returns:     (none)
//
//    ~plist
//        Destructor.
//        Parameters:  (none)
//        Returns:     (none)
//
//    operator=
//        Assignment operator.
//        Parameters:  otherList  (in) - source list.
//        Returns:     reference to the destination list.
//
//    addToEnd
//        This function adds the given person to the end of
//        the list.
//        Parameters:  p  (in) - pointer to person to add to the list.
//        Returns:     (none)
//
//    getFirst
//        This function gets the first person in the list.  If
//        the person was retrieved successfully, then the function
//        returns a pointer to that person.  If the person could not
//        be retrieved (for  example, the list is empty), then NULL
//        is returned.  The "current position" in the list is moved
//        to the second person in the list (if there is one).
//        Parameters:  (none)
//        Returns:     pointer to person retrieved from the list.
//
//    getNext
//        This function gets the next person in the person list, that
//        is, the person at the "current position" in the list.  If the
//        person was retrieved successfully, then the function returns
//        a pointer to that person.  If the person could not be
//        retrieved (for example, the person list is empty), then
//        NULL is returned.  The "current position" in the list is moved
//        to the next person in the list.
//        Parameters:  (none)
//        Returns:     pointer to person retrieved from the list.
//
//    atEnd
//        This function determines if the "current position" in the
//        list is at the end of the list.  If this function returns
//        true, then a call to getNext() will return a person.  If
//        this function returns false, then a call to getNext() will
//        not return a person.
//        Parameters:  (none)
//        Returns:     true  - if the "current position" is at the
//                                end of the list.
//                     false - if the "current position" is not at the
//                                end of the list.
//
//    clearList
//        This function empties the list.  After a call to this
//        function, both getFirst() and getNext() will not return
//        a person and atEnd() will return true.
//        Parameters:  (none)
//        Returns:     (none)
//
//  MEMBER TYPES
//    element  (private) - structure of an element used in the list.
//
//  FRIENDS
//    operator<<   - the output operator.
//

class plist {
   public:
      plist();
      plist(const plist& otherList);
      ~plist();
      const plist& operator=(const plist& otherList);
      void addToEnd(person * p);
      person * getFirst();
      person * getNext();
      bool atEnd() const;
      void clearList();
      friend ostream& operator<<(ostream& os, const plist& pl);
   private:
      plistElem * head;
      plistElem * current;
      plistElem * newElem(person * p);
      void moveToEnd();
};


#endif