package net.sourceforge.jsurveyor;
import java.util.ArrayList;

/**
 * Class to model questionnaires.
 * The main responsibility for this class it to handle which usergroups are allowed to answer it, along with a list of the pages in the questionnaire.
 * 
 * @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
 */
public class Questionnaire {

	/**
	 * Field questionnaireID
	 */
	private int questionnaireID;
	/**
	 * Field owner
	 */
	private String owner;
	/**
	 * Field questionnaireName
	 */
	private String questionnaireName;
	/**
	 * Field state
	 */
	private boolean state;
	/**
	 * Field refUserGroups
	 */
	private ArrayList refUserGroups;
	/**
	 * Field refQuestionPages
	 */
	private ArrayList refQuestionPages;
	/**
	 * Field introText
	 */
	private String introText;
	
	/**
	 * Constructor for Questionnaire
	 */
	public Questionnaire() {
		this.owner = "No owner has been set yet";
		this.questionnaireName = "No name has been set yet";
		this.state = false;
		refUserGroups = new ArrayList();
		refQuestionPages = new ArrayList();
		introText = "";
	}

	/**
	 * Constructor for Questionnaire
	 * @param owner String
	 */
	public Questionnaire(String owner) {
		this.owner = owner;
		this.questionnaireName = "No name has been set yet";
		this.state = false;
		refUserGroups = new ArrayList();
		refQuestionPages = new ArrayList();
		introText = "";
	}

	/**
	 * Constructor for Questionnaire
	 * @param owner String
	 * @param questionnaireName String
	 */
	public Questionnaire(String owner, String questionnaireName) {
		this.owner = owner;
		this.questionnaireName = questionnaireName;
		this.state = false;
		refUserGroups = new ArrayList();
		refQuestionPages = new ArrayList();
		introText = "";
	}

	/**
	 * Constructor for Questionnaire, use through DataAccess.
	 * @param questionnaireID int
	 * @param owner String
	 * @param questionnaireName String
	 * @param state boolean
	 * @param refUserGroups ArrayList
	 * @param refQuestionPages ArrayList
	 * @param introText String
	 */
	public Questionnaire(
		int questionnaireID,
		String owner,
		String questionnaireName,
		boolean state,
		ArrayList refUserGroups,
		ArrayList refQuestionPages,
		String introText) {

		this.owner = owner;
		this.questionnaireID = questionnaireID;
		this.questionnaireName = questionnaireName;
		this.state = state;
		this.refUserGroups = refUserGroups;
		this.refQuestionPages = refQuestionPages;
		this.introText = introText;
	}

	/**
	 * Adds a UserGroup and hereby allowing them to answer this Questionnaire
	 * @pre the usergroup is not already added.
	 * @param userGroup UserGroup
	 */
	public void addUserGroup(UserGroup userGroup) {
		assert !(
				isUserGroupAdded(userGroup)) : "The userGroup is already added";
		refUserGroups.add(userGroup.toString());
	}

	/**
	 * Removes a usergroup from the Questionnaire, so that they no longer can answer it.
	 * @pre the usergroup is added
	 * @param userGroup UserGroup
	 */
	public void removeUserGroup(UserGroup userGroup) {
		assert isUserGroupAdded(userGroup) : "The userGroup is not added";
		refUserGroups.remove(userGroup.toString());
	}

	/**
	 * Adds a page of questions to the Questionnaire
	 * @pre the questionPage is not already added.
	 * @pre the questionnaire is inactive
	 * @param questionPage QuestionPage
	 */
	public void addQuestionPage(QuestionPage questionPage) {
		assert !(
			isQuestionPageAdded(questionPage)) : "The questionPage is already added";
		assert(state == false) : "The questionnaire is active";
		refQuestionPages.add(questionPage.toString());
	}
	
