{ Assignment 9 }
{ Written by Bryan Bridges }

program assign09;
uses crt;

{ Declare Constants }
const
   Title1 = '    GHERESUS UNIVERSITY RECORDS DEPARTMENT';
   Title2 = '      STUDENT TUITION CALCULATION TABLE';
   Title3 = 'SORTED BY STATE FROM THE LOWEST TO THE HIGHEST';
   Title4 = 'NAME           STATE   HOURS   BOARD   BILL';
   Title5 = 'IT IS FUN TO PROGRAM!';
   full_in = 545;
   full_out = 1184;
   part_in = 44;
   part_out = 94;
   fee = 60;
   board = 425;
   max_students = 10;

{ Declare Types }
type
   student_records = record
                     name : string[16];
                     state : string[8];
                     hours : integer;
                     board : string[10];
                     bill : real
                     end;
   student_records_array_type = array [1..max_students] of student_records;

{ Declare Variables }
var
   student_records_array : student_records_array_type;
   I, N : integer;
   Input, Output : text;

{***********************************************************************}

     procedure swap (var A, B : student_records);
     {Interchange Records A and B}
     var
          C : student_records;
     begin
          C := A;
          A := B;
          B := C
     end;

{--------------------------------------------------------------------}

     procedure sort (var sorting_student_records_array : student_records_array_type);
     { Sort Student Records By State, Then Name }
     var
          Location, Index, Lowest : Integer;
     begin
          for Location := 1 to max_students - 1 do
          begin
               Lowest := Location;
               for Index := (Location + 1) to max_students do
                   begin
                   if (sorting_student_records_array[Index].state < sorting_student_records_array[Lowest].state) then
                      Lowest := Index;
                   if (sorting_student_records_array[Index].state = sorting_student_records_array[Lowest].state) and
                   (sorting_student_records_array[Index].name < sorting_student_records_array[Lowest].name) then
                      Lowest := Index;
                   end;
               swap (sorting_student_records_array[Location], sorting_student_records_array[Lowest])
          end;
     end;

{***********************************************************************}


{ Start Main Program }
begin

{ Assign Input & Output Files }
  assign (Input, 'D:\FILES\BAB''S\PASCAL\ASSIGN09.INP');
  reset (Input);
  assign (Output, 'D:\FILES\BAB''S\PASCAL\ASSIGN09.OUT');
  rewrite (Output);

{ Read Tables from Input File }
  for I := 1 to 10 do
  begin
       read (Input, student_records_array[I].name, student_records_array[I].state, student_records_array[I].hours);
       readln (Input, student_records_array[I].board);
  end;

{ Creation of Table #2 }
  begin
       { Write Output Header Part 1 }
       writeln (Output, Title1);
       writeln (Output, Title2);
       writeln (Output, Title4);

       { Bill Calculations }
       for I := 1 to 10 do
       begin
           { Tuition Calculation }
           if student_records_array[I].hours > 12 then
              { Full Time }
              if student_records_array[I].state = 'MI      ' then
                  { Full Time In-State }
                  student_records_array[I].bill := full_in
              else
                  { Full Time Out-of-State }
                  student_records_array[I].bill := full_out
           else
              { Part Time }
              if student_records_array[I].state = 'MI      ' then
                  { Part Time In-State }
                  student_records_array[I].bill := (part_in * student_records_array[I].hours)
              else
                  { Part Time Out-of-State }
                  student_records_array[I].bill := (part_out * student_records_array[I].hours);

           { Board Calculations }
           if (student_records_array[I].board = '      YES') or (student_records_array[I].board = '       YES') then
              { On Campus Housing }
              student_records_array[I].bill := student_records_array[I].bill + board
           else
              { Off Campus Housing }
              student_records_array[I].bill := student_records_array[I].bill;

           { Fixed Fee }
           student_records_array[I].bill := student_records_array[I].bill + fee;

           { Re-Formating Output }
           if (student_records_array[I].board = '       NO') or (student_records_array[I].board = '      NO') then
              N := 1
           else
              N := 0;

           { Student Output }
           write (Output, student_records_array[I].name, student_records_array[I].state, student_records_array[I].hours);
           writeln (Output, student_records_array[I].board, student_records_array[I].bill:10+N:2);
       end;

       { Write Output Header Part 2 }
       writeln (Output, Title5);
  end;

{ Creation of Table #3 }
  begin
  { Write Output Header }
  writeln (Output);
  writeln (Output, Title1);
  writeln (Output, Title2);
  writeln (Output, Title3);
  writeln (Output, Title4);

  { Sort By Residence }
  sort (student_records_array);

  for I := 1 to 10 do
      begin
      { Re-Formating Output }
      if (student_records_array[I].board = '       NO') or (student_records_array[I].board = '      NO') then
         N := 1
      else
         N := 0;

      { Student Output }
         write (Output, student_records_array[I].name, student_records_array[I].state, student_records_array[I].hours);
         writeln (Output, student_records_array[I].board, student_records_array[I].bill:10+N:2);
       end;
  end;
  writeln (Output, '---------------------------------------------');
{ End Main Program }
end.
