// Ten plik zawiera pen wersj "Podstawowego schematu klasy" dla klasy studentRecord

#include <string>
using std::string;
#include <iostream>
using std::cout;

class studentRecord {
public:
   studentRecord();
   studentRecord(int newGrade, int newID, string newName);
   int grade();
   void setGrade(int newGrade);
   int studentID();
   void setStudentID(int newID);
   string name();
   void setName(string newName);
private:
   int _grade;
   int _studentID;
   string _name;
};

studentRecord::studentRecord() {
   setGrade(0);
   setStudentID(-1);
   setName("");
}

studentRecord::studentRecord(int newGrade, int newID, string newName) {
   setGrade(newGrade);
   setStudentID(newID);
   setName(newName);
}

int studentRecord::grade() {
   return _grade;
}

void studentRecord::setGrade(int newGrade) {
   if ((newGrade >= 0) && (newGrade <= 100)) 
      _grade = newGrade;
}

string studentRecord::name() {
   return _name;
}

void studentRecord::setName(string newName) {
   _name = newName;
}

int studentRecord::studentID() {
   return _studentID;
}

void studentRecord::setStudentID(int newID) {
   _studentID = newID;
}

int main() {
   // podstawowy kod testujcy
   studentRecord sr(88, 1653, "Artur Studencki");
   cout << sr.grade() << "\n";
   cout << sr.studentID() << "\n";
   cout << sr.name() << "\n";

   return 0;
}

---

// Ten plik zawiera klas studentRecord razem z jej metodami wspierajcymi

#include <string>
using std::string;
#include <iostream>
using std::cout;

class studentRecord {
public:
   studentRecord();
   studentRecord(int newGrade, int newID, string newName);
   int grade();
   void setGrade(int newGrade);
   int studentID();
   void setStudentID(int newID);
   string name();
   void setName(string newName);
   string letterGrade();
protected:
   bool isValidGrade(int grade);
private:
   int _grade;
   int _studentID;
   string _name;
};

studentRecord::studentRecord() {
   setGrade(0);
   setStudentID(-1);
   setName("");
}

studentRecord::studentRecord(int newGrade, int newID, string newName) {
   setGrade(newGrade);
   setStudentID(newID);
   setName(newName);
}

int studentRecord::grade() {
   return _grade;
}

void studentRecord::setGrade(int newGrade) {
   if (isValidGrade(newGrade)) 
      _grade = newGrade;
}

string studentRecord::name() {
   return _name;
}

void studentRecord::setName(string newName) {
   _name = newName;
}

int studentRecord::studentID() {
   return _studentID;
}

void studentRecord::setStudentID(int newID) {
   _studentID = newID;
}

bool studentRecord::isValidGrade(int grade) {
   if ((grade >= -1) && (grade <= 100)) 
      return true;
   else 
      return false;
}

string studentRecord::letterGrade() {
   if (!isValidGrade(_grade)) return "BD";
   const int numberCategories = 9;
   const string gradeLetter[] = {"2", "3-", "3", "3+", "4-", "4", "4+", "5-", "5"};
   const int lowestGradeScore[] = {0, 61, 66, 71, 76, 81, 86, 91, 96};
   int category = 0;
   while (category < numberCategories && lowestGradeScore[category] <= _grade)
      category++;
   return gradeLetter[category - 1];
}

int main() {
   // podstawowy kod testujcy
   studentRecord sr(88, 1653, "Artur Studencki");
   cout << sr.grade() << "\n";
   cout << sr.studentID() << "\n";
   cout << sr.name() << "\n";
   cout << sr.letterGrade() << "\n";

   return 0;
}

---

// Ten plik zawiera klas studentCollection razem ze wszystkimi dodatkami, zaprezentowanymi w ksice

#include <string>
using std::string;
#include <iostream>
using std::cout;

// Poniej znajduje si pena wersja klasy studentRecord, wykorzystywana przez klas studentCollection

class studentRecord {
public:
   studentRecord();
   studentRecord(int newGrade, int newID, string newName);
   int grade();
   void setGrade(int newGrade);
   int studentID();
   void setStudentID(int newID);
   string name();
   void setName(string newName);
   string letterGrade();
protected:
   bool isValidGrade(int grade);
private:
   int _grade;
   int _studentID;
   string _name;
};

studentRecord::studentRecord() {
   setGrade(0);
   setStudentID(-1);
   setName("");
}

studentRecord::studentRecord(int newGrade, int newID, string newName) {
   setGrade(newGrade);
   setStudentID(newID);
   setName(newName);
}

int studentRecord::grade() {
   return _grade;
}

