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.audio.AnswerAudio;
import de.tud.kom.socom.web.client.influence.audio.InfluenceAnswerAudioView;
import de.tud.kom.socom.web.client.influence.audio.InfluenceAnswerFreeAudioView;
import de.tud.kom.socom.web.client.sharedmodels.InfluenceAnswer;
import de.tud.kom.socom.web.client.sharedmodels.SimpleEntry;
public class AudioInfluenceStrategy extends InfluenceStrategy<AnswerAudio> {
private static final String[] VALID_ENDINGS = new String[] {"mp3", "ogg"};
private InfluencePresenter presenter;
private List<InfluenceAnswerViewInterface<AnswerAudio>> answersAudio;
private HashMap<InfluenceAnswerViewInterface<AnswerAudio>, InfluenceAnswer> answers;
private Timer fileDetectionTimer;
private ErrorMediaNotReadyView notReadyError;
private ErrorServerUnknownErrorView unkownError;
private int freeAnswerFormCount;
public AudioInfluenceStrategy(AppController appController, InfluencePresenter influencePresenter) {
super(appController);
presenter = influencePresenter;
answersAudio = new LinkedList<InfluenceAnswerViewInterface<AnswerAudio>>();
answers = new HashMap<InfluenceAnswerViewInterface<AnswerAudio>,InfluenceAnswer>();
notReadyError = new ErrorMediaNotReadyView();
unkownError = new ErrorServerUnknownErrorView();
freeAnswerFormCount = 0;
}
@Override
public void addPredefinedAnswer(InfluenceAnswer answer) {
InfluenceAnswerAudioView audioanswer = new InfluenceAnswerAudioView(false);
String filePath = getDataPath(answer.getAnswer().split(";")[1]);
audioanswer.setAnswer(new AnswerAudio(filePath, answer.getAnswer().split(";")[0]));
if(presenter.showResults){
audioanswer.setResultInformation(presenter.getTotalNumberOfVotes(), answer.getResult().getVotes(), presenter.getWinner().equals(answer));
}
answersAudio.add(audioanswer);
answers.put(audioanswer, answer);
}
@Override
public InfluenceAnswerViewInterface<AnswerAudio> addFreeAnswer(InfluenceAnswer answer, boolean votable) {
InfluenceAnswerAudioView audioanswer = new InfluenceAnswerAudioView(presenter.showResults);
String filePath = getDataPath(answer.getAnswer().split(";")[1]);
audioanswer.setAnswer(new AnswerAudio(filePath, answer.getAnswer().split(";")[0]));
audioanswer.setFromUser(answer.getOwnerId(), answer.getOwnerName(), answer.getResult().getTimestamp());
if(presenter.showResults){
audioanswer.setResultInformation(presenter.getTotalNumberOfVotes(), answer.getResult().getVotes(), presenter.getWinner().equals(answer));
}
audioanswer.setVotable(votable);
answersAudio.add(audioanswer);
answers.put(audioanswer, answer);
return audioanswer;
}
@Override
public void addFreeAnswerForm() {
if(presenter.showResults) return;
/**an answer with free audio...changes to this are reflected in FormValueChangeEvent **/
InfluenceAnswerFreeAudioView audioanswer = new InfluenceAnswerFreeAudioView(false, 60);
answersAudio.add(audioanswer);
//TODO visibility
answers.put(audioanswer, new InfluenceAnswer(this.presenter.getUserId(), true, 2));
this.freeAnswerFormCount++;
}
@Override
public List<InfluenceAnswer> collectSelectedAnswers(List<InfluenceAnswerViewInterface<AnswerAudio>> selected) {
List<InfluenceAnswer> selectedAnswers = new LinkedList<InfluenceAnswer>();
for (InfluenceAnswerViewInterface<AnswerAudio> formelem: selected)
{
InfluenceAnswer a = this.answers.get(formelem);
if(a != null){
if(a.isNewFreeAnswer()){
a.setOwnerId(presenter.getUserId());
}
selectedAnswers.add(a);
}
}
if (selectedAnswers.size() < presenter.minOptions || selectedAnswers.size() > presenter.maxOptions)
{
presenter.showErrorMinMax(selectedAnswers.size());
return null;
}
return selectedAnswers;
}
@Override
public InfluenceAnswerViewInterface<AnswerAudio> findParentViewForElement(Widget sourceWidget) {
for(InfluenceAnswerViewInterface<AnswerAudio> a: answersAudio)
{
if (a.equals(sourceWidget)) return a;
}
return null;
}
@Override
public void updateFreeAnswerOnChange(InfluenceFreeAnswerViewInterface<AnswerAudio> answer, String value) {
}
@Override
public void updateFreeAnswerOnUploadSuccess(
final InfluenceFreeAnswerViewInterface<AnswerAudio> answer,
SimpleEntry<String, String>[] sourceParameter, final JSONValue result) {
final String filePath = result.isObject().get("file").isString().stringValue();
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) {
AudioInfluenceStrategy.this.presenter.showError(unkownError);
}
public void onResponseReceived(Request request, Response response) {
if(response.getStatusCode() == 404)
{
AudioInfluenceStrategy.this.presenter.showError(notReadyError);
}
else
{
fileDetectionTimer.cancel();
onFreeAnswerFileReady(answer, result);
}
}
});
} catch (RequestException e) {
AudioInfluenceStrategy.this.presenter.showError(unkownError);
}
}
};
fileDetectionTimer.scheduleRepeating(500);
}
protected void onFreeAnswerFileReady(InfluenceFreeAnswerViewInterface<AnswerAudio> answer, JSONValue result) {
this.presenter.hideError(notReadyError);
String filePath = result.isObject().get("file").isString().stringValue();
InfluenceAnswer newAnswer = createReceivedAnswer(result.isObject());
replaceFreeAnswerFormWithAnswer(answer, filePath, newAnswer);
if(this.presenter.maxOptions > this.freeAnswerFormCount)
this.addFreeAnswerForm();
this.presenter.paintAnswers();
}
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();
int deletedFlag = 0;
int visibility = 2;
return new InfluenceAnswer(id, message, false, ownerid, ownerName, deletedFlag, visibility);
}
private InfluenceAnswerAudioView replaceFreeAnswerFormWithAnswer(InfluenceFreeAnswerViewInterface<AnswerAudio> answer, String filePath, InfluenceAnswer newAnswer) {
InfluenceAnswerAudioView newanswer = new InfluenceAnswerAudioView(presenter.showResults);
newanswer.setAnswer(new AnswerAudio(getDataPath(filePath), newAnswer.getAnswer()));
newanswer.setFromUser(this.presenter.getUserId(), this.presenter.getUserName(), new Date());
if(answersAudio.remove(answer) && answers.remove(answer) != null){
answersAudio.add(newanswer);
answers.put(newanswer, newAnswer);
}
return newanswer;
}
@Override
public List<InfluenceAnswerViewInterface<AnswerAudio>> getPossibleAnswers() {
return answersAudio;
}
@Override
public void clearAnsweres() {
answersAudio.clear();
answers.clear();
}
@Override
public Map<InfluenceAnswerViewInterface<AnswerAudio>, InfluenceAnswer> getAnswerMap() {
return answers;
}
@Override
public String[] getValidFileEndings() {
return VALID_ENDINGS;
}
}