/*
	CRIR - Checkbox & Radio Input Replacement
	Author: Chris Erwin (me[at]chriserwin.com)
	www.chriserwin.com/scripts/crir/

	Updated July 27, 2006.
	Jesse Gavin added the AddEvent function to initialize
	the script. He also converted the script to JSON format.
	
	Updated July 30, 2006.
	Added the ability to tab to elements and use the spacebar
	to check the input element. This bit of functionality was
	based on a tip from Adam Burmister.
	
	Actualizado 27 de Agosto, 2008 (francis)
	Añadida la funcionalidad para que este script haga funcionar al formulario
	indicado como una barra de votacion.

' ------------------
' - FUNCIONAMIENTO -
' ------------------
' Para que el formulario se muestre usando CSS interactivo, es necesario cargar el script
' localizado en el fichero jsVotos.js y el fichero CSS starRating.css.
' Sin el script cargado o con CSS/Javascript desactivado, la barra de votación funcionará
' como un campo radio normal, sin ver reducida su funcionalidad.
' Si se carga el script almacenado en jsVotos.js, entonces el script hace lo siguiente:
' 0. El CSS esconde los radios y deja solo los labels.
' 1. El script busca todos los elementos label y sus correspondientes elementos 
'    input type radio asociados.
' 2. Para cada elemento encontrado se comprueba si pertenece a una barra de 
'    votación (clase crirHiddenJS)
' 3. Se inicializa cada elemento que cumple la condición anterior a estrella vacía.
' 4. También se añade a los elementos anteriores un evento para que se ejecute 
'    una función onclick para poder cambiar su estado.
' 5. Se busca el elemento checked entre los anteriores y se pone una estrella 
'    encendida, también a los elementos que van por detrás de él y que tienen el 
'    mismo valor en 'name'.
' 6. Cada vez que se hace click sobre un elemento, se apagan y encienden las 
'    estrellas correspondientes entre los elementos input type radio con el 
'    mismo valor en 'name'.
' 
' Estrella encendida -> label clase radio_checked.
' Estrella apagada -> label clase radio_unchecked.

*/

var elementCheckedId, elementCheckedForm;

