Rev 2000 | Blame | Compare with Previous | Last modification | View Log | RSS feed
package org.tela_botanica.del.client.composants.votes.moyennevotes;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import org.tela_botanica.del.client.cache.CacheClient;
import org.tela_botanica.del.client.composants.votefleur.VoteFleurPresenteur;
import org.tela_botanica.del.client.composants.votefleur.VoteFleurVue;
import org.tela_botanica.del.client.modeles.Image;
import org.tela_botanica.del.client.modeles.Protocole;
import org.tela_botanica.del.client.modeles.VoteProtocole;
import org.tela_botanica.del.client.navigation.evenement.BusEvenementiel;
import org.tela_botanica.del.client.navigation.evenement.changementEtatUtilisateur.EvenementChangementEtatUtilisateur;
import org.tela_botanica.del.client.navigation.evenement.changementEtatUtilisateur.GestionnaireEvenementChangementEtatUtilisateur;
import org.tela_botanica.del.client.navigation.evenement.suppressioncommentaire.EvenementSuppressionCommentaire;
import org.tela_botanica.del.client.navigation.evenement.suppressioncommentaire.GestionnaireEvenementSuppressionCommentaire;
import org.tela_botanica.del.client.services.rest.VoteProtocoleService;
import org.tela_botanica.del.client.services.rest.async.AjoutVoteProtocoleCallback;
import org.tela_botanica.del.client.services.rest.async.VoteProtocoleCallback;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.dom.client.HasMouseMoveHandlers;
import com.google.gwt.event.dom.client.MouseMoveEvent;
import com.google.gwt.event.dom.client.MouseMoveHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.HasWidgets;
import com.google.gwt.user.client.ui.IsWidget;
import com.google.gwt.user.client.ui.Panel;
public class MoyenneVotePresenteur {
public interface Vue extends IsWidget {
public HasClickHandlers getBoutonAnnuler();
public HasClickHandlers getVotes();
public int getValeurVote();
public void afficherBoutonAnnuler();
public void masquerBoutonAnnuler();
public void afficherNbVotes();
public void masquerNbVotes();
//public void afficherNbPoints();
//public void masquerNbPoints();
public void reinitialiserVotes();
public void rafraichir(int moyenneVote, int nbVotes, int nombrePoints, double moyenneArithmetique, double mediane, HashMap<Integer,Integer> occurrencesParNote, double moyennePonderee);
public void ajouterAuParent(HasWidgets composite);
public void afficherVotePrisEnCompte();
public HasWidgets getZoneFleur();
public HasText getZoneProtocole();
public HasText getNbVotes();
//public HasText getNbPoints();
public HasClickHandlers getLienNbVotes();
public void setNoteGenerale(int note);
public void afficherVoteModifie();
public HasMouseMoveHandlers getZoneVoter();
public void masquerZoneVoter();
public void afficherMessageVoteIdentifie(boolean doitEtreIdentifiePourVoter);
public void setNoteGeneraleToolTip(double valeurVoteTotalPrecise);
public void desactiverInteractionVote();
public void activerInteractionVote();
public void afficherVoteSupprime();
public Panel getPanneauDetailVotes();
public void afficherPanneauDetailVotes();
public void masquerPanneauDetailVotes();
public HasClickHandlers getLienPanneauFermer();
}
private Vue vue;
private Protocole protocole;
private Image image;
private int valeurVoteDefaut = -1;
private int valeurVoteUtilisateur = -1;
private int valeurVoteTotal = 0;
private double moyenneArithmetique = 0;
private double mediane = 0;
private int nombrePoints = 0;
private double valeurVoteTotalPrecise = 0.0;
private HashMap<Integer,Integer> occurrencesParNote;
// TODO: on devrait passer un conteneur qui permet d'accéder à ces services
private VoteProtocoleService voteProtocoleService;
public MoyenneVotePresenteur(Image image, Protocole protocole, Vue vue,
VoteProtocoleService voteProtocoleService) {
this.vue = vue;
this.protocole = protocole;
this.image = image;
this.voteProtocoleService = voteProtocoleService;
String nomProtocole = protocole.getNom();
nomProtocole = nomProtocole.substring(0, 1).toUpperCase()
+ nomProtocole.substring(1).toLowerCase();
vue.getZoneProtocole().setText(nomProtocole);
}
public void go(HasWidgets composite) {
vue.ajouterAuParent(composite);
gererEvenements();
rafraichirVue();
}
public void gererEvenements() {
vue.afficherMessageVoteIdentifie(utilisateurPeutVoter());
vue.getZoneVoter().addMouseMoveHandler(new MouseMoveHandler() {
@Override
public void onMouseMove(MouseMoveEvent event) {
if(utilisateurPeutVoter()) {
vue.masquerZoneVoter();
}
}
});
vue.getVotes().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
if(utilisateurPeutVoter()) {
valeurVoteUtilisateur = vue.getValeurVote();
enregistrerVote();
vue.afficherBoutonAnnuler();
} else {
Window.alert("Voter pour ce protocole nécéssite d'être identifié");
}
}
});
vue.getBoutonAnnuler().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
valeurVoteUtilisateur = valeurVoteDefaut;
vue.masquerBoutonAnnuler();
supprimerVote();
vue.reinitialiserVotes();
}
});
// Affiche un chouette panneau qui montre le détail des votes
vue.getLienNbVotes().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
if (vue.getPanneauDetailVotes().isVisible()) {
vue.masquerPanneauDetailVotes();
} else {
vue.afficherPanneauDetailVotes();
}
}
});
vue.getLienPanneauFermer().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
vue.masquerPanneauDetailVotes();
}
});
BusEvenementiel.getInstance().addHandler(EvenementChangementEtatUtilisateur.TYPE, new GestionnaireEvenementChangementEtatUtilisateur() {
@Override
public void onModificationEtatUtilisateur(EvenementChangementEtatUtilisateur evenementChangementEtatUtilisateur) {
rafraichirVue();
}
});
}
public boolean utilisateurPeutVoter() {
return !protocole.doitEtreIdentifiePourVoter() || CacheClient.getInstance().getUtilisateur().estIdentifie();
}
public void setValeurVoteUtilisateur(int valeurVoteUtilisateur) {
this.valeurVoteUtilisateur = valeurVoteUtilisateur;
}
public void enregistrerVote() {
vue.desactiverInteractionVote();
final VoteProtocole voteProtocole = new VoteProtocole();
voteProtocole.setProtocole(this.protocole);
voteProtocole.setVote(valeurVoteUtilisateur);
String idContributeur = CacheClient.getInstance().getUtilisateur()
.getId();
voteProtocole.setContributeur(idContributeur);
//TODO: ceci devrait pouvoir être factorisé
if (image.utilisateurAVotePourProtocole(this.protocole.getId() + "",
idContributeur)) {
voteProtocole.setId(image.getVotesProtocoles(this.protocole.getId()+"").get(idContributeur).getId());
VoteProtocoleCallback vpc = new VoteProtocoleCallback() {
@Override
public void surRetour(Void objetRetour) {
image.ajouterVoteProtocole(voteProtocole);
rafraichirVue();
vue.afficherVoteModifie();
vue.activerInteractionVote();
}
};
voteProtocoleService.modifierVote(image.getIdImage(),
voteProtocole, vpc);
} else {
AjoutVoteProtocoleCallback vpc = new AjoutVoteProtocoleCallback() {
@Override
public void surRetour(String idVote) {
voteProtocole.setId(idVote);
image.ajouterVoteProtocole(voteProtocole);
rafraichirVue();
vue.afficherVotePrisEnCompte();
vue.activerInteractionVote();
}
};
voteProtocoleService.ajouterVote(image.getIdImage(), voteProtocole,
vpc);
}
}
public void supprimerVote() {
vue.desactiverInteractionVote();
final String idContributeur = CacheClient.getInstance().getUtilisateur()
.getId();
final VoteProtocole voteProtocole = image.getVotesProtocoles(protocole.getId()).get(idContributeur);
VoteProtocoleCallback vpc = new VoteProtocoleCallback() {
@Override
public void surRetour(Void objetRetour) {
// TODO: voir si l'on affiche un message en cas de succès ?
image.supprimerVoteProtocole(protocole.getId() + "", idContributeur);
rafraichirVue();
vue.afficherVoteSupprime();
vue.activerInteractionVote();
}
};
voteProtocoleService.supprimerVote(image.getIdImage(), voteProtocole, vpc);
}
public int getValeurVoteTotal() {
return valeurVoteTotal;
}
public IsWidget getVue() {
return vue;
}
private void rafraichirVue() {
valeurVoteTotal = calculerMoyenneVotesArrondie();
moyenneArithmetique = calculerMoyenneVotes();
mediane = calculerMedianeVotes();
valeurVoteTotalPrecise = calculerMoyennePondereeVotes();
nombrePoints = calculerNombrePointsEchelleArbitraire();
VoteProtocole voteProtocole = image.getVotesProtocoles(
protocole.getId()).get(
CacheClient.getInstance().getUtilisateur().getId());
int voteUtilisateur = 0;
if (voteProtocole != null) {
voteUtilisateur = voteProtocole.getVote();
vue.masquerZoneVoter();
}
if(image.utilisateurAVotePourProtocole(protocole.getId()+"", CacheClient.getInstance().getUtilisateur().getId())) {
vue.afficherBoutonAnnuler();
}
vue.afficherMessageVoteIdentifie(utilisateurPeutVoter());
VoteFleurPresenteur presenteurFleur = new VoteFleurPresenteur(
new VoteFleurVue());
presenteurFleur.setNote(valeurVoteTotal);
vue.setNoteGenerale(valeurVoteTotal);
vue.setNoteGeneraleToolTip(valeurVoteTotalPrecise);
presenteurFleur.go(vue.getZoneFleur());
vue.rafraichir(voteUtilisateur, image.getVotesProtocoles(protocole.getId()).size(), nombrePoints,
moyenneArithmetique, mediane, occurrencesParNote, valeurVoteTotalPrecise);
}
public double calculerMedianeVotes() {
double med = 0;
// comparateur de votes (le bulldozer Java™ pour écraser une mouche)
class Comparatisateur3000 implements Comparator<VoteProtocole> {
@Override
public int compare(VoteProtocole v1, VoteProtocole v2) {
if (v1.getVote() > v2.getVote()) {
return 1;
} else if (v1.getVote() > v2.getVote()) {
return -1;
} else {
return 0;
}
}
}
// conversion en liste triable
List<VoteProtocole> liste = new ArrayList<VoteProtocole>(image.getVotesProtocoles(protocole.getId()).values());
Collections.sort(liste, new Comparatisateur3000());
int longueur = liste.size();
if (longueur > 0) {
if (longueur % 2 == 0) {
// moyenne des éléments centraux
med = (liste.get(longueur / 2 - 1).getVote() + liste.get(longueur / 2).getVote()) / 2;
} else {
// élément central
med = liste.get((int) (longueur / 2)).getVote();
}
}
return med;
}
// calcule la moyenne arithmétique
public double calculerMoyenneVotes() {
double valeurVote = 0;
double nbVote = 0;
for (Iterator<String> iterator = image
.getVotesProtocoles(protocole.getId()).keySet().iterator(); iterator
.hasNext();) {
VoteProtocole imageCelValidationData = image.getVotesProtocoles(
protocole.getId()).get(iterator.next());
valeurVote += (double) imageCelValidationData.getVote() / 5;
nbVote++;
}
if (nbVote > 0) {
valeurVote /= nbVote;
valeurVote *= 5;
}
return valeurVote;
}
// Calcule une moyenne, où chaque note est pondérée par son nombre d'occurrences au carré.
// voir http://www.tela-botanica.org/wikini/DevInformatiques/wakka.php?wiki=AppliDelCalculVotes
public double calculerMoyennePondereeVotes() {
double score = 0;
double diviseur = 0;
int nbOccurrences;
// mise à jour des occurrences par note, utile pour le panneau de détails
occurrencesParNote = new HashMap<Integer,Integer>();
// rangement par note => occurrences
for (String clef : image.getVotesProtocoles(protocole.getId()).keySet()) {
VoteProtocole imageCelValidationData = image.getVotesProtocoles(protocole.getId()).get(clef);
nbOccurrences = 1;
if (occurrencesParNote.containsKey(imageCelValidationData.getVote())) {
nbOccurrences = occurrencesParNote.get(imageCelValidationData.getVote()) + 1;
}
occurrencesParNote.put(imageCelValidationData.getVote(), nbOccurrences);
}
// calcul pondéré
for (Integer clef : occurrencesParNote.keySet()) {
score += clef * occurrencesParNote.get(clef) * occurrencesParNote.get(clef);
diviseur += occurrencesParNote.get(clef) * occurrencesParNote.get(clef);
}
if (diviseur > 0) {
score /= diviseur;
}
return score;
}
// remplace chaque note par un nombre de points noté dans "echelle" afin de favoriser
// les note fortes (5 et 4), pour le défi photo notamment
public int calculerNombrePointsEchelleArbitraire() {
int points = 0;
//int[] echelle = {-1,0,1,4,20};
int[] echelle = {1,10,100,1000,10000};
for (String clef : image.getVotesProtocoles(protocole.getId()).keySet()) {
VoteProtocole imageCelValidationData = image.getVotesProtocoles(protocole.getId()).get(clef);
if (imageCelValidationData.getVote() > 0) {
points += echelle[imageCelValidationData.getVote() - 1];
}
}
return points;
}
public int calculerMoyenneVotesArrondie() {
//double valeurVote = calculerMoyenneVotes();
double valeurVote = calculerMoyennePondereeVotes();
return (int) Math.round(valeurVote);
}
}