/*
Système de tags/labels en Javascript
Copyright Jérémy Fache Juillet 2008
*/

/* Arrays */
var myTags = [];
var tagsArray = [];
var tagsToAdd = [];
var tagsToDel = [];

var tags = {

	init: function() {
		$('.article').each(function() {
			if($(this).attr("id") != "") {
				var artId = $(this).attr("id").split("-");
				tags.updateCloud(artId[1]);
			}
		});
		
		/* Filtres tagcloud */
		tags.countVisible();	
		$("select.tagcloudfilter").change(function() {
			
			var filter = $(".tagcloudfilter").val().split("-");
			
			if(filter[0] == "over") {
				$(".tagcloud li").show();
				for(i = filter[1]; i >= 0; i--) {
					$(".tagcloud li.occurence-" + i).hide();
				}
			}
			else if(filter[0] == "equal") {
				$(".tagcloud li").hide();
				$(".tagcloud li.occurence-" + filter[1]).show();
			}
			tags.countVisible();
		});
		
		if(userID == 0) {
			$('a[href=#add_tags]').requires_login();
		}
		
	},
	
	countVisible: function() {
		$(".tags-showed").html("(" + $(".tagcloud li:visible").length + ")");
	},

	clean: function(artId) {
		/* Retire les tags dans l'occurence est < 1 */
		tagsArray[artId] = $.grep(tagsArray[artId], function(n, i) {
			return tagsArray[artId][i][1] < 1 ? 0 : 1;
		});
	},

	getNames: function(artId) {
		var tagsName = [];
		$.each(tagsArray[artId], function(i) {
			tagsName[i] = tagsArray[artId][i][0];
		});
		return tagsName;
	},
	
	getPopular: function(artId) {
		/* Tri par occurence */
		tagsArray[artId].sort(sortNumber);
		var popularTags = tagsArray[artId].slice(0, 7);
		/* Tri alphabétique */
		popularTags.sort(sortNatural);
		tagsArray[artId].sort(sortNatural);
		return popularTags;
	},
	
	approve: function (artId, tagIndex) {
		/* +1 en occurence, ajout à mes tags et dans les tags à sauvegarder */
		tagsArray[artId][tagIndex][1]++;
		myTags[artId].push(tagsArray[artId][tagIndex][0]);
		tagsToAdd[tagIndex] = tagsArray[artId][tagIndex][0];
		
		/* Update */
		tags.updateCloud(artId);
		tags.save(artId);
	},
	
	remove: function (artId, tagIndex) {
		/* On cherche l'index dans mytags puis on supprime de l'array */
		myTagsIndex = $.inArray(tagsArray[artId][tagIndex][0], myTags[artId]);
		myTags[artId].splice(myTagsIndex, 1);
		
		/* -1 en occurence, ajout dans les tags à supprimer */
		tagsArray[artId][tagIndex][1]--;
		tagsToDel[tagIndex] = tagsArray[artId][tagIndex][0];
		
		/* Update */
		tags.clean(artId);
		tags.updateCloud(artId);
		tags.save(artId);
	},
	
	save: function(artId) {
		$.ajax({
			data: {
				action: "tags_save",
				art_id: artId,
				tags_add: $.toJSON(tagsToAdd),
				tags_del: $.toJSON(tagsToDel)
			},
			beforeSend: function() {
				$('#article-' + artId + ' .article-tags-status').html('<img src="img/shao197/dot.gif" width="3" height="3" alt="Sauvegarde" />');
			},
			success: function() {
				/* Reset des tags à sauvegarder */
				tagsToAdd.length = 0;
				tagsToDel.length = 0;
				$('#article-' + artId + ' .article-tags-status').empty();
			}
		});
	},
	
	update: function(artId) {
		/* Récupération de la valeur du champ Mes Tags et Suppression des doublons et des tags dont la longueur est < à 3 caractères */
		var myNewTags = $('#article-' + artId + ' .article-mytags').val().split(/,/);
		/* Suppression des espaces avant/après */
		$.each(myNewTags, function(i) {
			myNewTags[i] = $.trim(myNewTags[i]);
		});
		
		var hash = new Object();
		var tempList = [];
		$.each(myNewTags, function(i) {
			if (hash[myNewTags[i].toLowerCase()] != 1 && myNewTags[i].length > 2 && myNewTags[i].length <= 120) {
				tempList = tempList.concat(myNewTags[i]);
				hash[myNewTags[i].toLowerCase()] = 1
			}
		});
		myNewTags = tempList;
		
		/* Récup des index et noms des tags */
		var tagsName = tags.getNames(artId);
		
		/* Parcours de mes nouveaux tags */
		$.each(myNewTags, function(i) {
			var tagsIndex = $.inArray(myNewTags[i], tagsName);
			
			/* Mon nouveau tag est-il dans la liste générale ? */
			if(tagsIndex != -1) { /* Oui, on vérifie maintenant s'il est déjà dans mes tags */
				var isInMyTags = $.inArray(myNewTags[i], myTags[artId]);
				
				/* Mon nouveau tag appartient-il déjà à mes tags ? */
				if(isInMyTags == -1) { /* Non, donc +1 sur l'occurence */
					tagsArray[artId][tagsIndex][1]++;
					tagsToAdd[i] = myNewTags[i];
				}
			} else { /* Non, donc on l'ajoute aux tags */
				tagsArray[artId].push([myNewTags[i], 1]);
				tagsToAdd[i] = myNewTags[i];
			}
		});
		
		/* Parcours de mes anciens tags à la recherche des tags qui ne sont plus utilisés */
		$.each(myTags[artId], function(i) {
			var isStillPresent = $.inArray(myTags[artId][i], myNewTags);
			
			/* Mon ancien tag est-il toujours dans mes tags ? */
			if(isStillPresent == -1) { /* Non, on le supprime */
				var tagsIndex = $.inArray(myTags[artId][i], tagsName);
				tagsArray[artId][tagsIndex][1]--;
				tagsToDel[i] = tagsArray[artId][tagsIndex][0];
			}
		});
		
		/* MAJ de mes tags */
		myTags[artId] = [].concat(myNewTags);
		
		/* Update */	
		tags.clean(artId);
		tags.updateCloud(artId, "all");
		tags.save(artId);
	},
	
	updateCloud: function(artId) {
		/* Tri alphabétique */
		tagsArray[artId].sort(sortNatural);
		
		/* MAJ du champ texte */
		$('#article-' + artId + ' .article-mytags').val(myTags[artId].join(", "));
		
		var tagsOccur = [];
		$.each(tagsArray[artId], function(i) {
			tagsOccur[i] = tagsArray[artId][i][1];
		});
		
		var fSizeMin = 100, fSizeMax = 150, fSizeRange = fSizeMax - fSizeMin;
		var occurMin = tagsOccur.min(), occurMax = tagsOccur.max(), occurRange = occurMax - occurMin;
		occurMin < 1 ? occurMin = 1 : "";
		occurRange < 1 ? occurRange = 1 : "";
		
		var newTagCloud = "";
		
		/* Parcours des tags et mise en forme */
		$.each(tagsArray[artId], function(i) {
			if(tagsOccur[i] > 0) {
				var tagFontSize = fSizeMin + (((tagsOccur[i] - occurMin) * fSizeRange) / occurRange);
				
				var split = ",";
				if(i == tagsArray[artId].length - 1) { split = ""; }
				
				var linkOccurOpen = "", linkOccurClose = "";
				
				/* Affichage des liens si user loggué */
				if(userID > 0) {
					var ownTag = $.inArray(tagsArray[artId][i][0], myTags[artId]);
					if(ownTag == -1)
						var action = "approve", aClass = "tag", aTitle = "Confirmer ce tag";
					else
						var action = "remove", aClass = "tag-used", aTitle = "Retirer de mes tags";
					
					linkOccurOpen = '<a title="' + aTitle + '" class="' + aClass + '" href="#" onclick="tags.' + action + '(' + artId + ', ' + i + ');return false;">';
					linkOccurClose = '</a>';
				}
				
				/* Regénération du nuage de tags */
				newTagCloud += '<a style="font-size:' + tagFontSize + '%;" title="Voir les articles associés" href="./tag/' + encodeURIComponent(tagsArray[artId][i][0]) + '">' + tagsArray[artId][i][0] + '</a> <span class="tag-occurence">' + linkOccurOpen + '(' + tagsArray[artId][i][1] + ')' + linkOccurClose + '</span>' + split + ' ';
			}
		});
		if(tagsArray[artId].length < 1)
			newTagCloud = "Pas de tags associés";
			
		/* Update tag cloud */
		$('#article-' + artId + ' .article-tags-list').html(newTagCloud);
	},
	
	togglePanel: function(artId) {
		$('#article-' + artId + ' .article-tagpanel').toggle();
	},
	
	toggleInfos: function(artId) {
		$('#article-' + artId + ' .article-taggers').toggle();
		if($('#article-' + artId + ' .article-taggers-list').html() == "") {
			$.ajax({
				data: {
					action: 'tags_get_taggers',
					art_id: artId
				},
				beforeSend: function() {
					$('#article-' + artId + ' .article-taggers-list').html('Chargement...');
				},
				success: function(response) {
					$('#article-' + artId + ' .article-taggers-list').html(response);
				}
			});
		}
	},
	
	addToList: function(element) {
		var element = $(element);
		var artId = element.parents(".article").attr("id").split("-");
		var tagsList = $('#article-' + artId[1] + ' .article-mytags');
		tagsList.val(tagsList.val() + (tagsList.val() != "" ? ", " : "") + element.html())
	}
};



function sortNumber(a,b) {
	return b[1] - a[1];
}

/* Sort alphabétique */
function sortNatural(a, b){
	var a2 = a[0].toLowerCase();
	var b2 = b[0].toLowerCase();
	if(a2 == b2)
		return 0;
	return a2 < b2 ? -1 : 1;
}


Array.prototype.min = function() {
	var Min = this[0];
	for (var i=0; i<this.length; i++) if (this[i]*1<Min) Min = this[i];
	return Min;
}

Array.prototype.max = function() {
	var Max = this[0];
	for (var i=0; i<this.length; i++) if (this[i]*1>Max) Max = this[i];
	return Max;
}
