Subversion Repositories eFlore/Applications.del

Rev

Rev 2080 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
638 aurelien 1
package org.tela_botanica.del.client.composants.votes.moyennevotes;
9 benjamin 2
 
1583 mathias 3
import java.util.ArrayList;
4
import java.util.Collections;
5
import java.util.Comparator;
1566 mathias 6
import java.util.HashMap;
629 aurelien 7
import java.util.Iterator;
1583 mathias 8
import java.util.List;
9 benjamin 9
 
629 aurelien 10
import org.tela_botanica.del.client.cache.CacheClient;
1085 gduche 11
import org.tela_botanica.del.client.composants.votefleur.VoteFleurPresenteur;
12
import org.tela_botanica.del.client.composants.votefleur.VoteFleurVue;
629 aurelien 13
import org.tela_botanica.del.client.modeles.Image;
423 gduche 14
import org.tela_botanica.del.client.modeles.Protocole;
148 benjamin 15
import org.tela_botanica.del.client.modeles.VoteProtocole;
1471 aurelien 16
import org.tela_botanica.del.client.navigation.evenement.BusEvenementiel;
17
import org.tela_botanica.del.client.navigation.evenement.changementEtatUtilisateur.EvenementChangementEtatUtilisateur;
18
import org.tela_botanica.del.client.navigation.evenement.changementEtatUtilisateur.GestionnaireEvenementChangementEtatUtilisateur;
19
import org.tela_botanica.del.client.navigation.evenement.suppressioncommentaire.EvenementSuppressionCommentaire;
20
import org.tela_botanica.del.client.navigation.evenement.suppressioncommentaire.GestionnaireEvenementSuppressionCommentaire;
423 gduche 21
import org.tela_botanica.del.client.services.rest.VoteProtocoleService;
1471 aurelien 22
import org.tela_botanica.del.client.services.rest.async.AjoutVoteProtocoleCallback;
823 aurelien 23
import org.tela_botanica.del.client.services.rest.async.VoteProtocoleCallback;
939 benjamin 24
 
423 gduche 25
import com.google.gwt.event.dom.client.ClickEvent;
26
import com.google.gwt.event.dom.client.ClickHandler;
629 aurelien 27
import com.google.gwt.event.dom.client.HasClickHandlers;
1095 gduche 28
import com.google.gwt.event.dom.client.HasMouseMoveHandlers;
29
import com.google.gwt.event.dom.client.MouseMoveEvent;
30
import com.google.gwt.event.dom.client.MouseMoveHandler;
1471 aurelien 31
import com.google.gwt.user.client.Window;
629 aurelien 32
import com.google.gwt.user.client.ui.HasText;
9 benjamin 33
import com.google.gwt.user.client.ui.HasWidgets;
629 aurelien 34
import com.google.gwt.user.client.ui.IsWidget;
1583 mathias 35
import com.google.gwt.user.client.ui.Panel;
9 benjamin 36
 
