#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "grades.h"

GROUP_NODE *push(GROUP_NODE *group,const char *name, float grade)
{
	GRADE_NODE *tmp;
	tmp = new_grade_node(name,grade);
	if(!group->grades)
	{
		group->grades = tmp; /*make it the head*/
		tmp = NULL;
	}
	else
	{
		tmp->next = group->grades; /*make it the head*/
		group->grades = tmp;	   /*and attach the old stack*/
		tmp = NULL;		   /*to it*/
	}
	return group;
}

GROUP_NODE *pop(GROUP_NODE *group)
{
	GRADE_NODE *tmp, *temp;
	if((!group) || (!group->grades))
		return NULL;
	else
	{
		tmp = group->grades->next; /*tmp gets the 2nd in the stack*/
		temp = group->grades;	   /*temp gets the first*/
		temp->next = NULL;	   /*detach temp*/
		free(temp);		   /*free temp*/
		temp = NULL;		   /*move temp away*/
		group->grades = tmp;	   /*tmp is the 2nd; make it the 1st*/
		tmp = NULL;		   /*move tmp away*/
	}
	return group;
}

float average(GRADE *grades)
{
	GROUP_NODE *group = grades->grades;
	float aver = 0.0;
	while(group)
	{
		aver += aver_group(group);
		group = group->next;
	}
	return aver;
}

float aver_group(GROUP_NODE *group)
{
	float aver;
	aver = aver_grades(group->grades);
	aver *= group->weight;
	return aver;
}

float aver_grades(GRADE_NODE *grades)
{
	float aver = 0.0;
	int count = 0;
	GRADE_NODE *tmp = grades;
	while(tmp)
	{
		aver += tmp->grade;
		count++;
		tmp = tmp->next;
	}
	aver /= count;
	return aver;
}

int generate_report(GRADE *grades, FILE *file)
{
	GROUP_NODE *group = grades->grades;
	if(!file)
		return 0;
	fprintf(file,"Class: %s\n",grades->course);
	fprintf(file,"Student: %s\n",grades->student);
	fprintf(file,"Teacher: %s\n",grades->teacher);
	while(group)
	{
		if(!print_group(group,file))
			return 0;
		else
			group = group->next;
	}
	return 1;
}

int print_group(GROUP_NODE *group, FILE *file)
{
	GRADE_NODE *grd = group->grades;
	if(!file)
		return 0;
	fprintf(file,"\tGroup Name: %s\n",group->name);
	fprintf(file,"\tWeight:  %f\n",group->weight);
	while(grd)
	{
		if(!print_grade(grd,file))
			return 0;
		else
			grd = grd->next;
	}
	return 1;
}

int print_grade(GRADE_NODE *grade, FILE *file)
{
	if(!file)
		return 0;
	fprintf(file,"\t\tAssignment: %s\n",grade->name);
	fprintf(file,"\t\tGrade: %f\n",grade->grade);
	return 1;
}

GRADE_NODE *new_grade_node(const char *name, float grade)
{
	GRADE_NODE *new_grade;
	new_grade = (GRADE_NODE*)malloc(sizeof(GRADE_NODE));
	strcpy(new_grade->name,name);
	new_grade->grade = grade;
	new_grade->next = NULL;
	return new_grade;
}

GROUP_NODE *new_group_node(const char *name, float weight)
{
	GROUP_NODE *new_group;
	new_group = (GROUP_NODE *)malloc(sizeof(GRADE_NODE));
	strcpy(new_group->name,name);
	new_group->weight = weight;
	new_group->next = NULL;
	new_group->grades = NULL;
	return new_group;
}

GRADE *new_grade(const char *course, const char *student,const char *teacher)
{
	GRADE *new_grd;
	new_grd = (GRADE*)malloc(sizeof(GRADE));
	strcpy(new_grd->course,course);
	strcpy(new_grd->student,student);
	strcpy(new_grd->teacher,teacher);
	new_grd->grades = NULL;
	return new_grd;
}

GRADE *pop_group(GRADE *grade)
{
	GROUP_NODE *grp1, *grp2;
	if((!grade) || (!grade->grades))
		return NULL;
	grp1 = grade->grades->next;
	grp2 = grade->grades;
	grp2->next = NULL;
	grp2 = free_group_node(grp2);
	grade->grades = grp1;
	return grade;
}

GRADE *push_group(GRADE *grade, const char *name, float weight)
{
	GROUP_NODE *grp;
	grp = new_group_node(name,weight);
	if(!grp->grades)
	{
		grp->next = grade->grades;
		grade->grades = grp;
	}
	else
	{
		grp->next = grade->grades;
		grade->grades = grp;
	}
	grp = NULL;
	return grade;
}

GROUP_NODE *free_group_node(GROUP_NODE *group)
{
	while(group->grades)
	{
		group = pop(group);
	}
	free(group);
	return group;
}

GRADE *read_grades(FILE* file)
{
	char buf[15];
	float f;
	GRADE *grd;
	grd = new_grade("NOCOURSE","NOSTUDENT","NO TEACHER");
	fscanf(file,"%s",buf);
	while(strcmp(buf,"EndGrades")!=0)
	{
		if(strcmp(buf,"Student")==0)
		{
			fscanf(file,"%s",buf);
			strcpy(grd->student,buf);
		}
		else if(strcmp(buf,"Class")==0)
		{
			fscanf(file,"%s",buf);
			strcpy(grd->course,buf);
		}
		else if(strcmp(buf,"Group")==0)
		{
			fscanf(file,"%s",buf);
			fscanf(file,"%f",&f);
			f = f / 100;
			grd = push_group(grd,buf,f);
		}
		else if(strcmp(buf,"Grade")==0)
		{
			fscanf(file,"%s",buf);
			fscanf(file,"%f",&f);
			grd->grades = push(grd->grades,buf,f);
		}
		else if(strcmp(buf,"Teacher")==0)
		{
			fscanf(file,"%s",buf);
			strcpy(grd->teacher,buf);
		}
		fscanf(file,"%s",buf);
	}
	return grd;
}
