/**
 * @package bibliotheque
 * @subpackage benchmark
 * @filesource
 */

/**
 * objet js permettant de générer des zone de saisie ou d'affichage de score
 * configurable, degradable, multi-instances, etc
 * 
 * @attention : l'interface suivante est utilisable en cas de nécessité d'implémentation html seulement,
 * il est tout de fois recommandé d'utiliser l'ObjScore.php pour l'implémenter tant que celà est possible.
 *
 * @note son utilisation est simple, il suffit de définir un input de type radio possédant un tag score sur chaque item 
 * puis d'initialiser l'objet sur le dom ou partie, il va alors automatiquement remplacer l'input radio par un input hidden
 * contenant la valeur choisie dans l'affichage qu'il va égallement générer
 * celui-ci est configurable par le biais du premier radio saisi par exemple :
 *
 * 		<input type="radio" id="f_test" name="f_test" score='déconseillé'	value='0' readonly='false' classOn='scoreEtoileOn' classOff='scoreEtoileOff' classHover='scoreEtoileHover' classDiv = 'scoreEtoileDiv' descriptionDefaut = 'Attribuer un score'>
 * 		<input type="radio" id="f_test" name="f_test" score='bof'		value='1'>
 * 		<input type="radio" id="f_test" name="f_test" score='moyen'		value='2'>
 * 		<input type="radio" id="f_test" name="f_test" score='bien'		value='3' checked>
 * 		<input type="radio" id="f_test" name="f_test" score='super'		value='4'>
 * 		<br><br><br> ou 
 * 		<input type="radio" id="f_test3" name="f_test3" score='déconseillé'	value='0' readonly='false' classOn='barreOn' classOff='barreOff' classHover='barreHover' classDiv ='barreDiv' descriptionDefaut = 'Attribuer un score'>
 * 		<input type="radio" id="f_test3" name="f_test3" score='bof'			value='1'>                                                                                              
 * 		<input type="radio" id="f_test3" name="f_test3" score='moyen'		value='2'>                                                                                              
 * 		<input type="radio" id="f_test3" name="f_test3" score='bien'		value='3'>                                                                                              
 * 		<input type="radio" id="f_test3" name="f_test3" score='super'		value='4'>                                                                                              
 * 		<input type="radio" id="f_test3" name="f_test3" score='extra'		value='5'>                                                                                              
 * 		<input type="radio" id="f_test3" name="f_test3" score='incroyable'	value='6'>                                                                                              
 *		<input type="radio" id="f_test3" name="f_test3" score='incroyable'	value='7'>                                                                                              
 *		<input type="radio" id="f_test3" name="f_test3" score='incroyable'	value='8'>                                                                                              
 *
 * @attention les tags ainsi saisis sont tous optionnels sauf les tags score, value, name et id
 *
 * il faut également qu'un css soit présent avec par exemple :
 *		div.scoreDescription {float:right;font-size:small;}
 *
 *		div.scoreEtoileDiv { width : 190px; height : 16px; cursor:pointer;}
 *		div.scoreEtoileOn	{background:transparent url(http://damien.benoit.copainsdavant.dev.lan35.linternaute.com/image/quoideneuf/score_on.png) no-repeat scroll 0 0px; width : 16px; height : 16px; float:left;}
 *		div.scoreEtoileOff {background:transparent url(http://damien.benoit.copainsdavant.dev.lan35.linternaute.com/image/quoideneuf/score_off.png) no-repeat scroll 0 0px; width : 16px; height : 16px; float:left;}
 *		div.scoreEtoileHover {background:transparent url(http://damien.benoit.copainsdavant.dev.lan35.linternaute.com/image/quoideneuf/score_actif.png) no-repeat scroll 0 0px; width : 16px; height : 16px; float:left;}
 *
 *		div.barreDiv { background-color : lightGrey; width : 150px; height : 15px;cursor:pointer; }
 *		div.barreOn	{background-color : green; width : 15px; height : 15px; float:left;}
 *		div.barreOff {background-color : blue; width : 15px; height : 15px; float:left;}
 *		div.barreHover {background-color : red; width : 15px; height : 15px; float:left;}
 * 
 * 
 * @note En cas d'import ajax dans le dom on réactualise avec la méthode suivante :
 * if(typeof(benchmark.execution.objScore) == 'object')	{ benchmark.execution.objScore.initialise(); }
 * ou bien :
 * if(typeof(benchmark.execution.objScore) == 'object')	{ benchmark.execution.objScore.initialise('#selecteur'); } 						
 *
 * @require benchmark.framework.ihm.effet.ObjEffet
 * @author Damien BENOIT <benoit@benchmark.fr>
 * @package bibliotheque
 * @subpackage html_include
 * @version 1.00
 * @see objScore.php 
 * @since 20/04/2009 Damien BENOIT <benoit@benchmark.fr> création
 */

