#include <stdio.h>
#include <stdlib.h>

#define MAX 21
#define MAX_ELEM 8
#define SCORE 12
#define NUM_SKATER 4
#define BASE 3.1

typedef struct{
                char  name[MAX];
		int   elements;
                float baseval[MAX_ELEM];
                int score[MAX_ELEM][SCORE];
	        float total_base;
		float tech_score;
		float total_score;
              }SKATER;

int  getData(SKATER skater[NUM_SKATER]);
void calcData(SKATER skater[NUM_SKATER]);
void insertSort(SKATER skater[NUM_SKATER], int num);
void printData(SKATER skater[]);

int main (void)
{
	// Global Declarations
	SKATER skater[NUM_SKATER];
	int num;

	// Funtion calls
	num = getData(skater);
	calcData(skater);
	insertSort(skater, NUM_SKATER);
	printData(skater);
	return 0;
}

/********************************* getData ************************************
Pre:
Post:
*/
int getData(SKATER skater[NUM_SKATER])
{
	// LOcal Declarations
	FILE* fpIn;
	int   i = 0;  
	int	  k;
	int   j;
	char  buffer[256]; 

	// Statements
	if((fpIn = fopen("lab6data.txt","r"))==NULL)
	{
		printf("File opening error");
		system("PAUSE");
		exit(100);
	}
     
	while(i < NUM_SKATER && fgets(buffer, sizeof(buffer) - 1, fpIn))
	{		
		sscanf(buffer,"%*c%19[^0123456789]", skater[i].name);			
		for(k = 0; k < MAX_ELEM; k++)
		{			
			if(fgets(buffer, sizeof(buffer)-1, fpIn) != NULL)
		    {			 
				sscanf(buffer,"%d %f", &skater[i].elements, &skater[i].baseval[k]);
				for(j = 0; j < SCORE; j++)
				{
					sscanf(buffer,"%d", &skater[i].score[k][j]);
				}
			}
		} 
	    
		i++;		
	}

	system("PAUSE");
	fclose(fpIn);

	return i;
}

/* ****************************** calcData *******************************
Pre:
Post:
*/
void calcData(SKATER skater[NUM_SKATER])
{
	//Local Declaration 
	int i,j,k;
	int smallest, largest;
	int temp = 0;
	float temp_baseval = 0;
	float temp_score = 0;
	float total;

//Statements
	for(i=0; i< NUM_SKATER; i++)
	{	
		for(j=0; j< MAX_ELEM; j++)
		{	
			smallest = skater[i].score[j][0];
			largest = skater[i].score[j][SCORE-1];

			for(k=0; k< SCORE; k++)
			{
				temp += skater[i].score[j][k]; //adds total scores

				if(smallest > skater[i].score[j][k])
					smallest = skater[i].score[j][k];
				else if(largest < skater[i].score[j][k])
					largest = skater[i].score[j][k];
			}

			//total scores minus largest and smallest
			total = (float)(temp - (largest+smallest)) / (float)SCORE; 
			temp = 0;
			
			//calculates result on the basis of baseval <= or > than 3.1
			if(skater[i].baseval[j] <= BASE)
			   skater[i].total_score = (float)(.5 * total) + skater[i].baseval[j];
			else
			   skater[i].total_score = total + skater[i].baseval[j];
			
			temp_baseval += skater[i].baseval[j]; //sums up baseval
			temp_score += skater[i].total_score; //sums up technical score
		}
		
		skater[i].tech_score = temp_score;
		skater[i].total_base = temp_baseval;

		temp_baseval=0;
		temp_score=0;
	}


	return;
}

/*	==================== insertSort ====================
	Sorts list using Insertion Sort. Thes list is divided into sorted 
	and unsorted list. With each pass the first elemnt in unsorted list
	is inserted in sortedlist.

	   Pre	 	SKATER skater is a structure
	   Post		returns sorted structure based on highest technical score
*/

void insertSort(SKATER skater[NUM_SKATER], int num)
{

//Local Declaration 
	int loc;
	SKATER temp;
	SKATER *pCurr;
	SKATER *pWalk;
	SKATER *pLast;

//Statements
	for(pCurr = skater + 1, pLast = skater + num-1; 
		pCurr <= pLast;
		pCurr++)
	{
	 loc = 0;
	 temp = *pCurr;

	 for(pWalk = pCurr -1; 
		 pWalk >= skater && !loc;)

	 //compares the tech scores of swimmers
	 if(temp.tech_score > pWalk->tech_score) 
		 {
			 *(pWalk+1) = *pWalk;
			 pWalk--;
		 }
	 else
		 loc = 1;
	 *(pWalk+1) = temp;
	}

  return;
}

/* ****************************** printData *******************************8
Pre:
Post:
*/
void printData(SKATER skater[])
{
	//Local Declaration 
	FILE*fpOut;
	int i,j,k;

	//Statements
	if(!(fpOut=fopen("output.txt", "w")))
		printf("CANT OPENT output.txt");

	printf("Calculating.....\n");
	printf("DONE see output.txt\n"); //checks to see if output.txt opens

	fprintf(fpOut,"NAME:      LAB#6      EMAIL: \n\n");
	fprintf(fpOut,"EVENT: MEN SHORT PROGRAM\n");
	fprintf(fpOut,"CHIEF ACCOUNTANT: \n\n");
	

	for(i=0; i<NUM_SKATER; i++)
	   {	
		fprintf(fpOut,"SKATER: %s\n\n", skater[i].name);
		fprintf(fpOut,"[BASE]                   [SCORE]                        [TOTAL]\n");
		fprintf(fpOut,"---------------------------------------------------------------\n");
		for(j=0; j<MAX_ELEM; j++)
			 {
				 fprintf(fpOut,"%5.2f   ", skater[i].baseval[j]);
				  for(k=0; k<SCORE; k++)
					  {
					   fprintf(fpOut,"%3d ", skater[i].score[j][k]);
					  }
			     fprintf(fpOut,"  %5.2f", skater[i].total_score);
				 fprintf(fpOut,"\n");
		     }
		
		fprintf(fpOut,"---------------------------------------------------------------\n");
		fprintf(fpOut,"Total Base: %5.2f                  Total Technical Score: %5.2f", 
				skater[i].total_base, skater[i].tech_score);
				  
	   fprintf(fpOut,"\n\n\n");
	   }
	
	return;
}
