/***********************************************/
/*                                             */
/*  Solution to Project 6                      */
/*                                             */
/***********************************************/

#include <stdio.h>
#include <string.h>
#define FILENAME "Proj6.out"

/*  Define Structure */

typedef struct Student
{
	char	LastName[35];
	char	FirstName[35];
	int		Social;
	float	Projects[6];
	float	Quizzes[5];
	float	MidTerm;
	float	Final;
} StudentStructure;

int ReadData(FILE *DataFile, Student *StudentData);


/*  The next two functions are not required but make the code more readable */

char ComputeFinalGrade(float FinalTotal, float Grading[5][2]);

/*  Begin Main */

void main(void)
{
	/*  Declarations */
	FILE		*DataFile;
	int			Choice;
	float Grading[5][2] = 
		{{ 100.0, 90.0},		/* A */
		 {  89.0, 80.0},		/* B */
		 {  79.0, 70.0},		/* C */
		 {  69.0, 60.0},		/* D */
		 {  59.0,  0.0}};		/* F */
	float Weighting[3][6] =
		{{ 10, 20, 20, 20, 20, 30},	/* Projects */
		 { 10, 20, 30, 20, 20},		/* Quizzes  */
		 { 30, 20, 20, 30}};		/* Overall  */
	StudentStructure	 StudentData;
	StudentStructure	*StudentInfo;
	
	/*  Function Prototypes */
	int  WriteStudentRecord(FILE *DataFile, Student *StudentInfo);
	FILE *OpenFile(void);
	int  InputStudentRecord(Student *StudentData, float Weighting[3][6]);
	int  PrintNamesGrades(FILE *DataFile, Student *StudentInfo, float Weighting[3][6], float Grading[5][2]);
	int  GetOption(void);
	int  PrintAllData(FILE *DataFile, Student *StudentInfo, float Grading[5][2], float Weighting[3][6]);

	
	/* Main part of program */
	StudentInfo = &StudentData;
	do
	{	
		Choice = GetOption();
		DataFile = OpenFile();
		switch (Choice)
		{
		case 1:  /* Input student data               */
			InputStudentRecord(StudentInfo, Weighting);
			WriteStudentRecord(DataFile, StudentInfo);
			fflush(DataFile);
			break;
			
		case 2:  /* Print all data                   */
			rewind(DataFile);
			PrintAllData(DataFile, StudentInfo, Grading, Weighting);
			break;
			
		case 3:  /* Print names and grades           */
			rewind(DataFile);
			PrintNamesGrades(DataFile, StudentInfo, Weighting, Grading);
			break;
		case 4:  /* Quit                             */
			fclose(DataFile);
			return;
		} /* End of switch */
	} /* End of do */
	while (Choice != 4);
	
	
}

/*-------------------------------------------*/
/*            Function OpenFile              */
/*-------------------------------------------*/

FILE *OpenFile(void)
{
	FILE *DataFile;
	DataFile = fopen(FILENAME, "a+");
	if (DataFile == NULL)
		printf("Problem opening/creating data file");
	return DataFile;
}

/*-------------------------------------------*/
/*        Function InputStudentRecord        */
/*-------------------------------------------*/

int InputStudentRecord(Student *StudentInfo, float Weighting[3][6])
{
	int i;
	
	printf("Please input student's last name: ");
	scanf("%s", StudentInfo->LastName);
	printf("Please input student's first name: ");
	scanf("%s", StudentInfo->FirstName);
	printf("Please input last five digits of student's social security number: ");
	scanf("%d", &StudentInfo->Social);
	for (i=0; i<=5; i++)
	{
		do
		{
			printf("Please enter score for project %2i max possible %3.0f :", i + 1, Weighting[0][i]);
			scanf("%f", &StudentInfo->Projects[i]);
			if (StudentInfo->Projects[i] > Weighting[0][i])
				printf("\b\nLarget number allowed is %5.2f\n",Weighting[0][i]);
		}
		while (StudentInfo->Projects[i] > Weighting[0][i]);
	}
	for (i=0; i<= 4; i++)
	{
		do
		{
			printf("Please enter score for quiz %2i max possible %3.0f :", i + 1, Weighting[1][i]);
			scanf("%f", &StudentInfo->Quizzes[i]);
			if (StudentInfo->Quizzes[i] > Weighting[1][i])
				printf("\b\nLarget number allowed is %5.2f\n",Weighting[1][i]);
		}
		while (StudentInfo->Quizzes[i] > Weighting[1][i]);
	}
	printf("Please enter score for the Mid-Term Exam: ");
	scanf("%f", &StudentInfo->MidTerm);
	printf("Please enter score for Final Exam:");
	scanf("%f", &StudentInfo->Final);
	printf("Finished inputting a student record");
	return 0;
}