crir = {	
	
	init: function() {	
		divNoJS = document.getElementById('votosNoJS');	
		divNoJS.className = 'votosJS';
	
		arrLabels = document.getElementsByTagName('label');	
			
		searchLabels:
		for (var i=0; i<arrLabels.length; i++) {			
			// get the input element based on the for attribute of the label tag
			if (arrLabels[i].getAttributeNode('for') && arrLabels[i].getAttributeNode('for').value != '') {
				labelElementFor = arrLabels[i].getAttributeNode('for').value;				
				inputElement = document.getElementById(labelElementFor);							
			}
			else {				
				continue searchLabels;
			}	
							
			inputElementClass = inputElement.className;				
		
			// if the input is specified to be hidden intiate it
			if (inputElementClass == 'crirHiddenJS') {
				//arrLabels[i].addEventListener('mouseover', crir.toggleRadioLabel, false);
				
				inputElement.className = 'crirHidden';				
				
				inputElementType = inputElement.getAttributeNode('type').value;	
				
				// add the appropriate event listener to the input element
				if (inputElementType == "radio") {
					inputElement.onclick = crir.toggleRadioLabel;
				}
				
				// set the initial label state and add event listeners
				if (inputElement.checked) {
					if (inputElementType == 'radio') { 
						arrLabels[i].className = 'radio_checked' 						
						elementCheckedId = inputElement.id;
						elementCheckedForm = inputElement.form.getAttributeNode('id').value;
						crir.toggleAnteriores(elementCheckedForm, elementCheckedId);
					}																	
				}
				else {
					if (inputElementType == 'radio') { arrLabels[i].className = 'radio_unchecked' }
				}											
			}
			else if (inputElement.nodeName != 'SELECT' && inputElement.getAttributeNode('type').value == 'radio') { // this so even if a radio is not hidden but belongs to a group of hidden radios it will still work.
				arrLabels[i].onclick = crir.toggleRadioLabel;
				arrLabels[i].getAttributeNode('for').value;
				inputElement.onclick = crir.toggleRadioLabel;
			}
		}	
	},	
	
	// Apaga todas las estrellas.
	disableAll: function(targetForm) {
		arrLabels = document.getElementsByTagName('label');	
	
		searchLabels:
		for (var i=0; i<arrLabels.length; i++) {			
			// get the input element based on the for attribute of the label tag
			if (arrLabels[i].getAttributeNode('for') && arrLabels[i].getAttributeNode('for').value != '') {
				labelElementFor = arrLabels[i].getAttributeNode('for').value;				
				inputElement = document.getElementById(labelElementFor);
			}
			else {				
				continue searchLabels;
			}	

			inputElementClassName = inputElement.className;
			inputElementForm = inputElement.form.getAttributeNode('id').value;
		
			// Si el elemento es del mismo grupo de radio lo desactivamos
			if (inputElementForm == targetForm && inputElementClassName == 'crirHidden') {
				arrLabels[i].className = 'radio_unchecked';
			}
		}			
	},
	
	// Enciende la estrella indicada para el formulario indicada y todas las anteriores del mismo formulario.
	toggleAnteriores: function (targetForm, elementCheckedID) {
		arrLabels = document.getElementsByTagName('label');	
	
		searchLabels:
		for (var i=0; i<arrLabels.length; i++) {			
			// get the input element based on the for attribute of the label tag
			if (arrLabels[i].getAttributeNode('for') && arrLabels[i].getAttributeNode('for').value != '') {
				labelElementFor = arrLabels[i].getAttributeNode('for').value;				
				inputElement = document.getElementById(labelElementFor);
			}
			else {				
				continue searchLabels;
			}	

			inputElementClassName = inputElement.className;
			inputElementForm = inputElement.form.getAttributeNode('id').value;
		
			// Si el elemento es del mismo grupo de radio y anterior
			// al activo, también lo mostramos como activo.
			if (inputElementForm == targetForm && inputElementClassName == 'crirHidden') {
				if (arrLabels[i].getAttributeNode('for').value <= elementCheckedID) {
					arrLabels[i].className = 'radio_checked';
				}
			}
		}		
	},	
		
	// Busca la 'label' asociada al radio buttom.
	findLabel: function (inputElementID) {
		arrLabels = document.getElementsByTagName('label');
	
		searchLoop:
		for (var i=0; i<arrLabels.length; i++) {
			if (arrLabels[i].getAttributeNode('for') && arrLabels[i].getAttributeNode('for').value == inputElementID) {				
				return arrLabels[i];
				break searchLoop;				
			}
		}		
	},	
	
	// Cambia el estado de un formulario o pinta el supuesto estado del formulario según se le llama (haciendo click o con mouseover).
	toggleRadioLabel: function (id) {	
		
		// Esto es para detectar cómo nos llaman, si con click o poniendo el mouse encima.
		clickedLabelElement = crir.findLabel(id);
		clickedInputElement = document.getElementById(id);
		
		// Llamada a este evento haciendo click: Cambiamos el valor del formulario de acorde a la estrella pulsada.
		if( clickedInputElement == null ){
			clickedLabelElement = crir.findLabel(this.getAttributeNode('id').value);
		
			clickedInputElement = this;
			clickedInputElementId = clickedInputElement.getAttributeNode('id').value;
			clickedInputElementForm = clickedInputElement.form.getAttributeNode('id').value;								

			elementCheckedId = clickedInputElementId;
			elementCheckedForm = clickedInputElementForm;
			clickedInputElement.checked = true;
			
			arrInputs = document.getElementsByTagName('input');
	
			// uncheck (label class) all radios in the same group
			for (var i=0; i<arrInputs.length; i++) {			
				inputElementType = arrInputs[i].getAttributeNode('type').value;
				if (inputElementType == 'radio') {
					if( arrInputs[i].form.getAttributeNode('id') != null ) {
						inputElementForm = arrInputs[i].form.getAttributeNode('id').value;
					}
					if( arrInputs[i].getAttributeNode('id') != null ) {						
						inputElementId = arrInputs[i].getAttributeNode('id').value;
					}
					inputElementClass = arrInputs[i].className;
					// find radio buttons with the same parent form as the one we've changed and have a class of chkHidden
					// and then set them to unchecked
					if (inputElementForm == clickedInputElementForm && inputElementClass == 'crirHidden') {				
						inputElementID = arrInputs[i].getAttributeNode('id').value;
						labelElement = crir.findLabel(inputElementID);
						labelElement.className = 'radio_unchecked';
					}
				}
			}			
	
			// if the radio clicked is hidden set the label to checked
			if (clickedInputElement.className == 'crirHidden') {
				clickedLabelElement.className = 'radio_checked';
				crir.toggleAnteriores(clickedInputElementForm, clickedInputElementId);	
			}
			
		// Llamada con evento mouseover (no cambiamos el valor del formulario), solo dibujamos como si hicieramos click. Al salir 
		// se llama a la función mouseFuera() que restaura el estado de la barra.
		} else {
			clickedLabelElement = crir.findLabel(id);
			
			clickedInputElement = document.getElementById(id);
			clickedInputElementId = clickedInputElement.getAttributeNode('id').value;
			clickedInputElementForm = clickedInputElement.form.getAttributeNode('id').value;				
			
			crir.disableAll(clickedInputElementForm);
			crir.toggleAnteriores(clickedInputElementForm, clickedInputElementId);	
		}		
	},
	
	addEvent: function(element, eventType, doFunction, useCapture){
		if (element.addEventListener) 
		{
			element.addEventListener(eventType, doFunction, useCapture);
			return true;
		} else if (element.attachEvent) {
			var r = element.attachEvent('on' + eventType, doFunction);
			return r;
		} else {
			element['on' + eventType] = doFunction;
		}
	},
	
	// -------------------------------------------------------------------
	// Cuando sacamos el ratón de la barra, la pintamos según el voto que haya fijado.

	mouseFuera: function(e) {
		// Dibujamos la barra de votos según el voto válido (último pulsado o el del resultado si no se ha clikeado en ningún lado).
		crir.disableAll(clickedInputElementForm);
		crir.toggleAnteriores(elementCheckedForm, elementCheckedId);
	}
}

