/**
 * Base class for question sotred in a QuestionDB.
 * Section 2.3.2
 * @author Kim Paterson
 * @author Mitchell Rosen
 */
package question;

import java.util.Collection;
import java.sql.Time; //This is just a guess of which time class we'd want
import java.sql.Date;

public abstract class Question implements QuestionItem {
   /**
    * This field holds the text and/or instructions for the question.
    */
   public String questionBox;

   /**
    * This field measures the difficulty of a question on a scale of 1 to 5,
    * where 1 is the lowest difficulty, and 5 is the highest.
    */
   public int difficulty;

   /**
    * This filed stores the estimated time to complete the question.
    */
   public Time estimatedTimeToComplete;

   /**
    * Each question has a collection of keywords that describe the topics covered
    * by the question.
    */
   public Collection<Keyword> keywords;

   /**
    * When a question is used on a test, this field is updated with the date of
    * the publication of the test.
    */
   public Date lastUsed;

   /**
    * A generic type answer can contain a subclass instance of a question type
    * that implements the answer interface.
    */
   public Answer answer;

   /**
    * Sets the difficulty of a question on a scale of 1 to 5.
    * @param difficulty is a measure of how easy to hard a question is on a scale
    * of 1 to 5
    */
   /*@
     ensures
   //
   // The difficulty is not null and is within the range of 1 to 5
   //
   (this.difficulty == difficulty )
   && (this.difficulty >= 1) && (this.difficulty <= 5);

   @*/
   public abstract void setDifficulty(int difficulty);

   /**
    * Sets the estimated time to answer the question.
    * @param time takes a Time data type that represents how long
    * a question takes.
    */
   /*@
     ensures
   //
   // The estimated time to completion is not null and this.estimatedTimeToComplete equals
   // the new input
   //
   (this.estimatedTimeToComplete !=null) && (this.estimatedTimeToComplete.equals(time));
   @*/
   public abstract void setEstimatedTime(Time time);

   /**
    * Sets the instructions/information to be displayed for a question.
    * @param questionText is a String that contains the information
    * and/or instructions about a question.
    */
   /*@
     ensures
   //
   // The this.questionText equals the input questionText and is not null
   //
   (this.questionBox.equals(questionText)) && (this.questionBox != null);
   @*/
   public abstract void setQuestionText(String questionText);

   /**
    * Sets the date of last use for a question.
    * @param date takes a Date object that holds the date of when the
    * question was last used on a published test.
    */
   /*@
     ensures
   //
   // this.lastUsed is equal to the input date and is not null
   //
   (this.lastUsed.equals(date)) && (this.lastUsed != null);

   @*/
   public abstract void setLastUsed(Date date);

   /**
    * Adds a Keyword to the collection of topics the question
    * covers.
    * @param keyword is a Keyword datatype and represetns a
    * topic.
    */
   /*@
     requires
   //
   // Requires valid input
   //
   (keyword != null) && (keyword.name.length() > 0);

   ensures
   //
   // The given keyword is in this.keywords
   //
   keywords.contains(keyword)

   &&

   //
   // All other records in the output list are in the
   // output list and only those.
   //
   (\forall Keyword kw ;
   (keywords.contains(kw)) <==>
   !keyword.equals(kw) || \old(keywords).contains(kw));

   @*/
   public abstract void addKeyword(Keyword keyword);

   /**
    * Removes the specified keyword from a collection.
    * @param keyword the Keyword to be removed from the collection.
    */
   /*@
     @*/
   public abstract void deleteKeyword(Keyword keyword);

   /**
    * Returns the collection of Keywords associated with the question.
    * @return returns the collection of keywords stored in the Question object.
    */
   /*@
     @*/
   public abstract Collection<Keyword> getKeywords();

   /**
    * Returns the question text.
    * @return returns the question text stored in the Question object
    */
   /*@
     @*/
   public abstract String getQuestionText();

   /**
    * Returns the difficulty of the question as an Integer.
    * @return the difficulty of a question as an integer.
    */
   /*@
     @*/
   public abstract int getDifficulty();

   /**
    * Returns a Time object that contains the estimated time to complete
    * the question.
    * @return returns a Time object with the estimated time to complete.
    */
   /*@
     @*/
   public abstract Time getEstimatedTime();

   /**
    * Returns the stored date with the last date the question was
    * used on a published test.
    * @return a Date object with the last date the question was used
    */
   /*@
     @*/
   public abstract Date getLastUsed();

   /**
    * Uses the stored answer in the Question object and compares
    * it against the Answer parameter object for equality, returning
    * a double between 0 and 1 representing how correct the answer is.
    * @param the student's answer to the question
    * @return a double in the range [0...1] representing percent correctness.
    */
   /*@
     @*/
   public abstract double grade(Answer answer);
}