package de.tud.kom.socom.web.client.influence.strategies;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import com.google.gwt.core.client.GWT;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Widget;
import de.tud.kom.socom.web.client.AppController;
import de.tud.kom.socom.web.client.baseelements.viewerrors.ErrorMediaNotReadyView;
import de.tud.kom.socom.web.client.baseelements.viewerrors.ErrorServerUnknownErrorView;
import de.tud.kom.socom.web.client.influence.InfluencePresenter;
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.image.AnswerImage;
import de.tud.kom.socom.web.client.influence.image.InfluenceAnswerFreeImageView;
import de.tud.kom.socom.web.client.influence.image.InfluenceAnswerImageView;
import de.tud.kom.socom.web.client.sharedmodels.InfluenceAnswer;
import de.tud.kom.socom.web.client.sharedmodels.SimpleEntry;
public class ImageInfluenceStrategy extends InfluenceStrategy<AnswerImage> {
private static final String[] VALID_ENDINGS = new String[] { "png", "jpg", "jpeg", "gif" };
private InfluencePresenter presenter;
private List<InfluenceAnswerViewInterface<AnswerImage>> answerImageViews;
private Map<InfluenceAnswerViewInterface<AnswerImage>, InfluenceAnswer> answersPerAnswerView;
private Timer fileDetectionTimer;
private ErrorMediaNotReadyView notReadyError;
private ErrorServerUnknownErrorView unkownError;
private int freeAnswerFormCount;
public ImageInfluenceStrategy(AppController appController, InfluencePresenter influencePresenter) {
super(appController);
presenter = influencePresenter;
answerImageViews = new LinkedList<InfluenceAnswerViewInterface<AnswerImage>>();
answersPerAnswerView = new HashMap<InfluenceAnswerViewInterface<AnswerImage>, InfluenceAnswer>();
notReadyError = new ErrorMediaNotReadyView();
unkownError = new ErrorServerUnknownErrorView();
freeAnswerFormCount = 0;
}
@Override
public void addPredefinedAnswer(InfluenceAnswer answer) {
InfluenceAnswerImageView imageanswer = new InfluenceAnswerImageView(presenter.showResults);
String[] split = answer.getAnswer().split(";");
AnswerImage ai = new AnswerImage(split[1], split[0]);
imageanswer.setAnswer(ai);
if (presenter.showResults)
{
imageanswer.setResultInformation(presenter.getTotalNumberOfVotes(), answer.getResult().getVotes(), presenter
.getWinner().equals(answer));
}
answerImageViews.add(imageanswer);
answersPerAnswerView.put(imageanswer, answer);
imageanswer.enableReporting(false);
}
@Override
public InfluenceAnswerViewInterface<AnswerImage> addFreeAnswer(InfluenceAnswer answer, boolean votable) {
InfluenceAnswerImageView imageanswer = new InfluenceAnswerImageView(presenter.showResults);
String[] split = answer.getAnswer().split(";");
AnswerImage ai = new AnswerImage(split[1], split[0]);
imageanswer.setAnswer(ai);
imageanswer.setFromUser(answer.getOwnerId(), answer.getOwnerName(), answer.getResult().getTimestamp());
if (presenter.showResults)
{
imageanswer.setResultInformation(presenter.getTotalNumberOfVotes(), answer.getResult().getVotes(), presenter
.getWinner().equals(answer));
}
imageanswer.setVotable(votable);
answerImageViews.add(imageanswer);
answersPerAnswerView.put(imageanswer, answer);
return imageanswer;
}
@Override
public void addFreeAnswerForm() {
if (presenter.showResults)
return;
InfluenceAnswerFreeImageView imageanswer = new InfluenceAnswerFreeImageView(false, 60);
answerImageViews.add(imageanswer);
answersPerAnswerView.put(imageanswer, new InfluenceAnswer(this.presenter.getUserId(), true, 2));
this.freeAnswerFormCount++;
}
@Override
public List<InfluenceAnswerViewInterface<AnswerImage>> getPossibleAnswers() {
return answerImageViews;
}
@Override
public List<InfluenceAnswer> collectSelectedAnswers(List<InfluenceAnswerViewInterface<AnswerImage>> selected) {
List<InfluenceAnswer> selectedAnswers = new LinkedList<InfluenceAnswer>();
for (InfluenceAnswerViewInterface<AnswerImage> selectedAnswerView : selected)
{
InfluenceAnswer selectedAnswer = this.answersPerAnswerView.get(selectedAnswerView);
if (selectedAnswer != null)
{
if (selectedAnswer.isNewFreeAnswer())
{
// TODO: filter if necessary
selectedAnswer.setOwnerId(presenter.getUserId());
}
selectedAnswers.add(selectedAnswer);
}
}
if (selectedAnswers.size() < presenter.minOptions || selectedAnswers.size() > presenter.maxOptions)
{
presenter.showErrorMinMax(selectedAnswers.size());
return null;
}
return selectedAnswers;
}
@Override
public InfluenceAnswerViewInterface<AnswerImage> findParentViewForElement(Widget sourceWidget) {
for (InfluenceAnswerViewInterface<AnswerImage> a : answerImageViews)
{
if (a.equals(sourceWidget))
return a;
}
return null;
}
@Override
public void updateFreeAnswerOnChange(InfluenceFreeAnswerViewInterface<AnswerImage> parent, String message) {
}
@Override
public void updateFreeAnswerOnUploadSuccess(final InfluenceFreeAnswerViewInterface<AnswerImage> answer,
SimpleEntry<String, String>[] sourceParameter, final JSONValue result) {
final String filePath = result.isObject().get("file").isString().stringValue();
final boolean[] found = new boolean[] { false };
fileDetectionTimer = new Timer() {
@Override
public void run() {
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, GWT.getHostPageBaseURL()
+ getDataPath(filePath));
try
{
builder.sendRequest(null, new RequestCallback() {
public void onError(Request request, Throwable exception) {
ImageInfluenceStrategy.this.presenter.showError(unkownError);
}
public void onResponseReceived(Request request, Response response) {
if (found[0])
return;
if (response.getStatusCode() == 404)
{
ImageInfluenceStrategy.this.presenter.showError(notReadyError);
} else
{
found[0] = true;
fileDetectionTimer.cancel();
onFreeAnswerFileReady(answer, result);
}
}
});
} catch (RequestException e)
{
ImageInfluenceStrategy.this.presenter.showError(unkownError);
}
}
};
fileDetectionTimer.scheduleRepeating(500);
}
protected void onFreeAnswerFileReady(InfluenceFreeAnswerViewInterface<AnswerImage> answer, JSONValue result) {
this.presenter.hideError(notReadyError);
String filePath = result.isObject().get("file").isString().stringValue();
InfluenceAnswer newAnswer = createReceivedAnswer(result.isObject());
AnswerImage newAnswerObject = new AnswerImage(filePath, newAnswer.getAnswer());
boolean appendFreeAnswer = this.presenter.maxOptions > this.freeAnswerFormCount;
replaceAnswers(answer, newAnswer, newAnswerObject, appendFreeAnswer);
}
private void replaceAnswers(InfluenceFreeAnswerViewInterface<AnswerImage> oldAnswerView, InfluenceAnswer newAnswer,
AnswerImage newAnswerWrap, boolean appendOld) {
InfluenceAnswerImageView newAnswerView = new InfluenceAnswerImageView(presenter.showResults);
newAnswerView.setAnswer(newAnswerWrap);
newAnswerView.setFromUser(this.presenter.getUserId(), this.presenter.getUserName(), new Date());
if(!appendOld)
{ // do not delete if it should also be appended
answerImageViews.remove(oldAnswerView);
answersPerAnswerView.remove(oldAnswerView);
}
answerImageViews.add(newAnswerView);
answersPerAnswerView.put(newAnswerView, newAnswer);
this.presenter.replaceAnswerViews(oldAnswerView, newAnswerView, appendOld, true);
appendItemAdministration(presenter.getUserId(), presenter.userIsAdmin());
}
private InfluenceAnswer createReceivedAnswer(JSONObject object) {
String message = object.get("message").isString().stringValue();
long id = (long) object.get("id").isNumber().doubleValue();
long ownerid = this.presenter.getUserId();
String ownerName = this.presenter.getUserName();
return new InfluenceAnswer(id, message, false, ownerid, ownerName, 0, 2);
}
@Override
public void clearAnsweres() {
answerImageViews.clear();
answersPerAnswerView.clear();
}
@Override
public Map<InfluenceAnswerViewInterface<AnswerImage>, InfluenceAnswer> getAnswerMap() {
return answersPerAnswerView;
}
@Override
public String[] getValidFileEndings() {
return VALID_ENDINGS;
}
}