package nl.uva.polyql.ast;
import java.awt.Component;
import java.util.HashSet;
import java.util.Set;
import nl.uva.polyql.ast.values.StringValue;
import nl.uva.polyql.ast.values.Type;
import nl.uva.polyql.ast.values.Value;
import nl.uva.polyql.utils.Log;
import nl.uva.polyql.validation.ValidationErrors;
public class Question implements Rule {
private final String mId;
private final String mLabel;
private final Type mType;
private Value<?> mValue;
private boolean mValueValid = true;
private LineInfo mLineInfo;
private final Set<ValueListener> mUpdateListeners = new HashSet<>();
protected Question(final String id, final String label, final String type) {
this(id, label, Type.valueOf(type.toUpperCase()));
}
protected Question(final String id, final String label, final Type type) {
mId = id;
mLabel = StringValue.parse(label).getValue();
mType = type;
setValue(mType.getDefaultValue());
}
/**
* Sets this question's value and determines if the value is valid. Informs listeners of the
* change.
*
* @param value
* The new value
*
* @return True iff the value is valid
*/
public boolean setValue(final Value<?> value) {
if (value.getType() == mType) {
mValue = value;
mValueValid = true;
} else {
mValueValid = false;
}
for (final ValueListener listener : mUpdateListeners) {
listener.onQuestionUpdate(this);
}
return mValueValid;
}
@Override
public Component getView() {
return mValue.getView(this).getComponent();
}
public void addUpdateListener(final ValueListener listener) {
Log.i("LISTENER " + listener + " ADDED TO " + this);
mUpdateListeners.add(listener);
}
public Value<?> getValue() {
return mValue;
}
public boolean isValueValid() {
return mValueValid;
}
public boolean isEditable() {
return true;
}
@Override
public ValidationErrors validate() {
return new ValidationErrors();
}
@Override
public String toString() {
return mId;
}
public String getId() {
return mId;
}
public String getLabel() {
return mLabel;
}
public Type getType() {
return mType;
}
@Override
public void setLineInfo(final LineInfo lineInfo) {
mLineInfo = lineInfo;
}
@Override
public LineInfo getLineInfo() {
return mLineInfo;
}
/**
* The interface for that must be implemented to receive call-backs when the question's value is
* update, e.g., when the user types in the question's field.
*/
public interface ValueListener {
/**
* Called when the question's value is updated. E.g., when the user types in the question's
* field.
*
* @param question
* The question that called the method
*/
public void onQuestionUpdate(final Question question);
}
}