	/**
	 * Adds a page of questions at a specific position in the Questionnaire.
	 * @pre the questionPage is not already added
	 * @pre the questionnaire is inactive
	 * @param questionPage QuestionPage
	 * @param position int
	 */
	public void addQuestionPageAtPosition(QuestionPage questionPage, int position) {
		assert !(
				isQuestionPageAdded(questionPage)) : "The questionPage is already added";
		assert(state == false) : "The questionnaire is active";
		refQuestionPages.add(position, questionPage.toString());
	}
	
	/**
	 * Removes a page of questions from the Questionnaire.
	 * @pre the questionPage is added to the questionnaire
	 * @pre the questionnaire is inactive.
	 * @param questionPage QuestionPage
	 */
	public void removeQuestionPage(QuestionPage questionPage) {
		assert isQuestionPageAdded(questionPage) : "The questionPage is not added";
		assert(state == false) : "The questionnaire is active";
		refQuestionPages.remove(questionPage.toString());
	}

	/**
	 * Deactivates the Questionnaire
	 * @pre the questionnaire is active
	 */
	public void setInactive() {
		assert(state != false) : "The Questionnaire is already inactive";
		state = false;
	}

	/**
	 * Activates the Questionnaire
	 * @pre the questionnaire is inactive.
	 * @pre the questionnaire is non-empty, ie. questionPages has been added.
	 */
	public void setActive() {
		assert(state != true) : "The Questionnaire is already active";
		assert(
			refQuestionPages.isEmpty() == false) : "The Questionnaire is empty";
		state = true;
	}

	/**
	 * Returns whether or not the questionnaire is active.
	 * @return boolean
	 */
	public boolean getState() {
		return state;
	}

	/**
	 * Sets an ID for the questionnaire
	 * @param questionnaireIDInput int
	 */
	public void setQuestionnaireID(int questionnaireIDInput) {
		questionnaireID = questionnaireIDInput;
	}

	/**
	 * Returns the id of the questionnaire.
	 * @return int
	 */
	public int getQuestionnaireID() {
		return questionnaireID;
	}

	/**
	 * Sets the owner of the questionnaire.
	 * @param owner String
	 */
	public void setOwner(String owner) {
		this.owner = owner;
	}

	/**
	 * Returns the owner of the questionnaire.
	 * @return String
	 */
	public String getOwner() {
		return owner;
	}

	/**
	 * Sets a name for the questionnaire.
	 * @param questionnaireName String
	 */
	public void setQuestionnaireName(String questionnaireName) {
		this.questionnaireName = questionnaireName;
	}

	/**
	 * Returns the name of the questionnaire.
	 * @return String
	 */
	public String getQuestionnaireName() {
		return questionnaireName;
	}

	/**
	 * Sets an intro text for the questionnaire.
	 * @param introText String
	 */
	public void setIntroText(String introText) {
		this.introText = introText;
	}

	/**
	 * Returns the intro text of the questionnaire.
	 * @return String
	 */
	public String getIntroText() {
		return introText;
	}

	/**
	 * Returns an ArrayList with toString representations of the userGroups that are allowed to answer the questionnaire.
	 * @return ArrayList
	 */
	public ArrayList getRefUserGroups() {
		return refUserGroups;
	}

	/**
	 * Returns an ArrayList with toString representations of the added questionPages.
	 * @return ArrayList
	 */
	public ArrayList getRefQuestionPages() {
		return refQuestionPages;
	}

	/**
	 * Returns true if the questionPage is contained in the Questionnaire.
	 * @param questionPage QuestionPage
	 * @return boolean
	 */
	private boolean isQuestionPageAdded(QuestionPage questionPage) {
		return refQuestionPages.indexOf(questionPage.toString()) != -1;
	}

	/**
	 * Returns true if the userGroup is allowed to answer the questionnaire.
	 * @param userGroup UserGroup
	 * @return boolean
	 */
	private boolean isUserGroupAdded(UserGroup userGroup) {
		return refUserGroups.indexOf(userGroup.toString()) != -1;
	}

	/**
	 * Returns a string representation of the object.
	 * @return String
	 */
	public String toString() {
		return "R" + questionnaireID;
	}
}