//
//  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 
#include 
#include "bool.h"
#include "person.h"

//
//  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) - 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 true.  If the person could not be retrieved (for
//        example, the list is empty), then false is returned.  The
//        "current position" in the list is moved to the second person
//        in the list (if there is one).
//        Parameters:  p  (out) - person retrieved from the list.
//        Returns:     true  - if the person was retrieved successfully.
//                     false - if the person could not be retrieved.
//
//    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
//        true.  If the person could not be retrieved (for example, the
//        person list is empty), then false is returned.  The "current
//        position" in the list is moved to the next person in the list.
//        Parameters:  p  (out) - person retrieved from the list.
//        Returns:     true  - if the person was retrieved successfully.
//                     false - if the person could not be retrieved.
//
//    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);
      bool getFirst(person& p);
      bool getNext(person& p);
      bool atEnd() const;
      void clearList();
      friend ostream& operator<<(ostream& os, const plist& pl);
   private:
      struct element;
      element * head;
      element * current;
      element * newElement(person& p) const;
      void moveToEnd();
};

#endif