(******
 * This file defines objects and operation related to Graphs of the Grader
 *
 * See section 2.4.5 of the Milestone 4 requirements.
 *
 *)

module Graphs;
from Gradesheet import GradeSheet, CalculatedScore, StudentInfo;
from Tools import GradeLetter, GradeNumber, color, Min, GradeThreshold, 
  NumberOfGrades, Scheme, SchemeChoice;
export all;
(* Objects for creating a GradeHistory *)
obj GradeHistory is
  components: Terms and Teacher and Class;
  description: (*The GradeHistory is a graph that shows what a teacher gave as
  grades in past quarters*);
  
end GradeHistory;

obj Terms is StartTerm and EndTerm;
obj StartTerm is string;
obj EndTerm is string;
obj Teacher is string;
obj Class is string;

(* Objects for operations while Creating a Grading history of a professor. *)

op CreateGraph(Teacher, GradeSheet*) -> GradeHistory;

(* Objects for creating a histogram *)

obj Histogram is 
  components: gllist:GradeLines* and sc:ScoreCount*;
  description: (*The Histogram is a list of all the grade percents and displays
  astricks to represent how many students received each grade percent. It shows
  the user how many students recieved each grade*);
  
end Histogram;

obj GradeLines is GradeLetter and mi:Min;
obj ScoreCount is calc:CalculatedScore and num:NumOfScores;
obj NumOfScores is integer;

(* Operations for the histogram. *)

op EditHistogram
  inputs: h:Histogram, gl:GradeLines*, gt:GradeThreshold, gs:GradeSheet,
    ng:NumberOfGrades;
  outputs: h':Histogram, gt':GradeThreshold;
  precondition: (gt !=nil) and (gs != nil) and (h != nil);
  postcondition: 
    forall (i:integer | i >=0 and i <= ng) h'.gllist[i].mi 
      = gl[i].mi and gt'.schemechoice.scheme[i].gradenbr[i].min = gl[i].mi;

end EditHistogram;

op GenerateHistogram
  inputs: gt:GradeThreshold, gs:GradeSheet;
  outputs: h:Histogram;
  precondition: (gt != nil) and (gs != nil);
  postcondition: 
  (*The number of people who recieve a grade must be added up.*)
    forall (i:integer | i >=0 and i <= 100) h.sc[i].num = 
    SumTheScores(i,gs,h.sc[i].num);
end GenerateHistogram;


(* Objects for creating a PieChart *)

obj PieChart is 
  components: PieLines and sc:ScoreCount* and Percentage*;
  description: (* The PieChart displays the amount of students that recieve
  each grade graphically.*);
  
end PieChart;

obj Percentage is ScoreCount and TotalStudents;
obj TotalStudents is integer;
obj PieLines is 
  components: GradeLetter and Min and color;
  description: (*The PieLines is what the divides the different sections of
  the PieChart*);
  
end PieLines  ;


(* Operations for the piechart *)

op EditPieChart(PieChart, PieLines*, Percentage) -> PieChart;
op GeneratePieChart
  inputs: gt:GradeThreshold, gs:GradeSheet;
  outputs: p:PieChart;
  precondition: (gt != nil) and (gs != nil);
  postcondition: 
  (*The number of people who recieve a grade must be added up.*)
    forall (i:integer | i >=0 and i <= 100) p.sc[i].num = 
    SumTheScores(i,gs,p.sc[i].num);

end GeneratePieChart;

(* Recursive Function to add up the Number of Scores *)
 
function SumTheScores(i:integer, gs: GradeSheet, num:NumOfScores)->(num':NumOfScores) =
  forall(g:integer | g >= 0 and g <= #gs.silist) if (i = gs.silist[i].calcdscore) then
  num'= num + 1 and num = num';
end Graphs;