// CIS22B - "Old" Assignment 3 Solution using structs

#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstdlib>
#include <string>
#include <cstring>
#include <string>
using namespace std;

const unsigned short NumberOfStudents = 50;
const unsigned short PointsPossible = 400;
const unsigned short NumberOfAssignments = 8;

struct Assignments
{
int assignment[NumberOfAssignments];
int assignmentTotal;
};

struct Student
{
int id;
Assignments assignments;
int labExercises;
int midterm;
int final;
int codeLabPoints;
int totalPoints;
int percentOfTotal;
};

struct Class
{
Student students[NumberOfStudents];
};

const string InputFilename = "c:/temp/ass1data.txt";
const string OutputFile1 = "c:/temp/ass2output1.txt";
const string OutputFile2 = "c:/temp/ass2output2.txt";

void readPointsFromFile(const string& filename,Class&);
int  calculateAssTotalPoints(int[]);
void calculateTotalPointsAndPercent(Class&);

void printReport(const string& filename, const Class&);
void printStudentRecord(ostream& out, const Student&);

void sortDataByColumn(Class&, string column = "id", char AscendingDecending = 'A');
void swapStudent(Student& a, Student& b);
void intSwap(int& a, int& b);
void stringSwap(string& a, string& b);

int main()
{
Class students;

calculateTotalPointsAndPercent(students);

printReport(OutputFile1,students);

// sort data by student ID
sortDataByColumn(students);
printReport(OutputFile1,students);

// sort data by total points descending
sortDataByColumn(students,"percent",'D');
printReport(OutputFile2,students);
}

void readPointsFromFile(const string& filename, Class& data)
{
ifstream fin(filename.c_str());

if (!fin)
{
cerr << "Unable to open file, " << InputFilename << endl;
exit(1);
}
for (int i = 0; i < NumberOfStudents; i++)
{
fin >> data.students[i].id;
fin >> data.students[i].labExercises;
for (int j = 0; j < NumberOfAssignments; j++)
{
fin >> data.students[i].assignments.assignment[j];
}
fin >> data.students[i].midterm;
fin >> data.students[i].final;
fin >> data.students[i].codeLabPoints;
}
fin.close();
}

int calculateAssTotalPoints(int data[])
{
int min, sum;
min = data[0];
sum = data[0];

// Determine sum and minimum of first 7 assignments
for (int i = 1; i < NumberOfAssignments-1; i++)
{
if (min > data[i]) min = data[i];
sum += data[i];
}
sum += data[NumberOfAssignments-1] - min;
return sum;
}

void calculateTotalPointsAndPercent(Class& data)
{
for (int i = 0; i < NumberOfStudents; i++)
{
data.students[i].assignments.assignmentTotal = calculateAssTotalPoints(data.students[i].assignments.assignment);
data.students[i].totalPoints = data.students[i].midterm + data.students[i].labExercises + data.students[i].codeLabPoints + data.students[i].final + data.students[i].assignments.assignmentTotal;
// Round points to the nearest int
data.students[i].percentOfTotal = static_cast<int>((100. * data.students[i].totalPoints / PointsPossible +0.5));
}
}

{
for (int i = 0; i < NumberOfStudents; i++)
{
}
}

{
switch (pct/10)
{
case 6:
break;
case 7:
break;
case 8:
break;
case 9:
case 10:
break;
default:
}
if (pct >97) grade += '+';
else if (pct > 59)
{
if (pct % 10 > 7) grade += '+';
if (pct % 10 < 2) grade += '-';
}
}

void printReport(const string& filename, const Class& data)
{
ofstream fout(filename.c_str());

if (!fout)
{
cerr << "Unable to open file, " << filename << endl;
exit(2);
}

fout << "Stdnt Id  Ex  ----- Assignments -----  Tot  Mi  Fin  CL  Pts  Pct  Gr" << endl;
fout << "--------  --  -----------------------  ---  --  ---  --  ---  ---  --" << endl;

for (int i = 0; i < NumberOfStudents; i++)
{
printStudentRecord(fout,data.students[i]);
}
}

void printStudentRecord(ostream& out, const Student& student)
{
out << setfill('0') << setw(8) << right << student.id << setfill(' ') << ' ';
out << setw(3) << student.labExercises << ' ';
for (int i = 0 ; i < NumberOfAssignments; i++)
out << setw(3) << student.assignments.assignment[i];
out << setw(5) << student.assignments.assignmentTotal
<< setw(4) << student.midterm
<< setw(5) << student.final
<< setw(4) << student.codeLabPoints
<< setw(5) << student.totalPoints
<< setw(5) << student.percentOfTotal << "  "
<< setw(2) << left << student.grade << endl;
}

void sortDataByColumn(Class& data, string column, char AscendingDecending)
{
int i, j;
int firstValue, secondValue;
for (i = 0; i < NumberOfStudents - 1; i++)
{
for (j = i+1; j < NumberOfStudents; j++)
{
if (column == "id")
{
firstValue = data.students[i].id;
secondValue = data.students[j].id;
}
else if (column == "percent")
{
firstValue = data.students[i].percentOfTotal;
secondValue = data.students[j].percentOfTotal;
}
if (AscendingDecending == 'A')
{
if (firstValue > secondValue) swapStudent(data.students[i],data.students[j]);
}
else
{
if (firstValue < secondValue) swapStudent(data.students[i],data.students[j]);
}
}
}
}

void    swapStudent(Student& a, Student& b)
{
intSwap(a.id,b.id);
for (int i = 0; i < NumberOfAssignments; i++)
intSwap(a.assignments.assignment[i],a.assignments.assignment[i]);
intSwap(a.labExercises,b.labExercises);
intSwap(a.midterm,b.midterm);
intSwap(a.final,b.final);
intSwap(a.codeLabPoints,b.codeLabPoints);
intSwap(a.totalPoints,b.totalPoints);
intSwap(a.percentOfTotal,b.percentOfTotal);
}

void intSwap(int& a, int& b)
{
int temp = a;
a = b;
b= temp;
}

void stringSwap(string& a, string& b)
{
string temp = a;
a = b;
b= temp;
}