if(typeof(benchmark) == "undefined") { var benchmark = new Object(); }
if(typeof(benchmark.framework) == "undefined") { benchmark.framework = new Object(); }
if(typeof(benchmark.framework.ihm) == "undefined") { benchmark.framework.ihm = new Object(); }
if(typeof(benchmark.framework.ihm.form) == "undefined") { benchmark.framework.ihm.form = new Object(); }

/**
* objet conteneur de données pour un type de score, contenant donc ici les valeurs par défaut :
* @since 20/04/2009 Damien BENOIT <benoit@benchmark.fr> création
*/
benchmark.framework.ihm.form.ObjItemScore = function()
{
	this.classOn 		= 'scoreEtoileOn';
	this.classOff 		= 'scoreEtoileOff';
	this.classHover 		= 'scoreEtoileHover';
	this.classDiv 		= 'scoreEtoileDiv';
	this.classDescription	= 'scoreDescription';
	this.notes			= {};
	this.readonly		= false;
	this.nullPermis		= false;
	this.valeur			= null;
	this.descriptionDefaut 	= 'Passez votre souris sur les étoiles';
	this.descriptionActuel 	= this.descriptionDefaut;
	this.actif			= false;
};

/**
* objet gérant tout les scores :
* @since 20/04/2009 Damien BENOIT <benoit@benchmark.fr> création
* 
*/
benchmark.framework.ihm.form.ObjScore = function()
{
	// stock les données relatives à chaque score 
	this.tableauItemScore = {};
	
	// le selecteur par defaut pour reconnaitre les scores :
	this.selecteurParDefaut = 'input[type=radio][score]';// de type input radio et score actif 
	
	/**
	* fonction retournant une zone de score correctement formatée
	* @param string item nom de l'item en cours 
	* @return string
	* @todo en faire un template ?
	* @since 20/04/2009 Damien BENOIT <benoit@benchmark.fr> création
	*/
	this.genereScore = function(item)
	{
		var score = 	 
					// le div 
					'<div class="'+benchmark.execution.objScore.tableauItemScore[item].classDiv+'" id="score_'+item+'" >'+
					// le hidden
					'<input type="hidden" value="'+benchmark.execution.objScore.tableauItemScore[item].valeur+'" '+
					' name="'+item+'" '+
					' id="'+item+'" >';
					
		for (var i in benchmark.execution.objScore.tableauItemScore[item].notes )
		{
			if( benchmark.execution.objScore.tableauItemScore[item].notes[i].valeur > benchmark.execution.objScore.tableauItemScore[item].valeur )
			{
				score += '<div class="score '+benchmark.execution.objScore.tableauItemScore[item].classOff+'" value="'+benchmark.execution.objScore.tableauItemScore[item].notes[i].valeur+'">&nbsp;</div>';
			}
			else
			{
				score += '<div class="score '+benchmark.execution.objScore.tableauItemScore[item].classOn+'" value="'+benchmark.execution.objScore.tableauItemScore[item].notes[i].valeur+'">&nbsp;</div>';
			}
		}
		// on ajoute le champs de description par defaut si on est pas en readonly :
		if(!benchmark.execution.objScore.tableauItemScore[item].readonly){
			score += '<div'+ 
				' id = "score_description_'+item+'" '+ 
				' name = "score_description_'+item+'" '+ 
				' class="'+benchmark.execution.objScore.tableauItemScore[item].classDescription+'">'+
				benchmark.execution.objScore.tableauItemScore[item].descriptionActuel+'</div>';
		}
		// on ferme
		score += '&nbsp;</div>';

		return score;
	};
	
	
	/** 
	* redessine et remplace le score souhaité puis réinitialise les champs :
	*
	* @param string item nom de l'item en cours 
	* @since 20/04/2009 Damien BENOIT <benoit@benchmark.fr> création
	* @return void
	*/
	this.redessineScore = function(item)
	{
		$('#score_'+item)
			.replaceWith(this.genereScore(item));
		// on rajoute le comportement :
		this.bindComportement(item);
	};
	
	/** 
	* change le score souhaité :
	*
	* @param string item nom de l'item en cours 
	* @since 20/04/2009 Damien BENOIT <benoit@benchmark.fr> création
	* @return void
	*/
	this.changeScore = function(item,score)
	{
		// on renseigne l'objet de la valeur :
		this.tableauItemScore[item].valeur = score;
		$('#'+item).attr('value',score);

		// on change sa description par defaut :
		if(score != 0 && score != null && score != 'null' )
		{
			this.tableauItemScore[item].descriptionActuel = this.tableauItemScore[item].notes[score].description;
		}
		else
		{
			this.tableauItemScore[item].descriptionActuel = this.tableauItemScore[item].descriptionDefaut;
		}
		
		$('#score_'+item+' div.score')
			// on remet les classes à 0 (effet click accepté):
			.addClass(this.tableauItemScore[item].classOff)
			.removeClass(this.tableauItemScore[item].classOn+' '+this.tableauItemScore[item].classHover)
			// on parcours chaque score pour l'updater:
			.each(
				function(i)
				{
					if( 
						( score != 0 && score != null && score != 'null' ) 
						&&  benchmark.execution.objScore.tableauItemScore[item].valeur >= $(this).attr('value') 
						)
					{
						$(this)
							.removeClass(benchmark.execution.objScore.tableauItemScore[item].classOff)
							.addClass(benchmark.execution.objScore.tableauItemScore[item].classOn)
							;
					}
				}
			);
	};
	
	/**
	* bind le comportement sur la barre de score de l'item souhaité :
	* @param string item nom de l'item en cours 
	* @since 20/04/2009 Damien BENOIT <benoit@benchmark.fr> création
	* @return void
	*/
	this.bindComportement = function(item)
	{
		$('#score_'+item+' div.score')
			// quand on passe au dessus :
			.bind(
				'mouseover',
					{ 
						item	: benchmark.execution.objScore.tableauItemScore[item],
						nom	: item
					},
				function(e)
				{
					// seulement si item pas en readonly :
					if ( !e.data.item.readonly )
					{
						// on récupère le score survolé :
						var scoreSurvol = $(this).attr('value');
						// on parse chaque score possible
						$('#score_'+e.data.nom+' div.score')
							.each(
								function()
								{
									// on change le style jusqu'à l'image survolée:
									if( $(this).attr('value') <= scoreSurvol )
									{
										$(this).addClass(e.data.item.classHover);
									}
								}
							);
						// on attribue la description du score survolé :
						$('#score_description_'+e.data.nom).html(e.data.item.notes[scoreSurvol].description)
					}
				}
			)
			// qd on sort :
			.bind(
				'mouseout',
					{ 
						item	: benchmark.execution.objScore.tableauItemScore[item],
						nom	: item
					},
				function(e)
				{
					if ( !e.data.item.readonly )
					{
						$('#score_'+e.data.nom+' div.score')
							.removeClass(e.data.item.classHover);
						// on attribue la description du score en cours :
						$('#score_description_'+e.data.nom).html(e.data.item.descriptionActuel)
					}
				}
			)
			// qd on doubleclick :
			.bind(
				'dblclick',
					{ 
						item	: benchmark.execution.objScore.tableauItemScore[item],
						nom	: item
					},
				function(e)
				{
					if ( !e.data.item.readonly && e.data.item.nullPermis )
					{
						// on change la valeur à null :
						benchmark.execution.objScore.changeScore(e.data.nom,'null'); 
					}
					e.stopPropagation();
				}
			)							
			// qd on click :
			.bind(
				'click',
					{ 
						item	: benchmark.execution.objScore.tableauItemScore[item],
						nom	: item
					},
				function(e)
				{
					if ( !e.data.item.readonly )
					{
						// on change la valeur :
						benchmark.execution.objScore.changeScore(e.data.nom,$(this).attr('value')); 
					}
					
				}
			)
			.each(
				function()
				{
					// si possible on desactive la selection sur cette zone : 
					if
					( 
						typeof( benchmark.framework.ihm ) != 'undefined' &&
						typeof( benchmark.framework.ihm.effet ) != 'undefined' &&
						typeof( benchmark.framework.ihm.effet.ObjEffet ) != 'undefined' &&
						typeof( benchmark.framework.ihm.effet.ObjEffet.desactiveSelection ) == 'function' 
					)
					{
						benchmark.framework.ihm.effet.ObjEffet.desactiveSelection(this);
					}
				}
			)
			;

	};
	
	/**
	* initialise les scores sur tout ou partie du document dom 
	* @param string selecteur jQuery limitant la zone d'initialisation
	* @since 20/04/2009 Damien BENOIT <benoit@benchmark.fr> création
	* @return void
	*/
	this.initialise = function(selecteur)
	{
		// réglage du selecteur (tout ou partie) :
		if(typeof(selecteur) == 'string')
		{
			selecteur = selecteur + ' ' +this.selecteurParDefaut;
		}
		else
		{
			selecteur = this.selecteurParDefaut;
		}

		// on parcours l'arbre et stock les réglages pour chaque score :		
		$(selecteur)
			.each(
				//{}, ce modèle propre semble ne pas fonctionner dans notre version de jquery donc accès direct :/
				function(i)
				{
					// récupération de toutes les valeurs possibles :
					var nom 			= $(this).attr('name');
					var value 			= $(this).attr('value');
					var readonly		= $(this).attr('readonly');
					var nullPermis		= $(this).attr('nullPermis');
					var description 		= $(this).attr('score');
					var classOn			= $(this).attr('classOn');
					var classOff		= $(this).attr('classOff');
					var classHover		= $(this).attr('classHover');
					var classDiv		= $(this).attr('classDiv');
					var classDescription	= $(this).attr('classDescription');
					var descriptionDefaut	= $(this).attr('descriptionDefaut');
					
					// il faut un nom ! 
					if (typeof(nom) == 'undefined') { alert('erreur, il faut définir un ID au radio!');return false;}
					// si besoin on créé l'objet correspondant 
					if(typeof(benchmark.execution.objScore.tableauItemScore[nom]) == 'undefined' )
					{
						benchmark.execution.objScore.tableauItemScore[nom] = new benchmark.framework.ihm.form.ObjItemScore();
					}
					
					// on stock pour chaque item la valeur indépendante et la description :
					if ( typeof(value) == 'undefined' ) { alert('erreur, il faut définir un radio pour chaque score possible');return false;}
					else {
						benchmark.execution.objScore.tableauItemScore[nom].notes[value] = {};
						benchmark.execution.objScore.tableauItemScore[nom].notes[value].valeur = value;
					}
					// on stock pour chaque item la valeur indépendante et la description :
					if ( typeof(description)!= 'undefined') { benchmark.execution.objScore.tableauItemScore[nom].notes[value].description = description;}
					// puis les réglages globaux :
					if(typeof(readonly)		== 'boolean'&& readonly ) 			  { benchmark.execution.objScore.tableauItemScore[nom].readonly		= readonly; }
					if(typeof(nullPermis) 		== 'string' && nullPermis 		!= '' ) { benchmark.execution.objScore.tableauItemScore[nom].nullPermis		= ( nullPermis == 'true' ? true : false ); }
					if(typeof(classOn) 		== 'string' && classOn 			!= '' ) { benchmark.execution.objScore.tableauItemScore[nom].classOn		= classOn; }
					if(typeof(classOff)		== 'string' && classOff			!= '' ) { benchmark.execution.objScore.tableauItemScore[nom].classOff 		= classOff; }
					if(typeof(classHover)		== 'string' && classHover		!= '' ) { benchmark.execution.objScore.tableauItemScore[nom].classHover		= classHover; }
					if(typeof(classDiv)		== 'string' && classDiv			!= '' ) { benchmark.execution.objScore.tableauItemScore[nom].classDiv 		= classDiv; }
					if(typeof(classDescription)	== 'string' && classDescription	!= '' ) { benchmark.execution.objScore.tableauItemScore[nom].classDescription = classDescription; }
					if(typeof(descriptionDefaut)	== 'string' && descriptionDefaut	!= '' ) { benchmark.execution.objScore.tableauItemScore[nom].descriptionDefaut= descriptionDefaut; benchmark.execution.objScore.tableauItemScore[nom].descriptionActuel = descriptionDefaut; }
				}
			)
			;
		// on obtient pour chaque score la valeur et la description en cours :
		$(selecteur+':checked')
			.each(
				function(i)
				{
					var id = $(this).attr('id');
					var valeur = $(this).attr('value');
					// on stock le score :
					benchmark.execution.objScore.tableauItemScore[id].valeur = valeur;
					// on stock la description en cours : 
					benchmark.execution.objScore.tableauItemScore[id].descriptionActuel = benchmark.execution.objScore.tableauItemScore[id].notes[valeur].description;
				}
			);
		// on parcours chaque item obtenu et créé l'input hidden ainsi que le modèle de score :
		for ( var item in benchmark.execution.objScore.tableauItemScore)
		{
			// on ne génère l'item que s'il n'est pas déjà généré :
			if( $(this.selecteurParDefaut+'[name='+item+'][type=radio]').length > 0 )
			{
				benchmark.execution.objScore.tableauItemScore[item].actif = true;
				// s'il n'y a pas déjà une barre de score :
				if ( $('#score_'+item).attr('id') != 'score_'+item )
				{
					// on ajoute l'input hidden et la div :
					$('input[name='+item+']:first')
						.before(
							this.genereScore(item)
						)
					// on ajoute le comportement :
					this.bindComportement(item);
					
					// on supprime les radios :
					$(this.selecteurParDefaut+'[name='+item+']').remove();
				}
			}
			
		}
	};
	
};


/**
* @todo centraliser dans un objpage.js ? en tout cas trouver mieux que ça :
*/
$(document).ready(
	function()
	{
		/**
		* on créé si besoin le domaine d'instanciation :
		*/
		if(typeof(benchmark.execution) == "undefined") { benchmark.execution = new Object(); }
		if(typeof(benchmark.execution.objScore) == "undefined") 
		{ 
			benchmark.execution.objScore = new benchmark.framework.ihm.form.ObjScore();
		}
		benchmark.execution.objScore.initialise();
	}
);
