package net.sf.egonet.web.panel;
import java.util.ArrayList;
import java.util.List;
import net.sf.egonet.model.Alter;
import net.sf.egonet.model.Answer;
import net.sf.egonet.model.Interview;
import net.sf.egonet.model.Question;
import net.sf.egonet.model.QuestionOption;
import net.sf.egonet.persistence.Options;
import net.sf.egonet.persistence.SimpleLogicMgr;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.basic.MultiLineLabel;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.ajax.AjaxRequestTarget;
import org.apache.wicket.ajax.markup.html.AjaxFallbackLink;
import org.apache.wicket.markup.html.form.Form;
import org.apache.wicket.markup.repeater.RepeatingView;
import org.apache.wicket.markup.html.WebMarkupContainer;
import org.apache.wicket.model.Model;
import com.google.common.collect.Lists;
public class InterviewingPanel extends Panel {
private Question question;
private ArrayList<AnswerFormFieldPanel> answerFields;
private CheckboxesPanel<String> refDKCheck;
private Long interviewId;
private boolean multipleQuestions;
private final String
dontKnow = AnswerFormFieldPanel.dontKnow,
refuse = AnswerFormFieldPanel.refuse,
none = AnswerFormFieldPanel.none;
/**
* the 'usual' constructor, deals with one question/alter or
* one question and a list of alters.
* @param id - needed for wicket
* @param question - the question to ask
* @param answerFields - if one question/alter just one answerField.
* If a list of alters the answer entry field repeated for each alter
* @param interviewId - uniquely identifies the current interview
*/
public InterviewingPanel(String id,
Question question, ArrayList<AnswerFormFieldPanel> answerFields, Long interviewId)
{
super(id);
this.question = question;
this.answerFields = answerFields;
this.interviewId = interviewId;
multipleQuestions = false;
build();
}
/**
* this constructor will be used to put multiple questions for one alter
* (or alter-pair, or ego) on one page. In this case the questions will be
* extracted from the AnswerFormFieldPanels
* @param id - needed for wicket
* @param answerFields - array of answer fields. In this case there *should*
* be more than one
* @param interviewId - uniquely identifies the current interview
*/
public InterviewingPanel(String id,
ArrayList<AnswerFormFieldPanel> answerFields, Long interviewId)
{
super(id);
this.question = null;
this.answerFields = answerFields;
this.interviewId = interviewId;
multipleQuestions = true;
build();
}
/**
* IF this IS an alter or alter_pair question, the type IS MULTIPLE_SELECTION
* AND there is more than one answer Field
* THEN we want to use the action buttons to (optionally)
* set Don't Know, Refuse or the 'All' selection
*/
private void build() {
String strPrompt;
String strSkipReason;
Label lblBtnAll;
Form pageButtonsForm = new Form("pageButtonsForm");
boolean withDKRefActionButtons = false;
List<QuestionOption> listOfOptions = null;
Question.QuestionType qType = null;
Answer.AnswerType aType = null;
if ( question!=null ) {
qType = question.getType();
aType = question.getAnswerType();
if ((qType == Question.QuestionType.ALTER || qType==Question.QuestionType.ALTER_PAIR )&&
aType == Answer.AnswerType.MULTIPLE_SELECTION ) {
if ( answerFields.size() > 1)
withDKRefActionButtons = true;
}
}
setOutputMarkupId(true);
setOutputMarkupPlaceholderTag(true);
ArrayList<Alter> altersInPrompt = Lists.newArrayList();
if(answerFields.size() < 2 && ! answerFields.isEmpty()) {
altersInPrompt = answerFields.get(0).getAlters();
}
if(answerFields.size() > 1 && answerFields.get(0).getAlters().size() > 1) {
altersInPrompt = Lists.newArrayList(answerFields.get(0).getAlters().get(0));
}
if ( multipleQuestions ) {
add(new MultiLineLabel("prompt", ""));
ListView questionsView = new ListView("questions",answerFields) {
protected void populateItem(ListItem item) {
AnswerFormFieldPanel wrapper = (AnswerFormFieldPanel) item.getModelObject();
item.add(wrapper);
Question question = wrapper.getQuestion();
String strPrompt = question.individualizePrompt(wrapper.getAlters());
item.add(new Label("alter", strPrompt));
}
};
questionsView.setReuseItems(true);
add(questionsView);
} else {
strPrompt = question.individualizePrompt(altersInPrompt);
if ( interviewId==null ) {
strPrompt = question.escapeTextInsertionTags(strPrompt);
} else {
strPrompt = question.answerCountInsertion(strPrompt, interviewId);
strPrompt = question.questionContainsAnswerInsertion(strPrompt, interviewId, altersInPrompt);
strPrompt = question.dateDataInsertion(strPrompt, interviewId, altersInPrompt);
strPrompt = question.calculationInsertion(strPrompt, interviewId, altersInPrompt);
strPrompt = question.variableInsertion(strPrompt,interviewId, altersInPrompt);
strPrompt = question.conditionalTextInsertion(strPrompt, interviewId, altersInPrompt);
}
if ( SimpleLogicMgr.hasError()) {
System.out.println ("USE IF error in " + question.getTitle());
}
add(new MultiLineLabel("prompt", strPrompt).setEscapeModelStrings(false));
ListView questionsView = new ListView("questions",answerFields) {
protected void populateItem(ListItem item) {
AnswerFormFieldPanel wrapper = (AnswerFormFieldPanel) item.getModelObject();
item.add(wrapper);
ArrayList<Alter> alters = wrapper.getAlters();
Alter lastAlter = alters.isEmpty() ? null : alters.get(alters.size()-1);
item.add(new Label("alter",
(answerFields.size() < 2 && ! question.getAskingStyleList())
|| lastAlter == null ?
"" : lastAlter.getName()));
}
};
questionsView.setReuseItems(true);
add(questionsView);
}
// the remainder of the function deals with Don't Know and Refuse
// links (buttons) which will not be applicable to Multiple Questions
if ( multipleQuestions ) {
lblBtnAll = new Label("lblSetAlls", "");
pageButtonsForm.add(lblBtnAll);
RepeatingView rv = new RepeatingView("btnParent");
pageButtonsForm.add(rv);
pageButtonsForm.add(new Label("btnDontKnow",""));
pageButtonsForm.add(new Label("btnRefuse",""));
add(pageButtonsForm);
add(new Label("refDKCheck",""));
return;
}
ArrayList<String> allOptions = Lists.newArrayList();
ArrayList<String> selectedOptions = Lists.newArrayList();
strSkipReason = AnswerFormFieldPanel.getSkipReasonForListOfAlters(answerFields);
if ( strSkipReason.equals(dontKnow)) {
selectedOptions.add(dontKnow);
} else if ( strSkipReason.equals(refuse)) {
selectedOptions.add(refuse);
} else if ( strSkipReason.equals(none)) {
selectedOptions.add(none);
}
if( aType.equals(Answer.AnswerType.MULTIPLE_SELECTION) && question.getNoneButton()) {
allOptions.add(none);
}
if( !withDKRefActionButtons &&
qType != Question.QuestionType.EGO_ID &&
answerFields.size() > 1 ) {
allOptions.addAll(Lists.newArrayList(dontKnow,refuse));
}
refDKCheck = new CheckboxesPanel<String>("refDKCheck",allOptions,selectedOptions);
add(refDKCheck);
Long qID = question.getId();
if (qID!=null) {
listOfOptions = Options.getOptionsForQuestion(qID);
} else {
listOfOptions = new ArrayList<QuestionOption>(1);
}
lblBtnAll = new Label("lblSetAlls", "SET ALL UNANSWERED TO...");
pageButtonsForm.add(lblBtnAll);
RepeatingView rv = new RepeatingView("btnParent");
if ( question.getAllButton()) {
for ( QuestionOption option : listOfOptions ) {
WebMarkupContainer parent = new WebMarkupContainer(rv.newChildId());
rv.add(parent);
AjaxFallbackLink btnAll = new AjaxFallbackLink("btnAll") {
public void onClick ( AjaxRequestTarget target) {
AnswerFormFieldPanel.forceSelectionIfNone(answerFields, getModelObjectAsString(),
question.getMaxCheckableBoxes() );
for ( AnswerFormFieldPanel panel : answerFields ) {
target.addComponent(panel);
}
}
};
btnAll.setModel(new Model(option.getName()));
parent.add(btnAll);
btnAll.add(new Label("btnAllLabel",option.getName()));
}
} // end if question.getAllButton()
pageButtonsForm.add(rv);
AjaxFallbackLink btnDontKnow = new AjaxFallbackLink("btnDontKnow") {
public void onClick(AjaxRequestTarget target) {
AnswerFormFieldPanel.forceSelectionIfNone(answerFields, dontKnow, 1);
target.addComponent(this);
for ( AnswerFormFieldPanel panel : answerFields) {
target.addComponent(panel);
}
}
};
pageButtonsForm.add(btnDontKnow);
AjaxFallbackLink btnRefuse = new AjaxFallbackLink("btnRefuse") {
public void onClick(AjaxRequestTarget target) {
AnswerFormFieldPanel.forceSelectionIfNone(answerFields, refuse,1 );
target.addComponent(this);
for ( AnswerFormFieldPanel panel : answerFields) {
target.addComponent(panel);
}
}
};
pageButtonsForm.add(btnRefuse);
add(pageButtonsForm);
// the Don't know & refuse buttons are ONLY for list-of-alters
// with Multiple_Selection type questions AND list-of-alters
if ( withDKRefActionButtons ) {
if ( !question.getAllButton() &&
!question.getPageLevelDontKnowButton() &&
!question.getPageLevelRefuseButton()) {
lblBtnAll.setVisible(false);
}
if ( !question.getPageLevelDontKnowButton()) {
btnDontKnow.setEnabled(false);
btnDontKnow.setVisible(false);
}
if ( !question.getPageLevelRefuseButton()) {
btnRefuse.setEnabled(false);
btnRefuse.setVisible(false);
}
} else {
lblBtnAll.setVisible(false);
btnDontKnow.setEnabled(false);
btnRefuse.setEnabled(false);
btnDontKnow.setVisible(false);
btnRefuse.setVisible(false);
}
}
public List<String> pageFlags() {
if ( multipleQuestions )
return ( new ArrayList<String>());
return refDKCheck.getSelected();
}
public ArrayList<AnswerFormFieldPanel> getAnswerFields() {
return this.answerFields;
}
public static InterviewingPanel createExample(String id, Question question) {
ArrayList<AnswerFormFieldPanel> panels = Lists.newArrayList();
Interview interview = new Interview();
Alter oneAlter = new Alter(interview,"Jacob",1);
List<String> names =
Lists.newArrayList("Emma","Michael","Ethan","Isabella","Joshua");
for(int i = 0; i < (question.getAskingStyleList() ? 5 : 1); i++) {
ArrayList<Alter> alters = Lists.newArrayList();
Alter otherAlter = new Alter(interview,names.get(i),i+2);
if(question.getType().equals(Question.QuestionType.ALTER)) {
alters.add(otherAlter);
}
if(question.getType().equals(Question.QuestionType.ALTER_PAIR)) {
alters.add(oneAlter);
alters.add(otherAlter);
}
panels.add(AnswerFormFieldPanel.getInstance("question", question, alters, interview.getId()));
}
return new InterviewingPanel(id,question,panels, interview.getId());
}
}