/*-------------------------------------------*/
/*          Function PrintAllData            */
/*-------------------------------------------*/
int PrintAllData(FILE *DataFile, Student *StudentInfo, float Grading[5][2], float Weighting[3][6])
{
	int i;
	float	FinalTotal;
	float	score;
	float	TotScore;
	float	FinalAverage;
	
	printf("      Ray Derr's Database and Grading Program\n\n");
	
	printf("                   Grading Policy\n");
	printf("                   --------------\n");
	printf("              Grade     High     Low\n");
	for (i=0; i< 5; i++)
	{	
		if (('A' + i) != 'E') 
			printf("                %c       %3.0f%%     %3.0f%%\n",
			'A' + i,
			Grading[i][1],
			Grading[i][2]);
		else
			printf("                %c       %3.0f%%     %3.0f%%\n",
			'A' + i + 1,
			Grading[i][1],
			Grading[i][2]);
	}
	
	
	printf("\n\n                 Points Available\n");
	printf("                 ----------------\n");
	printf("            1     2     3     4     5     6\n");
	printf("           ---   ---   ---   ---   ---   ---\n");
    printf("Projects   ");
	for( i=0; i < 6; i++ )
		printf("%2.0f    ", Weighting[0][i]);
	printf("\nQuizes     ");
	for( i=0; i < 5; i++ )
		printf("%2.0f    ", Weighting[1][i]);
	   
	printf("\n\n\n                    Weighting\n");
	printf("                    ---------\n");
	printf("Projects  %2.0f%%  Quizzes %2.0f%%  Mid-Term %2.0f%%  Final  %2.0f%%\n\n",
		Weighting[2][0],
		Weighting[2][1],
		Weighting[2][2],
		Weighting[2][3]);
	   
	printf("                 Student Grades\n");    
	printf("                 --------------\n");
	while(ReadData(DataFile, StudentInfo)==1)
	{
		printf("%s, %s\t\t\t  Last Five of social  %d\n",
			StudentInfo->LastName,
			StudentInfo->FirstName,
			StudentInfo->Social);
		
		FinalTotal = 0.0;
		printf("  Project Scores: ");
		TotScore = 0.0;
		for(i = 0; i < 6; i++)
		{
			score = StudentInfo->Projects[i]/Weighting[0][i]*100.0;
			TotScore += score;
			printf("%4.1f%% ", score);
		}
		printf(" Average %4.1lf%%\n", TotScore/6.0 );
		FinalTotal += TotScore/6.0 * Weighting[2][0]/100.;
		printf("     Quiz Scores: ");
		TotScore = 0;     
		for(i=0; i<5; i++)
		{
			score = StudentInfo->Quizzes[i]/Weighting[1][i]*100.0;
			TotScore += score;
			printf("%4.1f%% ", score);
		}
		
		printf("       Average %4.1f%%\n", TotScore/5.0 );
		FinalTotal += TotScore/5.0 * Weighting[2][1]/100.0;
		
		FinalAverage = FinalTotal + StudentInfo->MidTerm * Weighting[2][2]/100.0 + StudentInfo->Final * Weighting[2][3]/100.0;   
		printf("           Exams: Mid-Term %5.1f%%  Final %5.1f%%  Average %5.2f%%  Grade %c\n",
			StudentInfo->MidTerm, StudentInfo->Final, FinalAverage, ComputeFinalGrade(FinalAverage, Grading));
	}
	return 0;
}


/*-------------------------------------------*/
/*         Function PrintNamesGrades         */
/*-------------------------------------------*/

