(*
 *
 * This file defines objects and operation related to questions.
 *
 *)

module Questions;

from Database import all;
from MainUIFunctionality import all;
export all;

obj Question is 
    components: qt:QuestionText and n:QuestionName and  cl:Class* and d:Difficulty
       and t:Time and lu:LastUsed and a:Author and pv:PointValue and ty:Type and k:QKeyword*;
    description: (* The generic abstract class for a Question *);
end Question;

obj QuestionText is string;
obj QuestionName is string;
obj Class is string;
obj Difficulty is integer;
obj Time is integer;
obj LastUsed is string;
obj Author is string;
obj PointValue is integer;
obj Type is string;
obj QKeyword is string;

obj MultipleChoice inherits from Question is
    components: ans:Answer*;
    description: (* A Mutliple choice question with an array of answers *);
end MultipleChoice;
obj Coding inherits from Question is
    components: ans:CodeAnswer and LaunchIDE;
    description: (* A coding question with Output, Text and/or Script *);
end Coding;
Essay inherits from Question is 
    components: ans:EssayAnswer;
    description: (* An essay question with keywords and/or full-essay answer *);
end Essay;
obj FillInTheBlank inherits from Question is 
    components: ans:Answer*;
    description: (* A fill-in-the-blank question *);
end FillInTheBlank;
obj TrueFalse inherits from Question is 
    components: ans:TrueOrFalse;
    description: (* A true or false question *);
end TrueFalse;
obj Matching inherits from Question is 
    components: ans:Answer* and b1:Bank and b2:Bank;
    description: (* A matching question with multiple banks *);
end Matching;

obj Percentage is real;

obj EssayAnswer is kw:Keyword* or at:AnswerText;
obj CodeAnswer is co:CodeOutput or pt:ProgramText or ts:TestScript;
obj CodeOutput is string;
obj ProgramText is string;
obj TestScript is lines:string* and result:Answer*;
obj LaunchIDE is boolean;
obj CheckAnswer is boolean;
obj CheckKeyword is boolean;

obj Keyword is string;

obj TrueOrFalse is boolean;

obj Bank is string*;

obj Answer is at:AnswerText and ap:AnswerPercentage;

obj AnswerText is string;
obj AnswerPercentage is integer;

op DeleteQuestion
   inputs: qdb:Database, q:Question;
   outputs: qdb':Database;
   precondition: q in qdb;
   postcondition:
      forall(q':Question)
        (q' in qdb') iff ((q' != q) and (q' in qdb)); 
   description: (*removes a question from the database*);
end;
end Questions;