/* File: struct4.c
   Sort an array of pointers to records.
*/
#include <stdio.h>
#include "genlib.h"
#include "simpio.h"
#include "strlib.h"

typedef struct dummy_tag { 
        string	name ;
        string	major ;
	double	gpa ;
	} student_record ;

typedef student_record *rec_ptr ;

/* Function prototypes */
rec_ptr read_record() ;
void print_record(student_record) ;
void SelectionSort(rec_ptr A[], int size) ;
int FindSmallest(rec_ptr A[], 
		 int start, int stop) ;

main() {
   rec_ptr students[20] ;
   int i, size ;

   size = GetInteger() ;
   for (i = 0 ; i < size ; i++) {
      students[i] = read_record() ;
   }
   SelectionSort(students,size) ;
   for (i = 0 ; i < size ; i++) {
      print_record( *(students[i]) ) ;
   }
}

/* Read in one record */
rec_ptr read_record() {
   rec_ptr p ;

   p = malloc(sizeof(student_record)) ;
   if (p == NULL) {
      printf("Memory allocation failed!!!\n") ;
      exit(-1) ;
   } 
   (*p).name = GetLine() ;
   p->major = GetLine() ;
   p->gpa = GetReal() ;
   return(p) ;
}

/* Print out one record neatly */
void print_record (student_record rec) {
   printf("%20s, %10s, GPA: %1.4f\n",
      rec.name, rec.major, rec.gpa) ;
}


/* Use Selection Sort to sort the array 
   of records according to GPA.
*/
void SelectionSort(rec_ptr A[], int size) {
   int unsorted, smallest_index;
   rec_ptr temp ;

   for(unsorted=0; unsorted < size-1; unsorted++){
      smallest_index 
	 = FindSmallest(A,unsorted,size-1);

      /* swap values */
      temp = A[smallest_index] ;
      A[smallest_index] = A[unsorted] ;
      A[unsorted] = temp ;
   }
}

/* Find smallest value in array A 
*/
int FindSmallest(rec_ptr A[], 
		 int start, int stop) {
   int smallest_index, i ;
   double smallest_value ;

   smallest_index = start ;
   smallest_value = A[start]->gpa ;
   for (i = start+1 ; i <= stop ; i++){
      if (A[i]->gpa < smallest_value) {
	 smallest_index = i ;
	 smallest_value = A[i]->gpa ;
      }
   }
   return(smallest_index) ;
}