void studentRecord::setGrade(int newGrade) {
   if ((newGrade >= 0) && (newGrade <= 100)) 
      _grade = newGrade;
}

string studentRecord::name() {
   return _name;
}

void studentRecord::setName(string newName) {
   _name = newName;
}

int studentRecord::studentID() {
   return _studentID;
}

void studentRecord::setStudentID(int newID) {
	_studentID = newID;
}

bool studentRecord::isValidGrade(int grade) {
   if ((grade >= -1) && (grade <= 100)) 
      return true;
   else 
      return false;
}

string studentRecord::letterGrade() {
   if (!isValidGrade(_grade)) return "BD";
   const int numberCategories = 9;
   const string gradeLetter[] = {"2", "3-", "3", "3+", "4-", "4", "4+", "5-", "5"};
   const int lowestGradeScore[] = {0, 61, 66, 71, 76, 81, 86, 91, 96};
   int category = 0;
   while (category < numberCategories && lowestGradeScore[category] <= _grade)
      category++;
   return gradeLetter[category - 1];
}

// Deklaracja klasy studentCollection

class studentCollection {
private:
   struct studentNode {
      studentRecord studentData;
      studentNode * next;
    };
public:
   studentCollection();
   ~studentCollection();
   studentCollection(const studentCollection &copy);
   studentCollection& operator=(const studentCollection &rhs);
   void addRecord(studentRecord newStudent);
   studentRecord recordWithNumber(int IDnum);
   void removeRecord(int IDnum);
private:
   typedef studentNode * studentList;
   studentList _listHead;
   void deleteList(studentList &listPtr);
   studentList copiedList(const studentList copy);
};

studentCollection::studentCollection() {
   _listHead = NULL;
}

void studentCollection::deleteList(studentList &listPtr) {
   while (listPtr != NULL) {
      studentNode * temp = listPtr;
      listPtr = listPtr->next;
      delete temp;
	}
}

studentCollection::~studentCollection() {
   deleteList(_listHead);
}

studentCollection::studentList studentCollection::copiedList(const studentList copy) {
   if (copy == NULL) {
      return NULL;
   }
   studentList newList = new studentNode;
   newList->studentData = copy->studentData;
   studentNode * oldLoopPtr = copy->next;
   studentNode * newLoopPtr = newList;
   while (oldLoopPtr != NULL) {
      newLoopPtr->next = new studentNode;
      newLoopPtr = newLoopPtr->next;
      newLoopPtr->studentData = oldLoopPtr->studentData;
      oldLoopPtr = oldLoopPtr->next;
   }
   newLoopPtr->next = NULL;
   return newList;
}

studentCollection::studentCollection(const studentCollection &copy) {
   _listHead = copiedList(copy._listHead);
}

studentCollection& studentCollection::operator=(const studentCollection &rhs) {
   if (this != &rhs) {
      deleteList(_listHead);
      _listHead = copiedList(rhs._listHead);
   }
   return *this;
}

void studentCollection::addRecord(studentRecord newStudent) {
   studentNode * newNode = new studentNode;
   newNode->studentData = newStudent;
   newNode->next = _listHead;
   _listHead = newNode;
}

void studentCollection::removeRecord(int IDnum) {
   studentNode * loopPtr = _listHead;
   studentNode * trailing = NULL;
   while (loopPtr != NULL && loopPtr->studentData.studentID() != IDnum) {
      trailing = loopPtr;
      loopPtr = loopPtr->next;
   }
   if (loopPtr == NULL) return;
   if (trailing == NULL) {
      _listHead = _listHead->next;
   } else {
      trailing->next = loopPtr->next;
   }
   delete loopPtr;
}

studentRecord studentCollection::recordWithNumber(int IDnum) {
   studentNode * loopPtr = _listHead;
   while (loopPtr != NULL && loopPtr->studentData.studentID() != IDnum) {
      loopPtr = loopPtr->next;
   }
   if (loopPtr == NULL) {
      studentRecord dummyRecord(-1, -1, "");
      return dummyRecord;
   } else {
      return loopPtr->studentData;
   }
}

int main() {
   // kod testujcy
   studentCollection s;
   studentRecord stu3(84, 1152, "Alicja");
   studentRecord stu2(75, 4875, "Robert");
   studentRecord stu1(98, 2938, "Tomasz");
   s.addRecord(stu3);
   s.addRecord(stu2);
   s.addRecord(stu1);
   s.removeRecord(4875);
   studentRecord testRetrieve = s.recordWithNumber(2938);
   cout << testRetrieve.name() << "\n";

   return 0;
}