package net.sourceforge.jsurveyor;

import java.util.ArrayList;

/**
 * This a abstract class to model questions. 
 * It handles the questiontext, dependency of other questions and has a writeable property.
 * 
 * @version 1.0
 * @author Claus Methmann Christensen
 * @author Anders Spliid Hansen
 * @author Esben Iversen Hansen
 * @author Lars H Jensen
 * @author Marcus Overheu
 * @author Thomas Ramdal
 * @author Peter Thomsen
 */
abstract class Question {
	/**
	 * Field questionID
	 */
	private int questionID;
	/**
	 * Field text
	 */
	private String text;
	/**
	 * Field writeable
	 */
	private boolean writeable;

	/**
	 * Field depends Does the question require a specifik answers to another
	 * question before it is asked?
	 */
	private boolean depends = false;

	/**
	 * Field dependency
	 */
	private ArrayList dependency = new ArrayList();

	/**
	 * Constructor for Question
	 */
	public Question() {
		text = "";
		writeable = true;
	}

	/**
	 * Constructor for Question
	 * 
	 * @param text
	 *                   String
	 */
	public Question(String text) {
		this.text = text;
		writeable = true;
	}

	/**
	 * Constructor for Question
	 * 
	 * @param text
	 *                   String
	 * @param writeable
	 *                   boolean
	 */
	public Question(String text, boolean writeable) {
		this.text = text;
		this.writeable = writeable;
	}

	/**
	 * Constructor for Question, use through DataAccess.
	 * 
	 * @param questionID
	 *                   int
	 * @param text
	 *                   String
	 * @param writeable
	 *                   boolean
	 * @param required
	 *                   boolean
	 * @param depends
	 *                   boolean
	 * @param dependency
	 *                   ArrayList
	 */
	public Question(
		int questionID,
		String text,
		boolean writeable,
		boolean required,
		boolean depends,
		ArrayList dependency) {
		this.questionID = questionID;
		this.text = text;
		this.writeable = writeable;
		//		this.required = required;
		this.depends = depends;
		this.dependency = dependency;
	}

	/**
	 * Returns the ID of the question.
	 * 
	 * @return int
	 */
	public int getQuestionID() {
		return questionID;
	}

	/**
	 * Sets the ID of the question.
	 * 
	 * @param questionID
	 *                   int
	 */
	public void setQuestionID(int questionID) {
		this.questionID = questionID;
	}

	/**
	 * Returns the question text.
	 * 
	 * @return String
	 */
	public String getText() {
		return text;
	}

	/**
	 * Sets the question text. 
	 * Throws IllegalAccessException if the question is active
	 * 
	 * @param text
	 *                   String
	 * @throws IllegalAccessException
	 */
	public void setText(String text) throws IllegalAccessException {
		if (!writeable) {
			throw new IllegalAccessException();
		}

		this.text = text;
	}

	/**
	 * Does the question depend on a specific answer from another question for it to be asked? Returns true if that is the case, otherwise it returns false.
	 * 
	 * @return boolean
	 */
	public boolean getDepends() {
		return depends;
	}

	/**
	 * Sets the dependency of this question to specific answers of a multiplechoice question. 
	 * @pre the numbers in the integer array must match possible choices in the dependency question.
	 * 
	 * @param question
	 *                   QuestionMultipleChoice
	 * @param choices
	 *                   int[]
	 * @throws IllegalAccessException
	 */
	public void setDependency(QuestionMultipleChoice question, int[] choices)
		throws IllegalAccessException {
		if (!writeable) {
			throw new IllegalAccessException();
		}
		String stringChoices = new String();
		for (int i = 0; i < choices.length; i++) {
			stringChoices = stringChoices + choices[i] + ";";
		}
		this.removeDependency();
		dependency.add(question.toString());
		dependency.add(stringChoices.substring(0, stringChoices.length() - 1));
		this.depends = true;
	}

	/**
	 * Removes any dependency on the question.
	 * 
	 * @throws IllegalAccessException
	 */
	public void removeDependency() throws IllegalAccessException {
		if (!writeable) {
			throw new IllegalAccessException();
		}
		dependency.clear();
		this.depends = false;
	}

	/**
	 * Returns the ArrayList representation of dependency
	 * 
	 * @return ArrayList
	 */
	public ArrayList getDependency() {
		return dependency;
	}

	/**
	 * 
	 * Returns true if the question is writeable.
	 * 
	 * @return boolean
	 */
	public boolean isWriteable() {
		return writeable;
	}

	/**
	 * Sets the writable parameter.
	 * 
	 * @param writeable
	 *                   boolean
	 */
	public void setWriteable(boolean writeable) {
		this.writeable = writeable;
	}

	/**
	 * Returns true if the question is writeable
	 * 
	 * @return boolean
	 */
	public boolean getWriteable() {
		return writeable;
	}

} // end class