int PrintNamesGrades(FILE *DataFile, Student *StudentInfo, float Weighting[3][6], float Grading[5][2])
{
	int i;
	float FinalTotal;
	float TotScore;
	float score;
	float FinalAverage;
	int   Pad;
	char  foo[35];
	
	printf("    NAME                  GRADE\n");
	printf("    ----                  -----\n");
	while(ReadData(DataFile, StudentInfo)==1)
	{
		
		FinalTotal = 0;
		TotScore = 0;     
		for(i=0; i<6; i++)
		{
			score = StudentInfo->Projects[i]/Weighting[0][i]*100.0;
			TotScore += score;
		}
		FinalTotal += TotScore/6. * Weighting[2][0]/100.0;
		TotScore = 0;     
		for(i=0; i<5; i++)
		{
			score = StudentInfo->Quizzes[i]/Weighting[1][i]*100.;
			TotScore += score;
		}
		FinalTotal += TotScore/5. * Weighting[2][1]/100.0;
		/* Let's make sure the grade is always in the right place */
		FinalAverage = FinalTotal + StudentInfo->MidTerm * Weighting[2][2]/100.0 + StudentInfo->Final * Weighting[2][3]/100.0;
		strcpy(foo,StudentInfo->LastName);
		Pad = 25-strlen(strcat(foo,StudentInfo->FirstName));
		printf("%s, %s", StudentInfo->LastName, StudentInfo->FirstName);
		for(i=0; i<=Pad; i++) printf(" ");
		printf("%c\n",ComputeFinalGrade(FinalAverage, Grading));
	}
	return 0;
}


/*-------------------------------------------*/
/*            Function ReadData              */
/*-------------------------------------------*/
int ReadData(FILE *DataFile, Student *StudentData)
{
	int Count;
	int i;
	
	Count = 0.0;
	
	Count += fscanf(DataFile,"%s %s %d",
		StudentData -> LastName,
		StudentData -> FirstName,
		&StudentData -> Social);
	for(i=0; i<6; i++)
		Count += fscanf(DataFile,"%f",&StudentData->Projects[i]);
	for(i=0; i<5; i++)
		Count += fscanf(DataFile,"%f",&StudentData->Quizzes[i]);
	Count += fscanf(DataFile,"%f %f",&StudentData->MidTerm, &StudentData->Final);
	if (Count != 16)
		return 0;
	else
		return 1;
	
}
/*-------------------------------------------*/
/*       Function ComputeFinalGrade          */
/*-------------------------------------------*/
char ComputeFinalGrade(float FinalAverage, float Grading[5][2])
{
	int i;
	char FinalGrade = 'Z';
	
	for(i=0; i<5; i++)
	{
		if (FinalAverage <= Grading[i][0] && FinalAverage >= Grading[i][1])
			FinalGrade = 'A' + i;
	}
	if (FinalGrade == 'E') FinalGrade = 'F';
	return FinalGrade;
}

/*-------------------------------------------*/
/*       Function GetOption                  */
/*-------------------------------------------*/
int GetOption(void)
{
	int Choice;
	do 
	{
		printf("\nRay Derr's Database and Grading Program\n\n");
		printf("   (1)  Input new student record\n");
		printf("   (2)  Print all existing data in file.\n");
		printf("   (3)  Print names and grades only - from file\n");
		printf("   (4)  Quit\n\n");
		printf("Please input your selection - ");
		fflush(stdin);
		scanf("%i",&Choice);
		
		if(Choice < 1 || Choice > 4 )
			printf("\nPlease input a valid number!\n\n");
	}
	while (Choice < 1 || Choice > 4);
	return Choice;
}

/*-------------------------------------------*/
/*            Function WriteStudentRecord    */
/*-------------------------------------------*/
int WriteStudentRecord(FILE *DataFile, Student *StudentData)
{
	int i;
	int Count;
	Count = 0.0;
	
	fprintf(DataFile,"%s  %s  %d",
		StudentData -> LastName,
		StudentData -> FirstName,
		StudentData -> Social);
	for(i=0; i<6; i++)
	{
		fprintf(DataFile,"%5.1f  ",StudentData->Projects[i]);
	}
	for(i=0; i<5; i++)
	{
		fprintf(DataFile,"%5.1f  ",StudentData->Quizzes[i]);
	}
	fprintf(DataFile,"  %5.1f  %5.1f  \n",StudentData->MidTerm, StudentData->Final);
	return 0;
	
}