crir.addEvent(window, 'load', crir.init, false);

// -------------------------------------------------------------------
// AJAX
// Funcion para procesar un voto y actualizar el DIV correspondiente.
// -------------------------------------------------------------------
function procVotoAjax(localizador, idPag, idPagOfuscado) {

	// Ponemos el iconito de carga
	barraVotacion = localizador + idPag;	  
	  
	$(barraVotacion + 'BotonEnviarVoto').hide();
	$(barraVotacion + 'DivCargando').show();   	  
	
	// Y llamamos a la función que procesa el voto y muestra el resultado.
	updateDivVotos(localizador, idPag, idPagOfuscado)
}

// -------------------------------------------------------------------
// AJAX
// Funcion que le envía el voto a la página de proceso y muestra el resultado.
// -------------------------------------------------------------------
function updateDivVotos(localizador, idPag, idPagOfuscado) {

	// Obtenemos el valor del voto.
	voto = getCheckedValue(document.getElementById(localizador+idPag));

	// Actualizamos el DIV.
	new Ajax.Updater(
		barraVotacion, 
		'/procVotoAjax.asp', 
		{ 					    
			method: 'post',
			parameters:'campoLocalizador='+localizador+'&valorLocalizador='+idPagOfuscado+'&voto='+voto
		}		
	)
}

// -------------------------------------------------------------------
// AJAX
// Funcion auxiliar para obtener el valor del voto consultando el formulario.
// -------------------------------------------------------------------
function getCheckedValue(radioObj) {
	if(!radioObj)
		return "";
	var radioLength = radioObj.length;
	if(radioLength == undefined)
		if(radioObj.checked)
			return radioObj.value;
		else
			return "";
	for(var i = 0; i < radioLength; i++) {
		if(radioObj[i].checked) {
			return radioObj[i].value;
		}
	}
	return "";
}

