package de.tud.kom.socom.web.client.influence;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import com.gargoylesoftware.htmlunit.javascript.host.Event;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.HeadingElement;
import com.google.gwt.dom.client.ParagraphElement;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.uibinder.client.UiTemplate;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Widget;
import de.tud.kom.socom.web.client.eventhandler.FormValueChangeEventHandler;
import de.tud.kom.socom.web.client.events.FormValueChangeEvent;
import de.tud.kom.socom.web.client.htmlelements.ErrorList;
import de.tud.kom.socom.web.client.htmlelements.ErrorListItemView;
import de.tud.kom.socom.web.client.influence.InfluencePresenter.InfluenceAnswerViewInterface;
import de.tud.kom.socom.web.client.influence.InfluencePresenter.InfluenceFreeAnswerViewInterface;
import de.tud.kom.socom.web.client.influence.administration.InfluenceAdministrationView;
import de.tud.kom.socom.web.client.influence.image.AnswerImage;
import de.tud.kom.socom.web.client.influence.image.InfluenceAnswerImageView;
import de.tud.kom.socom.web.client.util.DateTimeUtils;
/**
* @author jkonert
*
*/
public class InfluenceView extends Composite implements InfluencePresenter.InfluenceViewInterface, FormValueChangeEventHandler {
@UiTemplate("InfluenceView.ui.xml")
interface InfluenceViewUiBinder extends UiBinder<Widget, InfluenceView> { }
private static InfluenceViewUiBinder uiBinder = GWT.create(InfluenceViewUiBinder.class);
private InfluencePresenter presenter;
@UiField HeadingElement question;
@UiField DivElement timer;
@UiField ParagraphElement time;
@UiField FlexTable formElements;
@UiField HTMLPanel submitWrapper;
@UiField Button buttonSubmit;
@UiField ErrorList errorList;
@UiField InfluenceAdministrationView adminView;
private Map<InfluenceAnswerViewInterface<?>, HandlerRegistration[]> answers;
private int columnsMax;
private int currentRow;
private int currentColumn;
public InfluenceView(InfluencePresenter presenter) {
this.presenter = presenter;
this.answers = new HashMap<InfluenceAnswerViewInterface<?>,HandlerRegistration[]>();
//InfluencePanel panel = new InfluencePanel(SocomWebEntryPoint.getInstance(), Location.getParameter("influence"));
//initWidget(panel);
initWidget(uiBinder.createAndBindUi(this));
// this.adminView.setVisible(false);
this.adminView.setPresenter(presenter);
this.columnsMax = 1;
this.currentRow = 0;
this.currentColumn = 0;
}
@UiHandler("buttonSubmit")
public void onButtonSubmit(ClickEvent event)
{
presenter.onSubmitForm();
}
@Override
public void setAnswerColumns(int c) {
this.columnsMax = c;
}
@Override
public void showCountdown(Date timeout) {
if (timeout != null)
{
this.time.setInnerText(DateTimeUtils.toShortStringRelative(timeout));
this.timer.removeClassName("hidden");
}
else
{
this.time.setInnerText("..");
this.timer.addClassName("hidden");
}
}
@Override
public void setQuestion(String question)
{
if (question != null && question.length() > 0)
// this.question.setInnerText(SafeHtmlUtils.htmlEscape(addPunctationmarkAppendix(question)));
this.question.setInnerText(addPunctationmarkAppendix(question));
else this.question.setInnerText("");
}
private String addPunctationmarkAppendix(String question) {
if (question == null || question.length() == 0) return "";
question = question.trim();
// check if question already has a PunctationMark at end, otherwise add a question mark (?)
if ("?!.;,".indexOf(question.charAt(question.length()-1))==-1)
{
return question+"?";
}
return question;
}
@Override
public <T> void setPossibleAnswers(List<InfluenceAnswerViewInterface<T>> answers) {
this.currentColumn = this.currentRow = 0;
//check stored answer
for (InfluenceAnswerViewInterface<?> a: this.answers.keySet())
{//if not already contained
if (!answers.contains(a))
{ // remove the element
formElements.remove(a.asWidget());
}
}
for (InfluenceAnswerViewInterface<T> answer: answers)
{
if (!this.answers.containsKey(answer))
{
// only add to form, if not already there. Then do as well listen for events and remember the handler ids.
if(currentColumn == columnsMax)
{
currentColumn = 0;
currentRow++;
}
formElements.setWidget(this.currentRow, this.currentColumn++, answer.asWidget()); //next row next column
// formElements.add(answer.asWidget());
registerViewHandler(answer);
}
}
}
@Override
public <T> void appendAnswer(InfluenceAnswerViewInterface<T> answerView) {
if(currentColumn == columnsMax)
{
currentColumn = 0;
currentRow++;
}
formElements.setWidget(this.currentRow, this.currentColumn++, answerView.asWidget());
// formElements.add(freeAnswerView.asWidget());
registerViewHandler(answerView);
answerView.animate();
}
private <T> void registerViewHandler(InfluenceAnswerViewInterface<T> answerView) {
answerView.asWidget().sinkEvents(Event.CHANGE | Event.BLUR);
HandlerRegistration[] handlers = new HandlerRegistration[0];
this.answers.put(answerView, handlers);
}
@Override
public void replaceAnswers(InfluenceFreeAnswerViewInterface<AnswerImage> oldAnswerView,
InfluenceAnswerImageView newAnswerView, boolean appendOld, boolean selectNew) {
int col = 0, row = 0;
while(!formElements.getWidget(row, col).equals(oldAnswerView))
{
col++;
if(col == columnsMax)
{
col = 0;
row++;
}
}
registerViewHandler(newAnswerView);
formElements.setWidget(row, col, newAnswerView);
if(appendOld) appendAnswer(oldAnswerView);
if(selectNew) newAnswerView.setSelected(selectNew);
}
@SuppressWarnings("unchecked")
@Override
public <T> List<InfluenceAnswerViewInterface<T>> getSelectedAnswers() {
List<InfluenceAnswerViewInterface<T>> result = new LinkedList<InfluenceAnswerViewInterface<T>>();
for (InfluenceAnswerViewInterface<?> answer: answers.keySet())
{
if (answer.isSelected()) result.add((InfluenceAnswerViewInterface<T>)answer); // the cast works as no other options can be passed into...
}
return result;
}
@Override
public void disableSubmit() {
this.buttonSubmit.setEnabled(false);
}
@Override
public void enableSubmit() {
this.buttonSubmit.setEnabled(true);
}
@Override
public void showSubmit(boolean show) {
this.buttonSubmit.setVisible(show);
}
@Override
public void onFormValueChangeEvent(FormValueChangeEvent event) {
if (event.isSelectChange())
{
// Window.alert("Element own event FormValueChange catched");
//inform presenter of a select/deselect
return;
}
// Window.alert("Element own event FormValueChange catched a KeyxValue change to "+event.getValue());
// what about text changes in ownanswers??
}
@Override
public void showError(ErrorListItemView error) {
this.errorList.addError(error);
}
@Override
public void hideErrors() {
this.errorList.clear();
}
@Override
public void hideError(ErrorListItemView error) {
this.errorList.removeError(error);
}
@Override
public void setAdministrationVisible(boolean visible) {
// this.adminView.setVisible(visible);
if(visible)
this.adminView.removeStyleName("hidden");
else
this.adminView.addStyleName("hidden");
}
}