14 benjamin 37
public class MoyenneVotePresenteur {
9 benjamin 38
 
629 aurelien 39
	public interface Vue extends IsWidget {
40
		public HasClickHandlers getBoutonAnnuler();
939 benjamin 41
 
629 aurelien 42
		public HasClickHandlers getVotes();
939 benjamin 43
 
629 aurelien 44
		public int getValeurVote();
939 benjamin 45
 
629 aurelien 46
		public void afficherBoutonAnnuler();
939 benjamin 47
 
629 aurelien 48
		public void masquerBoutonAnnuler();
939 benjamin 49
 
629 aurelien 50
		public void afficherNbVotes();
939 benjamin 51
 
52
		public void masquerNbVotes();
53
 
1583 mathias 54
		//public void afficherNbPoints();
1566 mathias 55
 
1583 mathias 56
		//public void masquerNbPoints();
1566 mathias 57
 
629 aurelien 58
		public void reinitialiserVotes();
939 benjamin 59
 
1583 mathias 60
		public void rafraichir(int moyenneVote, int nbVotes, int nombrePoints, double moyenneArithmetique, double mediane, HashMap<Integer,Integer> occurrencesParNote, double moyennePonderee);
939 benjamin 61
 
629 aurelien 62
		public void ajouterAuParent(HasWidgets composite);
1095 gduche 63
 
1084 gduche 64
		public void afficherVotePrisEnCompte();
1095 gduche 65
 
1085 gduche 66
		public HasWidgets getZoneFleur();
1095 gduche 67
 
1086 gduche 68
		public HasText getZoneProtocole();
1095 gduche 69
 
1583 mathias 70
		public HasText getNbVotes();
71
 
72
		//public HasText getNbPoints();
73
 
74
		public HasClickHandlers getLienNbVotes();
75
 
1088 gduche 76
		public void setNoteGenerale(int note);
1095 gduche 77
 
1092 gduche 78
		public void afficherVoteModifie();
1095 gduche 79
 
80
		public HasMouseMoveHandlers getZoneVoter();
81
		public void masquerZoneVoter();
2080 aurelien 82
 
83
		public void afficherMessageVoteIdentifie(boolean doitEtreIdentifiePourVoter);
1266 aurelien 84
 
85
		public void setNoteGeneraleToolTip(double valeurVoteTotalPrecise);
1471 aurelien 86
 
1583 mathias 87
		public void desactiverInteractionVote();
1471 aurelien 88
 
1583 mathias 89
		public void activerInteractionVote();
1471 aurelien 90
 
1583 mathias 91
		public void afficherVoteSupprime();
92
 
93
		public Panel getPanneauDetailVotes();
94
 
95
		public void afficherPanneauDetailVotes();
96
 
97
		public void masquerPanneauDetailVotes();
98
 
99
		public HasClickHandlers getLienPanneauFermer();
629 aurelien 100
	}
939 benjamin 101
 
629 aurelien 102
	private Vue vue;
423 gduche 103
	private Protocole protocole;
629 aurelien 104
	private Image image;
939 benjamin 105
 
629 aurelien 106
	private int valeurVoteDefaut = -1;
107
	private int valeurVoteUtilisateur = -1;
108
	private int valeurVoteTotal = 0;
1583 mathias 109
	private double moyenneArithmetique = 0;
110
	private double mediane = 0;
1566 mathias 111
	private int nombrePoints = 0;
1266 aurelien 112
	private double valeurVoteTotalPrecise = 0.0;
1583 mathias 113
	private HashMap<Integer,Integer> occurrencesParNote;
939 benjamin 114
 
115
	// TODO: on devrait passer un conteneur qui permet d'accéder à ces services
959 benjamin 116
	private VoteProtocoleService voteProtocoleService;
939 benjamin 117
 
1095 gduche 118
	public MoyenneVotePresenteur(Image image, Protocole protocole, Vue vue,
119
			VoteProtocoleService voteProtocoleService) {
629 aurelien 120
		this.vue = vue;
423 gduche 121
		this.protocole = protocole;
629 aurelien 122
		this.image = image;
959 benjamin 123
		this.voteProtocoleService = voteProtocoleService;
1095 gduche 124
 
1086 gduche 125
		String nomProtocole = protocole.getNom();
1095 gduche 126
		nomProtocole = nomProtocole.substring(0, 1).toUpperCase()
127
				+ nomProtocole.substring(1).toLowerCase();
1086 gduche 128
		vue.getZoneProtocole().setText(nomProtocole);
9 benjamin 129
	}
130
 
629 aurelien 131
	public void go(HasWidgets composite) {
132
		vue.ajouterAuParent(composite);
423 gduche 133
		gererEvenements();
629 aurelien 134
		rafraichirVue();
9 benjamin 135
	}
939 benjamin 136
 
423 gduche 137
	public void gererEvenements() {
1095 gduche 138
 
2080 aurelien 139
		vue.afficherMessageVoteIdentifie(utilisateurPeutVoter());
1095 gduche 140
		vue.getZoneVoter().addMouseMoveHandler(new MouseMoveHandler() {
141
 
142
			@Override
143
			public void onMouseMove(MouseMoveEvent event) {
2080 aurelien 144
				if(utilisateurPeutVoter()) {
145
					vue.masquerZoneVoter();
146
				}
1095 gduche 147
			}
148
		});
149
 
423 gduche 150
		vue.getVotes().addClickHandler(new ClickHandler() {
151
			@Override
152
			public void onClick(ClickEvent event) {
2080 aurelien 153
				if(utilisateurPeutVoter()) {
154
					valeurVoteUtilisateur = vue.getValeurVote();
155
					enregistrerVote();
156
					vue.afficherBoutonAnnuler();
157
				} else {
158
					Window.alert("Voter pour ce protocole nécéssite d'être identifié");
159
				}
160
 
423 gduche 161
			}
162
		});
939 benjamin 163
 
423 gduche 164
		vue.getBoutonAnnuler().addClickHandler(new ClickHandler() {
165
			@Override
166
			public void onClick(ClickEvent event) {
629 aurelien 167
				valeurVoteUtilisateur = valeurVoteDefaut;
423 gduche 168
				vue.masquerBoutonAnnuler();
1471 aurelien 169
				supprimerVote();
423 gduche 170
				vue.reinitialiserVotes();
171
			}
172
		});
1583 mathias 173
 
174
		// Affiche un chouette panneau qui montre le détail des votes
175
		vue.getLienNbVotes().addClickHandler(new ClickHandler() {
176
			@Override
177
			public void onClick(ClickEvent event) {
178
				if (vue.getPanneauDetailVotes().isVisible()) {
179
					vue.masquerPanneauDetailVotes();
180
				} else {
181
					vue.afficherPanneauDetailVotes();
182
				}
183
			}
184
		});
185
 
186
		vue.getLienPanneauFermer().addClickHandler(new ClickHandler() {
187
			@Override
188
			public void onClick(ClickEvent event) {
189
				vue.masquerPanneauDetailVotes();
190
			}
191
		});
192
 
1471 aurelien 193
		BusEvenementiel.getInstance().addHandler(EvenementChangementEtatUtilisateur.TYPE, new GestionnaireEvenementChangementEtatUtilisateur() {
423 gduche 194
			@Override
1471 aurelien 195
			public void onModificationEtatUtilisateur(EvenementChangementEtatUtilisateur evenementChangementEtatUtilisateur) {
196
				rafraichirVue();
423 gduche 197
			}
198
		});
199
	}
2080 aurelien 200
 
201
	public boolean utilisateurPeutVoter() {
202
		return !protocole.doitEtreIdentifiePourVoter() || CacheClient.getInstance().getUtilisateur().estIdentifie();
203
	}
939 benjamin 204
 
629 aurelien 205
	public void setValeurVoteUtilisateur(int valeurVoteUtilisateur) {
206
		this.valeurVoteUtilisateur = valeurVoteUtilisateur;
207
	}
939 benjamin 208
 
423 gduche 209
	public void enregistrerVote() {
1471 aurelien 210
		vue.desactiverInteractionVote();
939 benjamin 211
		final VoteProtocole voteProtocole = new VoteProtocole();
423 gduche 212
		voteProtocole.setProtocole(this.protocole);
629 aurelien 213
		voteProtocole.setVote(valeurVoteUtilisateur);
1095 gduche 214
		String idContributeur = CacheClient.getInstance().getUtilisateur()
215
				.getId();
823 aurelien 216
		voteProtocole.setContributeur(idContributeur);
1471 aurelien 217
 
218
		//TODO: ceci devrait pouvoir être factorisé
1095 gduche 219
		if (image.utilisateurAVotePourProtocole(this.protocole.getId() + "",
220
				idContributeur)) {
1471 aurelien 221
			voteProtocole.setId(image.getVotesProtocoles(this.protocole.getId()+"").get(idContributeur).getId());
222
			VoteProtocoleCallback vpc = new VoteProtocoleCallback() {
223
				@Override
224
				public void surRetour(Void objetRetour) {
225
					image.ajouterVoteProtocole(voteProtocole);
226
					rafraichirVue();
227
					vue.afficherVoteModifie();
228
					vue.activerInteractionVote();
229
				}
230
			};
1095 gduche 231
			voteProtocoleService.modifierVote(image.getIdImage(),
232
					voteProtocole, vpc);
823 aurelien 233
		} else {
1471 aurelien 234
			AjoutVoteProtocoleCallback vpc = new AjoutVoteProtocoleCallback() {
235
				@Override
236
				public void surRetour(String idVote) {
237
					voteProtocole.setId(idVote);
238
					image.ajouterVoteProtocole(voteProtocole);
239
					rafraichirVue();
240
					vue.afficherVotePrisEnCompte();
241
					vue.activerInteractionVote();
242
				}
243
			};
1095 gduche 244
			voteProtocoleService.ajouterVote(image.getIdImage(), voteProtocole,
245
					vpc);
823 aurelien 246
		}
629 aurelien 247
	}
1471 aurelien 248
 
249
	public void supprimerVote() {
250
		vue.desactiverInteractionVote();
251
		final String idContributeur = CacheClient.getInstance().getUtilisateur()
252
				.getId();
253
		final VoteProtocole voteProtocole = image.getVotesProtocoles(protocole.getId()).get(idContributeur);
254
		VoteProtocoleCallback vpc = new VoteProtocoleCallback() {
255
			@Override
256
			public void surRetour(Void objetRetour) {
257
				// TODO: voir si l'on affiche un message en cas de succès ?
258
				image.supprimerVoteProtocole(protocole.getId() + "", idContributeur);
259
				rafraichirVue();
260
				vue.afficherVoteSupprime();
261
				vue.activerInteractionVote();
262
			}
939 benjamin 263
 
1471 aurelien 264
		};
265
		voteProtocoleService.supprimerVote(image.getIdImage(), voteProtocole, vpc);
266
	}
267
 
629 aurelien 268
	public int getValeurVoteTotal() {
269
		return valeurVoteTotal;
270
	}
271
 
272
	public IsWidget getVue() {
273
		return vue;
274
	}
939 benjamin 275
 
629 aurelien 276
	private void rafraichirVue() {
1266 aurelien 277
		valeurVoteTotal = calculerMoyenneVotesArrondie();
1583 mathias 278
		moyenneArithmetique = calculerMoyenneVotes();
279
		mediane = calculerMedianeVotes();
1566 mathias 280
		valeurVoteTotalPrecise = calculerMoyennePondereeVotes();
281
		nombrePoints = calculerNombrePointsEchelleArbitraire();
1095 gduche 282
		VoteProtocole voteProtocole = image.getVotesProtocoles(
283
				protocole.getId()).get(
284
				CacheClient.getInstance().getUtilisateur().getId());
1088 gduche 285
		int voteUtilisateur = 0;
286
		if (voteProtocole != null) {
287
			voteUtilisateur = voteProtocole.getVote();
1095 gduche 288
			vue.masquerZoneVoter();
1088 gduche 289
		}
1471 aurelien 290
 
291
		if(image.utilisateurAVotePourProtocole(protocole.getId()+"", CacheClient.getInstance().getUtilisateur().getId())) {
292
			vue.afficherBoutonAnnuler();
293
		}
2080 aurelien 294
 
295
		vue.afficherMessageVoteIdentifie(utilisateurPeutVoter());
1095 gduche 296
 
297
		VoteFleurPresenteur presenteurFleur = new VoteFleurPresenteur(
298
				new VoteFleurVue());
1085 gduche 299
		presenteurFleur.setNote(valeurVoteTotal);
1088 gduche 300
		vue.setNoteGenerale(valeurVoteTotal);
1266 aurelien 301
		vue.setNoteGeneraleToolTip(valeurVoteTotalPrecise);
1085 gduche 302
		presenteurFleur.go(vue.getZoneFleur());
1583 mathias 303
		vue.rafraichir(voteUtilisateur, image.getVotesProtocoles(protocole.getId()).size(), nombrePoints,
304
					   moyenneArithmetique, mediane, occurrencesParNote, valeurVoteTotalPrecise);
629 aurelien 305
	}
1566 mathias 306
 
1583 mathias 307
	public double calculerMedianeVotes() {
308
		double med = 0;
309
		// comparateur de votes (le bulldozer Java™ pour écraser une mouche)
310
		class Comparatisateur3000 implements Comparator<VoteProtocole> {
311
			@Override
312
			public int compare(VoteProtocole v1, VoteProtocole v2) {
313
				if (v1.getVote() > v2.getVote()) {
314
					return 1;
315
				} else if (v1.getVote() > v2.getVote()) {
316
					return -1;
317
				} else {
318
					return 0;
319
				}
320
			}
321
		}
322
		// conversion en liste triable
323
		List<VoteProtocole> liste = new ArrayList<VoteProtocole>(image.getVotesProtocoles(protocole.getId()).values());
324
		Collections.sort(liste, new Comparatisateur3000());
325
		int longueur = liste.size();
326
		if (longueur > 0) {
327
			if (longueur % 2 == 0) {
328
				// moyenne des éléments centraux
329
				med = (liste.get(longueur / 2 - 1).getVote() + liste.get(longueur / 2).getVote()) / 2;
330
			} else {
331
				// élément central
332
				med = liste.get((int) (longueur / 2)).getVote();
333
			}
334
		}
335
		return med;
336
	}
337
 
338
	// calcule la moyenne arithmétique
339
	public double calculerMoyenneVotes() {
340
		double valeurVote = 0;
341
		double nbVote = 0;
342
		for (Iterator<String> iterator = image
343
				.getVotesProtocoles(protocole.getId()).keySet().iterator(); iterator
344
				.hasNext();) {
345
			VoteProtocole imageCelValidationData = image.getVotesProtocoles(
346
					protocole.getId()).get(iterator.next());
347
			valeurVote += (double) imageCelValidationData.getVote() / 5;
348
			nbVote++;
349
		}
350
 
351
		if (nbVote > 0) {
352
			valeurVote /= nbVote;
353
			valeurVote *= 5;
354
		}
355
 
356
		return valeurVote;
357
	}
358
 
1566 mathias 359
	// Calcule une moyenne, où chaque note est pondérée par son nombre d'occurrences au carré.
360
	// voir http://www.tela-botanica.org/wikini/DevInformatiques/wakka.php?wiki=AppliDelCalculVotes
361
	public double calculerMoyennePondereeVotes() {
362
 
363
		double score = 0;
364
		double diviseur = 0;
365
		int nbOccurrences;
1583 mathias 366
		// mise à jour des occurrences par note, utile pour le panneau de détails
367
		occurrencesParNote = new HashMap<Integer,Integer>();
1566 mathias 368
 
369
		// rangement par note => occurrences
370
		for (String clef : image.getVotesProtocoles(protocole.getId()).keySet()) {
371
			VoteProtocole imageCelValidationData = image.getVotesProtocoles(protocole.getId()).get(clef);
372
			nbOccurrences = 1;
373
			if (occurrencesParNote.containsKey(imageCelValidationData.getVote())) {
374
				nbOccurrences = occurrencesParNote.get(imageCelValidationData.getVote()) + 1;
375
			}
376
			occurrencesParNote.put(imageCelValidationData.getVote(), nbOccurrences);
629 aurelien 377
		}
939 benjamin 378
 
1566 mathias 379
		// calcul pondéré
380
		for (Integer clef : occurrencesParNote.keySet()) {
381
			score += clef * occurrencesParNote.get(clef) * occurrencesParNote.get(clef);
382
			diviseur += occurrencesParNote.get(clef) * occurrencesParNote.get(clef);
629 aurelien 383
		}
384
 
1566 mathias 385
		if (diviseur > 0) {
386
			score /= diviseur;
387
		}
388
 
389
		return score;
1266 aurelien 390
	}
391
 
1566 mathias 392
	// remplace chaque note par un nombre de points noté dans "echelle" afin de favoriser
393
	// les note fortes (5 et 4), pour le défi photo notamment
394
	public int calculerNombrePointsEchelleArbitraire() {
395
		int points = 0;
1583 mathias 396
		//int[] echelle = {-1,0,1,4,20};
397
		int[] echelle = {1,10,100,1000,10000};
1566 mathias 398
 
399
		for (String clef : image.getVotesProtocoles(protocole.getId()).keySet()) {
400
			VoteProtocole imageCelValidationData = image.getVotesProtocoles(protocole.getId()).get(clef);
2000 mathias 401
			if (imageCelValidationData.getVote() > 0) {
402
				points += echelle[imageCelValidationData.getVote() - 1];
403
			}
1566 mathias 404
		}
405
 
406
		return points;
407
	}
408
 
1266 aurelien 409
	public int calculerMoyenneVotesArrondie() {
1566 mathias 410
		//double valeurVote = calculerMoyenneVotes();
411
		double valeurVote = calculerMoyennePondereeVotes();
939 benjamin 412
		return (int) Math.round(valeurVote);
423 gduche 413
	}
9 benjamin 414
}