
#ifndef STUDENTS
#define STUDENTS

#include <stddef.h> // for NULL
#include <fstream.h> // for ifstream and ofstream

#include "grades.h"

class gradedThingList;
class gradedThing;

class student {
public:

  // This constructor is used to read in student data from a specially 
  // formatted file.  It fills in all the slots from the file, and
  // for each gradedThing in the gradedThingList, it reads in a grade.
  student(ifstream,gradedThingList*);

  // This constructor is used to read in student data from the standard
  // input.  It prompts a user for the values of all the slots, and
  // as above, for each thing in the gradedThingList it prompts for a
  // grade.
  student(gradedThingList*);
  ~student();

  // This function is used to compare the names of two students.
  // It returns 0 if the student passed in has the same first and last
  // name as the student the method is called on.
  // It returns -1 if the lastname, firstname of the student the method is
  // called on comes alphabetically before the lastname, firstname of the
  // student passed as a parameter.
  // It returns 1 if the student passed in comes alphabetically before.
  // No side effects.
  int compareNames(student*);

  // Like the above, except uses strings to compare this student to.
  // no side effects.
  int compareNames(char* first, char* last);

  // Like the above, except compares the string passed in to the
  // SS# slot.  Returns -1, 0, 1 as above..
  // No side effects.
  int compareSSNo(char* ssno);

  // Returns the last name string.  No side effects.
  char* getLastName();
  // Returns the first name string.  No side effects.
  char* getFirstName();
  // Returns the SS# string.  No side effects.
  char* getSSNo();
  
  // returns true (nonzero) if this student has any grades, and
  // false (zero) if there are no grades for this student.
  int anyGrades();
  
  // The follow functions are used to iterate through the grades associated
  // with each student.  They maintain a pointer to the "current" grade.
  // for an example on iterating through a student's gradeList, see the
  // fileio.C file.
  // grades for each student must be stored in the same order as the
  // gradedThings list, in order for the write and read functions is
  // fileio.C to work.  This will happen if you use the addGrade method
  // below for each student whenever you add a new gradedThing.

  // resets the "current" pointer to the first grade in the list.
  // you must call this method before you start any iteration.
  void resetGradeList();
  // returns a point to the current grade in the list.
  // if the pointer is pointing past the last grade, this method will
  // return a NULL pointer.
  grade* currentGrade();
  // moves the pointer to the next grade in the list, and returns it.
  // if there is no next grade in the list, returns a NULL pointer.
  grade* nextGrade();
  
  // The following Methods add a new grade to the list of grades
  // for this student.

  // Given a pointer to an existing instance of grade, this method will
  // add that grade to the end of the student's list of grades.
  // returns the pointer to the new grade (that was passed in)
  grade* addGrade(grade*);

  // creates a new instance of a grade, and
  // given an input stream and a pointer to an instance of a gradedThing,
  // this method will read a new score from the stream and set the
  // gradeFor slot to the gradedThing.
  // returns a pointer to the new grade.
  grade* addGrade(ifstream,gradedThing*);

  // creates a new instance of a grade, and
  // Given a pointer to an instance of gradedThing, this method will
  // prompt the user for a score.
  // returns a pointer to the new grade.
  grade* addGrade(gradedThing*);

private:
  char lastName[21];
  char firstName[21];
  char ssno[12];
  gradeElement *firstGrade;
  gradeElement *lastGrade;
  gradeElement *current;
  
};
  
class studentList;

// you basically should not ever need to access instances of this class.
class studentElement {
public:

  studentElement(student*,studentElement*); // take new student and next
  ~studentElement();
  
  friend studentList;

private:
  studentElement* next;
  student* data;
};

// a list of students.
// The list is always sorted by lastname, firstname using
// insertion sort.
// Your main should probably have an instance of this class to keep
// track of all the students in the class.
class studentList {
public:
  // Iteration methods.  Just like those for students.  See fileio.C
  // for examples of using them.
  int empty();
  void reset();
  student* currentStudent(); 
  student* nextStudent();
  
  // These methods add a student to the list.
  // The new student is instertion-sorted into the list by lastname, firstname

  // Given a pointer to an instance of student, insert it..
  // the student MUST have a lastname and a firstname.
  // returns a pointer to the new student (that was passed in).
  student* addStudent(student*);

  // creates a new student, and given an
  // input stream, will read in the student data from
  // the file..  For each thing in the gradedThingList, it will
  // read a grade (score) from the file.
  // the format of the file requires that the last line NOT end
  // with a newline.
  // returns a pointer to the newly created student
  student* addStudent(ifstream,gradedThingList*);

  // creates a new student, and
  // will prompt the user for all the student info
  // and for a grade for each gradedThing in the list
  // returns a pointer to the newly created student.
  student* addStudent(gradedThingList*);
  
  studentList();
  ~studentList();

private:  // KEEP OUT
  studentElement* current;
  studentElement* first;
};

#endif

