package org.sana.android.procedure;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import org.sana.android.util.SanaUtil;
import org.w3c.dom.Node;
import android.content.Context;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.ScrollView;
/**
* MultiSelectElement is a ProcedureElement that creates a procedure page with
* multiple check-box items that can be selected.
* <p/>
* <ul type="none">
* <li><b>Clinical Use </b> Defined by subclasses.</li>
* <li><b>Collects </b>Zero or more string values representing items in the
* list of available answers delimited by TOKEN_DELIMITER.</li>
* </ul>
*
* @author Sana Development Team
*/
public class MultiSelectElement extends SelectionElement {
private String[] choices;
private ArrayList<CheckBox> cblist;
/** {@inheritDoc} */
@Override
public ElementType getType() {
return ElementType.MULTI_SELECT;
}
/** {@inheritDoc} */
@Override
protected View createView(Context c) {
ScrollView sv = new ScrollView(c);
LinearLayout ll = new LinearLayout(c);
HashSet<String> selectedSet = new HashSet<String>();
if(answer == null)
answer = "";
// we've got a problem if there are TOKEN_DELIMITERs in the value!
// since getAnswer separates responses using TOKEN_DELIMITER
String[] values = answer.split(TOKEN_DELIMITER);
for(String val : values) {
selectedSet.add(val);
}
ll.setOrientation(LinearLayout.VERTICAL);
cblist = new ArrayList<CheckBox>();
for(String choice : labels()) {
CheckBox cb = new CheckBox(c);
cb.setTag(getValueFromLabel(choice));
cb.setText(choice);
cb.setChecked(selectedSet.contains(String.valueOf(cb.getTag())));
cblist.add(cb);
ll.addView(cb);
}
sv.addView(ll, new ViewGroup.LayoutParams(-1,-1));
return encapsulateQuestion(c, sv);
}
/** {@inheritDoc} */
@Override
public void setAnswer(String answer) {
Log.i(TAG,"[" + id +"]setAnswer() --> " + answer);
this.answer = (answer == null)?"":answer;
// Update UI if visible
if(isViewActive()) {
for (CheckBox c : cblist) {
String label = c.getText().toString();
String value = String.valueOf(c.getTag());
if(answer.contains(value)) {
c.setChecked(true);
} else{
c.setChecked(false);
}
}
}
}
/** {@inheritDoc} */
@Override
public String getAnswer() {
Log.i(TAG,"[" + id +"]getAnswer()");
String val = "";
if(!isViewActive())
val = (answer == null)?"":answer;
else {
boolean any = false;
// loop over list and add to answer if checked
for (CheckBox c : cblist) {
if (c.isChecked()) {
val += c.getTag() + TOKEN_DELIMITER;
any = true;
}
}
//Remove trailing
if(any)
val = val.substring(0, val.length()-1);
}
Log.d(TAG, "...returning " + val);
return val;
}
/** Default constructor */
private MultiSelectElement(String id, String question, String answer,
String concept, String figure, String audio, String[] labels)
{
super(id, question, answer, concept, figure, audio, labels);
}
private MultiSelectElement(String id, String question, String answer,
String concept, String figure, String audio,
String[] labels, String[] values)
{
super(id, question, answer, concept, figure, audio, labels,values);
}
/** @see SelectionElement#fromXML(String, String, String, String, String,
* String,
* Node) */
public static MultiSelectElement fromXML(String id, String question,
String answer, String concept, String figure, String audio, Node node)
throws ProcedureParseException
{
String choicesStr = SanaUtil.getNodeAttributeOrDefault(node, "choices",
"");
String valuesStr = SanaUtil.getNodeAttributeOrDefault(node, "values",
choicesStr);
return new MultiSelectElement(id, question, answer, concept, figure,
audio, choicesStr.split(SelectionElement.TOKEN_DELIMITER),
valuesStr.split(SelectionElement.TOKEN_DELIMITER));
}
}