/************** Metodo de utilidad para enviar solicitudes asincronas **************/

/* 
 * Definicion del namespace de elementos de conexion
 */
GALILEO.namespace("util.Connect");

/*
 * Defincion del subcriptor general para los eventos de error tanto del servidor
 * como los desconocidos
 */
GALILEO.util.Connect.ErrorSubscriptor = function() {
};

/*
 * Definicion del metodo que se debe ejecutar ante un server error
 */
GALILEO.util.Connect.ErrorSubscriptor.prototype.onServerError = function(type, args, obj) {
    var dlg = new GALILEO.widget.GSimpleDialog('__dlgGeneralFailure', '25em', true);
    dlg.setIcon(GALILEO.widget.SimpleDialog.config.ERROR_ICON);
	dlg.setHeader("Error");
	dlg.setBody(GALILEO.util.Connect.config.server.response.DESCRIPTION_CODE[args[0].status]);
	dlg.show();
};

/*
 * Definicion del metodo que se debe ejecutar ante un error desconocido
 */
GALILEO.util.Connect.ErrorSubscriptor.prototype.onUnknownError = function(type, args, obj) {
    var dlg = new GALILEO.widget.GSimpleDialog('__dlgGeneralFailure', '25em', true);
    dlg.setIcon(GALILEO.widget.SimpleDialog.config.ERROR_ICON);
	dlg.setHeader("Error");
	dlg.setBody(args[0].statusText);
	dlg.show();
};

/*
 * Metodo general para la obtencion del texto asociado a un texto de error
 * @param errorCode Codigo del cual deseamos obtener el texto
 * @return true si es un codigo de error de respuesta del servidor
 */
GALILEO.util.Connect.isServerError = function(errorCode) {
	
	switch (errorCode) {
		case GALILEO.constants.server.response.COD_SERVER_DOWN:
			return true;
		case GALILEO.constants.server.response.COD_BAD_REQUEST:
			return true;
		case GALILEO.constants.server.response.COD_UNAUTHORIZED:
			return true;
		case GALILEO.constants.server.response.COD_PAYMENT_REQUIRED:
			return true;
		case GALILEO.constants.server.response.COD_FORBIDDEN:
			return true;
		case GALILEO.constants.server.response.COD_NOT_FOUND:
			return true;
		case GALILEO.constants.server.response.COD_METHOD_NOT_ALLOWED:
			return true;
		case GALILEO.constants.server.response.COD_NOT_ACCEPTABLE:
			return true;
		case GALILEO.constants.server.response.COD_PROXY_AUTH_REQUIRED:
			return true;
		case GALILEO.constants.server.response.COD_REQUEST_TIMEOUT:
			return true;
		case GALILEO.constants.server.response.COD_CONFLICT:
			return true;
		case GALILEO.constants.server.response.COD_GONE:
			return true;
		case GALILEO.constants.server.response.COD_LENGTH_REQUIRED:
			return true;
		case GALILEO.constants.server.response.COD_PRECONDITION_FAILED:
			return true;
		case GALILEO.constants.server.response.COD_REQUEST_ENTITY_TOO_LARGE:
			return true;
		case GALILEO.constants.server.response.COD_REQUEST_URI_TOO_LONG:
			return true;
		case GALILEO.constants.server.response.COD_UNSUPPORTED_MEDIA_TYPE:
			return true;
		case GALILEO.constants.server.response.COD_REQUESTED_RANGE_NOT_SATISFIABLE:
			return true;
		case GALILEO.constants.server.response.COD_EXPECTATION_FAILED:
			return true;
		case GALILEO.constants.server.response.COD_INTERNAL_ERROR_SERVER:
			return true;
		case GALILEO.constants.server.response.COD_NOT_IMPLEMENTED:
			return true;
		case GALILEO.constants.server.response.COD_BAD_GATEWAY:
			return true;
		case GALILEO.constants.server.response.COD_SERVICE_UNAVAILABLE:
			return true;
		case GALILEO.constants.server.response.COD_GATEWAY_TIMEOUT:
			return true;
		case GALILEO.constants.server.response.COD_HTTP_VERSION_NOT_SUPPORTED:
			return true;
		default:
			return false;
	}
};

/*
 * Metodo general de tratamiento del fallo en una peticion asincrona
 * @param o Objeto respuesta
 */
GALILEO.util.Connect.handlerFailure = function(o) {

	var isGlobalException = (o.status == GALILEO.util.Connect.config.server.response.COD_GLOBAL_EXCEPTION);
	var isSecurityException = (o.status == GALILEO.util.Connect.config.server.response.COD_SECURITY_EXCEPTION); 
	var isServerError = GALILEO.util.Connect.isServerError(o.status);
	
	if (isServerError) {
		GALILEO.util.Event.serverError.fire(o);
	}
	else if (isGlobalException) {
	   GALILEO.util.Event.globalException.fire();
	}
	else if (isSecurityException) {
	  GALILEO.util.Event.securityException.fire();
	}
	else {
		GALILEO.util.Event.unknownError.fire(o);
	}
};

/*
 * Metodo encargado de realizar el envio de una peticion asincrona al servidor utilizando GET como
 * forma de envio
 * @param url URL a la cual enviar la peticion
 * @param callback Objeto de retrollamada que se debe ejecutar al recibirse la respuesta
 *        del servidor
 * @return El objeto conexion
 */
GALILEO.util.Connect.asyncRequest = function (url, callback) {
	
	var expresion = /(.*)\.do(x?)(.*)/;
	if (expresion.test(url)) {
		url = url.replace(expresion, "$1" + ".dox" + "$3");
	}
  	return YAHOO.util.Connect.asyncRequest('GET', url, callback);
};

/*
 * Metodo encargado de realizar el envio de una peticion asincrona al servidor
 * @param formEl Nombre que posee el formulario que deseamos enviar o elemento
 * @param accion Metodo que se debe ejecutar en el servidor
 * @param callback Objeto de retrollamada que se debe ejecutar al recibirse la respuesta
 *        del servidor
 * @param return El objeto conexion
 */
GALILEO.util.Connect.asyncRequestForm = function (formEl, accion, callback) {
	var form = formEl;
	if (typeof formEl == "string") {
		form = document.forms[formEl];
	}
	form.accion.value = accion;
	
	// Obtenemos el action del formulario y cambiamos el .do por .dox
	var action = form.action;
	var expresion = /(.*)\.do.?/;
	if (expresion.test(action)) {
		form.action = action.replace(expresion, "$1" + ".dox");
	}
	YAHOO.util.Connect.setForm(form);
	return YAHOO.util.Connect.asyncRequest('POST', form.action, callback);
};

/*
 * Metodo encargado de realizar el envio de un formulario de forma asincrona al servidor
 * y escribir el resultado en una capa
 * @param formEl Nombre o elemento que posee el formulario que deseamos enviar
 * @param accion Metodo que se debe ejecutar en el servidor
 * @param contaninerId Capa en la cual realizar la carga del resultado devuelto por
 *        el servidor
 * @param success Metodo a ejecutar si la peticion se realiza de forma correcta
 * @return El objeto conexion
 */
GALILEO.util.Connect.asyncRequestFormEl = function (formEl, accion, containerId, success) {
	var form = formEl;
	if (typeof formEl == "string") { 
		form = document.forms[formEl];
	}
	form.accion.value = accion;
	
	// Obtenemos el action del formulario y cambiamos el .do por .dox
	var action = form.action;
	var expresion = /(.*)\.do.?/;
	if (expresion.test(action)) {
		form.action = action.replace(expresion, "$1" + ".dox");
	}

	var callback = {
		success: function(o) {
			var element = document.getElementById(containerId);
			element.innerHTML = o.responseText;
			if (success) {
				success();
			}
		},
		failure: GALILEO.util.Connect.generalHandlerFailure,
		scope: this
	};
	
	YAHOO.util.Connect.setForm(form);
	return YAHOO.util.Connect.asyncRequest('POST', form.action, callback);
};


/*
 * Metodo encargado de realizar el envio de una peticion asincrona al servidor cargando el resultado
 * en la capa especificada
 * @param url URL a la cual enviar la peticion
 * @param contaninerId Capa en la cual realizar la carga del resultado devuelto por
 *        el servidor
 * @param success Metodo a ejecutar si la peticion se realiza de forma correcta
 * @return El objeto conexion
 */
GALILEO.util.Connect.asyncRequestEl = function(url, containerId, success) {
	var callback = {
		success: function(o) {
			var element = document.getElementById(containerId);
			element.innerHTML = o.responseText;
			if (success) {
				success();
			}
		},
		failure: GALILEO.util.Connect.generalHandlerFailure,
		scope: this
	};
	
	var expresion = /(.*)\.do(x?)(.*)/;
	if (expresion.test(url)) {
		url = url.replace(expresion, "$1" + ".dox" + "$3");
	}
	return GALILEO.util.Connect.asyncRequest(url, callback);
};

/*
 * Metodo encargado de realizar el envio de una peticion asincrona al servidor cargando el resultado
 * en la capa especificada y procesar el resultado obtenido en formato JSON
 * @param url URL a la cual enviar la peticion
 * @param varFunct Metodo encargado de gestionar los objetos javascript que se
 *        generan despues del parseo JSON
 * @return El objeto conexion
 */
GALILEO.util.Connect.asyncRequestJSON = function(url, varFunct) {
	var success = function(o) {
		var objs = o.responseText.parseJSON();
		varFunct(objs);
	};
	
	var callback = {
		success: success,
		failure: GALILEO.util.Connect.generalHandlerFailure,
		scope: this
	};
	
	var expresion = /(.*)\.do(x?)(.*)/;
	if (expresion.test(url)) {
		url = url.replace(expresion, "$1" + ".dox" + "$3");
	}
	return GALILEO.util.Connect.asyncRequest(url, callback);
};

/*********** Metodos de utilidad para la gestion de elementos de formularios ************/

/*
 * Definicion del namespace de utilidad para formularios
 */
GALILEO.namespace("util.Form");

/*
 * Metodo encargado de decirnos si una cadena es float o no
 * @param form Formulario del cual queremos comprobar el campo
 * @param nameField Nombre del campo a comprobar
 * @return true si es numerica, false en caso contrario
 */
GALILEO.util.Form.isFloat = function (form, nameField) {
   var esNumerico = false;
   
   if (form && nameField) {
	   var field = GALILEO.util.Form.getField(form, nameField); 
   	
   	   if (field) {	
   	   	   return GALILEO.util.String.isFloat(field.value);
       }
   }
   
   return esNumerico;
};

/*
 * Metodo encargado de decirnos si una cadena es entera o no
 * @param form Formulario del cual queremos comprobar el campo
 * @param nameField Nombre del campo a comprobar
 * @return true si es entera, false en caso contrario
 */
GALILEO.util.Form.isInt = function (form, nameField) {
   var esNumerico = false;
   
   if (form && nameField) {	
   	   var field = GALILEO.util.Form.getField(form, nameField); 
	   if (field) {
	   	   esNumerico = GALILEO.util.String.isInt(field.value);
       }
   }
      
   return esNumerico;
};

/*
 * Metodo encargado de comprobar si un campo numerico esta entre un rango de valores
 * @param form Formulario del cual queremos comprobar el campo
 * @param nameField Nombre del campo a comprobar
 * @param min Valor minimo del rango
 * @param max Valor maximo del rango
 * @return true si esta en el rango, false en caso contrario
 */
GALILEO.util.Form.inRange = function(form, nameField, min, max) {
	var enRango = false;
	var numero = null;
	
	if (form && nameField) {	
   	   var field = GALILEO.util.Form.getField(form, nameField).value; 
   	   if ((GALILEO.util.Form.isInt(form, nameField) == true) || (GALILEO.util.Form.isFloat(form, nameField) == true)) {
   	   	  if (GALILEO.util.Form.isInt(form, nameField) == true) {
   			  if ((parseInt(min) <= parseInt(field)) && (parseInt(max) >= parseInt(field))) {
   			  	 enRango = true;
   			  }
   	   	  } else if (GALILEO.util.Form.isFloat(form, nameField) == true) {
   	   	  	  numero = GALILEO.util.Number.formatNumber.parse(field);
   			  if ((parseFloat(min) <= numero) && (parseFloat(max) >= numero)) {
   			  	 enRango = true;
   			  }
   	   	  }
   	   }
   }
	return enRango;
};

/*
 * Metodo encargado de decirnos si una cadena es un CIF correcto o no
 * @param form Formulario del cual queremos comprobar el campo
 * @param nameField Nombre del campo a comprobar
 * @return true si es correcto, false en caso contrario
 */
GALILEO.util.Form.validateCIF = function (form, nameField) {
   var esCIFValido = false;
   
   if (form && nameField) {	
   	   var field = GALILEO.util.Form.getField(form, nameField); 
	   if (field) {
	   	   esCIFValido = GALILEO.util.String.validateCIF(field.value);
       }
   }
      
   return esCIFValido;
};

/*
 * Metodo encargado de decirnos si una cadena es un NIF correcto o no
 * @param form Formulario del cual queremos comprobar el campo
 * @param nameField Nombre del campo a comprobar
 * @return true si es correcto, false en caso contrario
 */
GALILEO.util.Form.validateNIF = function (form, nameField) {
   var esNIFValido = false;
   
   if (form && nameField) {	
   	   var field = GALILEO.util.Form.getField(form, nameField); 
	   if (field) {
	   	   esNIFValido = GALILEO.util.String.validateNIF(field.value);
       }
   }
      
   return esNIFValido;
};


/*
 * Metodo encargado de indicarnos cual es el radio seleccionado en un radio group
 * @param form Formulario al que pertenece el radio group
 * @param nameRadioGroup Nombre del grupo de radios a comprobar
 * @return El elemento selecionado o bien null si no hay ninguno
 */
GALILEO.util.Form.getSelectedRadio = function (form, nameRadioGroup) {

   var radioGroup = null;
   	
   if (form && nameRadioGroup) {	
	   if (typeof nameRadioGroup == "string") {
			if (typeof form == "string") {
				form = document.forms[form];
			}
			radioGroup = form.elements[nameRadioGroup]
	   }
	   
	   if (radioGroup) {
		   if (radioGroup[0]) { 
	    	  for (var i=0; i < radioGroup.length; i++) {
	        	 if (radioGroup[i].checked) {
	            	return radioGroup[i]
		 		 }
			  }
		   } else {
	   		  if (radioGroup.checked) { return radioGroup; }
		   }
	   }
   }
   
   return null;
};



/*
 * Metodo encargado de indicarnos cual es el indice del radio seleccionado en un radio group
 * @param form Formulario al que pertenece el radio group
 * @param nameRadioGroup Nombre del grupo de radios a comprobar
 * @return El indice del radio group o -1 si no hay seleccionado
 */
GALILEO.util.Form.getSelectedIndexRadio = function (form, nameRadioGroup) {

   var radioGroup = null;

   if (nameRadioGroup && form) {
   	   
   	   if (typeof nameRadioGroup == "string") {
			if (typeof form == "string") {
				form = document.forms[form];
			}
			radioGroup = form.elements[nameRadioGroup]
	   }
		
	   if (radioGroup) {			
		   if (radioGroup[0]) { 
	    	  for (var i=0; i < radioGroup.length; i++) {
	        	 if (radioGroup[i].checked) {
	            	return i
		 		 }
			  }
		   } else {
	   		  if (radioGroup.checked) { return 0; }
		   }
	   }
   }
   
   return -1;
}; 


/*
 * Metodo encargado de devolver el array de los checkbox seleccionados
 * @param form Formulario al que pertenece el checkbox
 * @param nameCheckbox Nombre del checkbox a comprobar
 * @return Array de los checkbox seleccionados o bien null si no hay ninguno
 */
GALILEO.util.Form.getSelectedCheckboxArray = function (form, nameCheckbox) {

   var checkboxArray = new Array();
   	
   if (form && nameCheckbox) {	
	   if (typeof nameCheckbox == "string") {
			if (typeof form == "string") {
				form = document.forms[form];
			}
			checkbox = form.elements[nameCheckbox]
	   }
	   
	   if (checkbox) {
	   	   if (checkbox[0]) { 
		   	  var j = 0;	
	    	  for (var i=0; i < checkbox.length; i++) {
	        	 if (checkbox[i].checked) {
	            	checkboxArray[j] = checkbox[i].value;
	            	j = j + 1;
		 		 }
			  }
		   }else {
	   		  if (checkbox.checked) { checkboxArray[0]= checkbox.value; }
		   }
	   }
   }
   
   return checkboxArray;
};

/**
 * Metodo encargado de obtener el numero de decimales de un numero
 * @param form El formulario que contiene la cantidad a validar
 * @param nameField El nombre del campo a validar
 * @return El numero de decimales de los cuales consta el numero
 */
GALILEO.util.Form.getDecimalNumberDigits = function(form, nameField) {
	
	var exp1 = /(\d+)\.(\d+)/;
	var exp2 = /(\d+),(\d+)/;
	var numDigits = 0;
	
	 if (form && nameField) {	
   	    var field = GALILEO.util.Form.getField(form, nameField).value; 
		if (GALILEO.util.Form.isInt(form, nameField) == true) {
			return numDigits;
		} else if (GALILEO.util.Form.isFloat(form, nameField) == true) {
			// Comprobamos cual es el separador
			if (field.indexOf(',') == -1) {
				numDigits = field.replace(exp1, "$2");
				return numDigits.length;
			}
			else {
				numDigits = field.replace(exp2, "$2");
				return numDigits.length;
			}
		}
		else {
			return false;
		}
	}
	else {
		return false;
	}
};

/*
 * Metodo encargado de comprobar si un campo de texto es vacio
 * @param form Formulario del cual queremos comprobar el campo
 * @param nameField Nombre del campo a comprobar
 * @return true Si el campo es vacio, false en caso contrario
 */
GALILEO.util.Form.isEmpty = function(form, nameField) {
	if (form && nameField) {
		var field = GALILEO.util.Form.getField(form, nameField);
		if (field) {
			var text = GALILEO.util.String.trim(field.value);
			if (text.length == 0) {
				return true;
			}
		}
	}
	
	return false;
}; 

/*
 * Metodo encargado de obtener un campo de un formulario
 * @param form Formulario que posee el campo
 * @param nameField Nombre del campo que deseamos obtener
 * @return El elemento o null si no existe
 */
GALILEO.util.Form.getField = function(form, nameField) {
	if (form && nameField) {
		if (typeof nameField == "string") {
			if (typeof form == "string") {
				form = document.forms[form];
			}
			return form.elements[nameField]
		}
	}
	
	return null;
};

/*
 * Metodo encargado de cambiar las opciones de un combo en relacion a los valores recibidos
 * via AJAX
 * @form formulario donde se ubica el combo
 * @param select Combo o id del combo del cual cambiar sus opciones
 * @param o Objeto respuesta recibido
 * @param selectedValue Valor del elemento que queremos seleccionar
 *
 */
GALILEO.util.Form.setSelect = function(form, select, o, selectedValue) {
	if (form && select && o) {
		// Usar el formulario y el campo provoca problemas cuando existen tabs
		//select = GALILEO.util.Form.getField(form, select);
		select = YAHOO.util.Dom.get(select);
		var json = o.responseText.parseJSON();
		var longitud = select.length;
		
		// Borrar lo que hubiera en los options
		for (var i=0; i<longitud; i++){
			select.options[0] = null;
		}
		// Creamos las nuevas opciones con los resultados del array
		for (var i=0; i<json.Result.length; i++){
			if ((selectedValue != null) && (selectedValue === json.Result[i].Key)) {
				select.options[i] = new Option(json.Result[i].Value,json.Result[i].Key);
				select.options[i].selected = "selected";
			} else {
				select.options[i] = new Option(json.Result[i].Value,json.Result[i].Key);
			}
		}
	}
};

/********** Definicion de un namespace para la gestion de url's ********/

GALILEO.namespace("util.URL");
 
/*
 * Metodo encargado de codificar un texto utilizando la codificacion de URL
 * @param text Texto a codificar
 * @return El texto codificado
 */
GALILEO.util.URL.urlEncode = function (text) {
	// The Javascript escape and unescape functions do not correspond
	// with what browsers actually do...
	var SAFECHARS = "0123456789" +					// Numeric
					"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +	// Alphabetic
					"abcdefghijklmnopqrstuvwxyz" +
					"-_.!~*'()";					// RFC2396 Mark characters
	var HEX = "0123456789ABCDEF";

	var plaintext = text;
	var encoded = "";
	for (var i = 0; i < plaintext.length; i++ ) {
		var ch = plaintext.charAt(i);
	    if (ch == " ") {
		    encoded += "+";				// x-www-urlencoded, rather than %20
		} else if (SAFECHARS.indexOf(ch) != -1) {
		    encoded += ch;
		} else {
		    var charCode = ch.charCodeAt(0);
			if (charCode > 255) {
					var dlg = new GALILEO.widget.GSimpleDialog('__dlgURLDecode', '25em', true);
				    dlg.setIcon(GALILEO.widget.SimpleDialog.config.INFO_ICON);
					dlg.setHeader("Informe");
				    mensaje = "El caracter '" 
		                      + ch 
    		                  + "' no entra dentro del estandar de codificacion, sera sustituido por un espacio.\n";
					dlg.setBody(mensaje);
					dlg.show();
					
					encoded += "+";
			} else {
				encoded += "%";
				encoded += HEX.charAt((charCode >> 4) & 0xF);
				encoded += HEX.charAt(charCode & 0xF);
			}
		}
	} // for

	return encoded;
};

/*
 * Metodo encargado de decodificar un texto utilizando la codificacion de URL
 * @param text Texto a decodificar
 * @return El texto decodificado
 */
GALILEO.util.URL.urlDecode = function (text) {
   // Replace + with ' '
   // Replace %xx with equivalent character
   // Put [ERROR] in output if %xx is invalid.
   var HEXCHARS = "0123456789ABCDEFabcdef"; 
   var encoded = text;
   var plaintext = "";
   var i = 0;
   while (i < encoded.length) {
       var ch = encoded.charAt(i);
	   if (ch == "+") {
	       plaintext += " ";
		   i++;
	   } else if (ch == "%") {
			if (i < (encoded.length-2) 
					&& HEXCHARS.indexOf(encoded.charAt(i+1)) != -1 
					&& HEXCHARS.indexOf(encoded.charAt(i+2)) != -1 ) {
				plaintext += unescape( encoded.substr(i,3) );
				i += 3;
			} else {
				var dlg = new GALILEO.widget.GSimpleDialog('__dlgURLEncode', '25em', true);
			    dlg.setIcon(GALILEO.widget.SimpleDialog.config.ERROR_ICON);
				dlg.setHeader("Error");
				mensaje = 'Bad escape combination near ...' + encoded.substr(i);
				dlg.setBody(mensaje);
				dlg.show();
				
				plaintext += "%[ERROR]";
				i++;
			}
		} else {
		   plaintext += ch;
		   i++;
		}
	} // while
	
   return plaintext;
};

/*********** Metodos de utilidad para la gestion de DOM ************/
GALILEO.namespace("util.Dom");

/*
 * Metodo utilizado de crear un nuevo elemento para insertarlo en el dom
 * @param tag Elemento que deseamos crear
 * @param properties Array de propiedades que deseamos asignar, vienen definidas como
 *                   objetos del tipo {name, value}
 * @return El elemento que hemos creado
 */
GALILEO.util.Dom.createElement = function(tag, properties) {
	var element = null;

	try {
		// Intentamos crear el elemento de la forma de explorer
		var type = "";
		var name = "";
		if (properties) {
			for(var i = 0; i < properties.length; i++) {
				switch (properties[i].name) {
					case 'name':
						name = ("name='" + properties[i].value + "' ");
						break;
					case 'type':
						type = ("type='" + properties[i].value + "' ");
						break;
				}
			}
		} 
	
		element = document.createElement("<" + tag + ' ' + type + name + " >");

		if (properties) {
			for(var i = 0; i < properties.length; i++) {
				var property = properties[i];
				if ((property.name != 'type') && (property.name != 'name')) {
					if (property.name == 'className') {
						YAHOO.util.Dom.addClass(element, property.value);
					}
					else {
						element.setAttribute(property.name, property.value);
					}
				}
			}
		}
	} catch (e) {
		// Creamos el elemento de manera normal
		element = document.createElement(tag);

		if (properties) {
			for(var i = 0; i < properties.length; i++) {
				var property = properties[i];
				if (property.name == 'className') {
					YAHOO.util.Dom.addClass(element, property.value);
				}
				else {
					element.setAttribute(property.name, property.value);
				}
			}
		}
	}
	
	return element;
};

/**
 * Metodo encargado de obtener los elementos a raiz de un nombre de tag
 * @param tag Tag de los elementos que desamos obtener
 * @param root Elemento raiz a raiz del cual obtener los elementos, si no se
 * especifica, se usara document
 * @return Un array con los elementos que poseen ese tag
 */
GALILEO.util.Dom.getElementsByTagName = function(tag, root) {
	if (tag)
		if (root) {
			if ("string" == typeof root) {
				root = YAHOO.util.Dom.get(root);
			}
			return root.getElementsByTagName(tag);
		}
		else {
			return document.getElementsByTagName(tag);
		}
	return false;
};

/*
 * Metodo encargado de indicarnos cual es el radio seleccionado en un radio group
 * @param nameRadioGroup Nombre del grupo de radios a comprobar
 * @return El elemento selecionado o bien null si no hay ninguno
 */
GALILEO.util.Dom.getSelectedRadio = function (nameRadioGroup) {

   var radioGroup = null;
   	
   if (nameRadioGroup) {	
	   if (typeof nameRadioGroup == "string") {
			radioGroup = document.getElementsByName(nameRadioGroup);
	   }
	   
	   if (radioGroup) {
		   if (radioGroup[0]) { 
	    	  for (var i=0; i < radioGroup.length; i++) {
	        	 if (radioGroup[i].checked) {
	            	return radioGroup[i]
		 		 }
			  }
		   } else {
	   		  if (radioGroup.checked) { return radioGroup; }
		   }
	   }
   }
   
   return null;
};


/*
 * Metodo encargado de devolver el array de los checkbox seleccionados
 * @param nameCheckbox Nombre del checkbox a comprobar
 * @return Array de los checkbox seleccionados o bien null si no hay ninguno
 */
GALILEO.util.Dom.getSelectedCheckboxArray = function (nameCheckbox) {

   var checkboxArray = new Array();
   	
   if (nameCheckbox) {	
	   if (typeof nameCheckbox == "string") {
			checkbox = document.getElementsByName(nameCheckbox);
	   }
	   
	   if (checkbox) {
	   	   if (checkbox[0]) { 
		   	  var j = 0;	
	    	  for (var i=0; i < checkbox.length; i++) {
	        	 if (checkbox[i].checked) {
	            	checkboxArray[j] = checkbox[i].value;
	            	j = j + 1;
		 		 }
			  }
		   }else {
	   		  if (checkbox.checked) { checkboxArray[0]= checkbox.value; }
		   }
	   }
   }
   
   return checkboxArray;
};

/*********** Metodos de utilidad para la gestion de eventos ************/
GALILEO.namespace("util.Event");

/*
 * Definicion de un evento particularizado que nos indica que se ha escrito en el
 * DOM del documento
 */
GALILEO.util.Event.modifyDOM = new YAHOO.util.CustomEvent("modifyDOM");

/*
 * Definicion de un evento que indica un error global
 */
GALILEO.util.Event.globalException = new YAHOO.util.CustomEvent("globalException");

/*
 * Definicion de un evento que indica un error de seguridad
 */
GALILEO.util.Event.securityException = new YAHOO.util.CustomEvent("securityException");

/*
 * Definicion de un evento que indica un error producido por la respuesta del servidor
 */
GALILEO.util.Event.serverError = new YAHOO.util.CustomEvent("serverError");

/*
 * Definicion de un evento que indica un error desconocido
 */
GALILEO.util.Event.unknownError = new YAHOO.util.CustomEvent("unknownError");

/*********** Metodos de utilidad para la gestion de textos ************/

GALILEO.namespace("util.String");

/*
 * Metodo encargado de eliminar los espacios en blanco a la izquierda de un texto
 * @param text Texto a procesar
 * @return El texto si los espacios a la izquierda
 */
GALILEO.util.String.trimLeft = function(text) {
	return text.replace(/^(\s*)([\W\w]*)$/, '$2');
};

/*
 * Metodo encargado de eliminar los espacios en blanco a la derecha de un texto
 * @param text Texto a procesar
 * @return El texto si los espacios a la derecha
 */
GALILEO.util.String.trimRight = function(text) {
	return text.replace(/^([\W\w]*)(\b\s*)$/, '$1');
};

/*
 * Metodo encargado de eliminar los espacios en blanco en un texto, tanto a
 * la derecha como a la izquierda
 * @param text Texto a procesar
 * @return El texto si los espacios a la izquierda ni a la derecha
 */
GALILEO.util.String.trim = function(text) {
	return GALILEO.util.String.trimRight(GALILEO.util.String.trimLeft(text));
};

/*
 * Metodo encargado de comprobar si un String es un Integer
 * @param text Texto a comprobar
 * @return true si es Integer, false si no
 */
GALILEO.util.String.isInt = function(text) {
   var esNumerico = false;
   
   if (text) {	
	   var caracteresValidos = "0123456789";
   	   var caracter;
   	   
       esNumerico = true;
       for (i = 0; i < text.length && esNumerico == true; i++) {  
       	   caracter = text.charAt(i); 
           if (caracteresValidos.indexOf(caracter) == -1) {
               esNumerico = false;
           }
       }
           
       if (text.length == 0) {
       	   esNumerico = false;
       }
   }
      
   return esNumerico;
};

GALILEO.util.String.isFloat = function(text) {
   var esNumerico = false;
   
   if (text) {	
   	  var caracteresValidos = "0123456789.,";
  	  var caracter;
   	   
      esNumerico = true;
	  for (i = 0; i < text.length && esNumerico == true; i++) {  
	   	  caracter = text.charAt(i); 
          if (caracteresValidos.indexOf(caracter) == -1) {
       	     esNumerico = false;
	      }
      }

      // Comprobamos si no es unicamente un .   
      if ((text.length == 1) && ((text == '.') || (text == ','))) {
         esNumerico = false;
      }
   }
   
   return esNumerico;
};

GALILEO.util.String.validateCIF = function(text) {
        
   var pares = 0;
   var impares = 0;
   var suma;
   var ultima;
   var unumero;
   var uletra = new Array("J", "A", "B", "C", "D", "E", "F", "G", "H", "I");
   var auxiliar;
        
   text = text.toUpperCase();
   var regular = new RegExp(/^[ABCDEFGHKLMNPQS]\d{7}[0-9,A-J]$/g);
   if (!regular.exec(text)) 
      return false;
             
   ultima = text.substr(8,1);

   for (var cont = 1 ; cont < 7 ; cont ++){
      auxiliar = (2 * parseInt(text.substr(cont++,1))).toString() + "0";
      impares += parseInt(auxiliar.substr(0,1)) + parseInt(auxiliar.substr(1,1));
      pares += parseInt(text.substr(cont,1));
   }
   auxiliar = (2 * parseInt(text.substr(cont,1))).toString() + "0";
   impares += parseInt(auxiliar.substr(0,1)) + parseInt(auxiliar.substr(1,1));
         
   suma = (pares + impares).toString();
   unumero = parseInt(suma.substr(suma.length - 1, 1));
   unumero = (10 - unumero).toString();
         
   if(unumero == 10)
      unumero = 0;
         
   if ((ultima == unumero) || (ultima == uletra[unumero])){
      return true;
   } else {
      return false;
   }
};

GALILEO.util.String.validateNIF = function(text) {
  	text = text.toUpperCase();

    if (!/^\d{8}[A-Z]$/.test(text))
      return false;
        
    var ultima = text.substr(8,1);
    var numeros = text.substr(0,8);
        
    var letrasValidas="TRWAGMYFPDXBNJZSQVHLCKET";
    var posicion= numeros % 23;
    var letraCorrecta = letrasValidas.charAt(posicion);
        
    if (ultima != letraCorrecta) 
       return false;
        
    return true;
};

/*********** Metodos de utilidad para la gestion navegadores ************/

GALILEO.namespace("util.Navigator");

/* 
 * Metodo encargado de indicarnos que navegador es el que poseemos
 * @return Un string con el navegador con el que trabajamos, false en caso de
 *         no reconocerlo
 */
GALILEO.util.Navigator.getBrowser = function() {
	var ua = navigator.userAgent.toLowerCase();
  
	if (ua.indexOf('opera')!=-1) {
		return 'opera';
	} else if (ua.indexOf('msie')!=-1) {
		return 'ie';
	} else if (ua.indexOf('safari')!=-1) {
		return 'safari';
	} else if (ua.indexOf('gecko') != -1) {
		return 'gecko';
	} else {
	    return false;
	}
};

/*************** Metodos de utilidad para la gestion de formatos numericos ***********/

GALILEO.namespace("util.Number");

/*
 * Definicion de la clase encargada de realizar el formateo de un numero flotante o integer 
 * al estilo xxxxx,yy (2 digitos fraccionales)
 * Por defecto realiza el formateo de los numeros utilizando redondeo
 */
GALILEO.util.Number.FormatNumber = function() {
	this.formatter = new NumberFormat();		
    this.formatter.setCommas(true);
	this.formatter.setNegativeFormat(this.LEFT_DASH);
    this.formatter.setNegativeRed(false);
    this.formatter.setCurrency(false);
    this.formatter.setCurrencyPrefix('');
    this.formatter.setPlaces(2, false);
    this.formatter.setSeparators(true, '', ',');
    this.defaultNumberFormat = "0,00";
};

/*
 * Definicion del formateador encargado de formatear los numeros
 */
GALILEO.util.Number.FormatNumber.formatter = null;
/*
 * Definicion del formato por defecto a devolver
 */
GALILEO.util.Number.FormatNumber.defaultNumberFormat = null;

/*
 * Metodo encargado de realizar el formato de un numero a punto flotante
 * @param number Numero a formatear
 * @return El numero formateado o 0,00 en el caso de que sea incorrecto
 */
GALILEO.util.Number.FormatNumber.prototype.format = function(number) {
	if (number) {
		// Parseamos el numero en el caso de que sea valido
		number = this.parse(number);
		// Comprobamos que es correcto
		if (((GALILEO.util.String.isFloat(number) == true) || (GALILEO.util.String.isInt(number) == true)) && (number > 0)) {
			this.formatter.setNumber(number);
			return this.formatter.toFormatted();
		}
	}
	
	return this.defaultNumberFormat;
};

/*
 * Metodo encargado de realizar el parseo de un numero
 * @number Numero a parsear
 * @return El numero parseado en punto flotante o 0.0 si no es un numero
 */
GALILEO.util.Number.FormatNumber.prototype.parse = function(number) {
	var exp = /(\d+),(\d+)/;
	
	if (exp.test(number)) {
		number = number.replace(exp, "$1" + '.' + "$2");
	}
	var numberParse = parseFloat(number);
	
	if (isNaN(numberParse))
		return parseFloat('0.0');
	
	return numberParse;
};

/*
 * Metodo encargado de truncar un numero decimal al numero de digitos indicados
 * @param number Numero a truncar
 * @param digits Digitos a mostrar
 * @param msg Mensaje que se desea mostrar informando que no se permiten mas digitos
 * decimales
 * @return El numero truncado
 */
GALILEO.util.Number.FormatNumber.prototype.truncate = function(number, msg) {
	if (number) {
		// Comprobamos la posicion de la coma que indica la parte decimal
		var parteEntera = number + "";
		var parteDecimal = "";
		var posComa = parteEntera.indexOf(',');
		if (posComa != -1) {
			parteDecimal = ',' + parteEntera.substring(posComa + 1, parteEntera.length);
			if ((parteDecimal.length > 3) && (msg)){
				var dlg = new GALILEO.widget.GSimpleDialog('__dlgFormatNumber', '25em', false, true);
			    dlg.setIcon(GALILEO.widget.SimpleDialog.config.WARN_ICON);
				dlg.setHeader("Warning");
				dlg.setBody(msg);
				dlg.show();
				parteDecimal = parteDecimal.substring(0, 3);
			}
			parteEntera = parteEntera.substring(0, posComa);
		}
		
		return parteEntera + parteDecimal;
	}
	
	return this.defaultNumberFormat;
};

/*
 * Definicion de la clase encargada de realizar el formateo de un numero flotante o integer 
 * a moneda con el formato xxxxx,yy euros (2 digitos fraccionales)
 */
GALILEO.util.Number.FormatMoney = function() {
	GALILEO.util.Number.FormatMoney.superclass.constructor.call(this);
	this.defaultNumberFormat = '0,00' + ' \u20AC';
	this.formatter.setCurrency(true);
	this.formatter.setCurrencyPrefix(' \u20AC');
	this.formatter.setCurrencyPosition(this.formatter.RIGHT_OUTSIDE);
    this.formatter.setSeparators(true, '.', ',');
};

/*
 * Definicion de la herencia
 */
YAHOO.extend(GALILEO.util.Number.FormatMoney, GALILEO.util.Number.FormatNumber); 

// FIXME: Parser no probado en su totalidad
GALILEO.util.Number.FormatMoney.prototype.parse = function(number) {
	// Eliminamos el simbolo del euro
	number += "";
	var posEuro = number.indexOf(' ');
	var parteEntera = number;
	if (posEuro != -1) {
		parteEntera = number.substring(0, posEuro);
	}
	
	// Dividimos el numero en parte entera y parte decimal, es decir, buscamos la ,
	var posComa = parteEntera.indexOf(',');
	var parteDecimal = "";
	
	if (posComa != -1) {
		parteDecimal = ',' + parteEntera.substring(posComa + 1, parteEntera.length); 
		parteEntera = parteEntera.substring(0, posComa);
		// Transformamos la parte entera para parsearla correctamente	
		var exp = /(\d+).(\d{3})/;
		while(exp.test(parteEntera)) {
			parteEntera = parteEntera.replace(exp, "$1" + "$2");
		}
	}
	
	return GALILEO.util.Number.FormatMoney.superclass.parse.call(this, parteEntera + parteDecimal);
};

/*
 * Variables de utilidad para realizar el formato tanto de numero como de moneda
 */
GALILEO.util.Number.formatNumber = new GALILEO.util.Number.FormatNumber();
GALILEO.util.Number.formatMoney = new GALILEO.util.Number.FormatMoney();

/*
 * Creamos el objeto que sera el subcritor general que utilizaremos
 */
GALILEO.util.Connect.errorSubscriptor = new GALILEO.util.Connect.ErrorSubscriptor();

GALILEO.util.GPageLoad = function() {
	this._animate = GALILEO.util.PageLoad.config.animate;
	this._firstTime = true;
	this._eventListener = false;
	if (YAHOO.util.Dom.inDocument('gyui-page-load')) {
		this._init(this);
	} else {
		YAHOO.util.Event.onContentReady('gyui-page-load', this._init, this, true);
	}
};

GALILEO.util.GPageLoad.prototype._cargada = false;
GALILEO.util.GPageLoad.prototype._animate = null;
GALILEO.util.GPageLoad.prototype._element = null;
GALILEO.util.GPageLoad.prototype._content = null;
GALILEO.util.GPageLoad.prototype._anim = null;
GALILEO.util.GPageLoad.prototype._firstTime = true;
GALILEO.util.GPageLoad.prototype._eventListener = false;

GALILEO.util.GPageLoad.prototype._init = function(obj) {
	try {
		if (!obj._cargada) {
			obj._element = YAHOO.util.Dom.get('gyui-page-load');
			obj._content = YAHOO.util.Dom.getElementsByClassName('gyui-page-load-message', 'div', obj._element)[0];

			obj._anim = new YAHOO.util.Anim(obj._element, { opacity: {from: 0.95, to: 0} }, 1, YAHOO.util.Easing.easeOut);
	
			 var s = obj._element.style;
				s.zIndex = 100000000;
				s.left = 0;
				s.top = 0;
				s.margin = 0;
				s.padding = 0;
				s.opacity = 0.95;
				s.overflow = 'hidden';
				s.visibility = 'visible';
				s.position = 'absolute';
				s.filter = 'alpha(opacity=95)';
				s.display = 'block';
		    obj.show();
		}
	 } catch (e) {}
};

GALILEO.util.GPageLoad.prototype.show = function() {
	if (!this._cargada) {
		YAHOO.util.Dom.addClass(document.body, 'gyui-page-load-select');
		YAHOO.util.Dom.setStyle(document.body, 'overflow', 'hidden');
		YAHOO.util.Dom.setStyle(this._element, 'display', 'block');
		this._ajustar();
		if (this._firstTime) {
			YAHOO.util.Event.addListener(window, 'load', this.end, this, true);
			this._firstTime = false;
			this._eventListener = true;
		}
	}
};

GALILEO.util.GPageLoad.prototype._end = function(obj) {

	if (YAHOO.util.Dom.get('gyui-page-load')) {
		YAHOO.util.Dom.setStyle(YAHOO.util.Dom.get('gyui-page-load'), 'display', 'none');
	}
	YAHOO.util.Dom.removeClass(document.body, 'gyui-page-load-select');
	YAHOO.util.Dom.setStyle(document.body, 'overflow', '');
};

GALILEO.util.GPageLoad.prototype._onEnd = function(e, args, obj) {

	obj._end();
};

GALILEO.util.GPageLoad.prototype.end = function(e, obj) {
	obj._cargada = true;
	if (obj._eventListener) {
		YAHOO.util.Event.removeListener(window, 'load', obj.end);
		obj._eventListener = false;
	}
	if ((obj._animate) && (obj._anim)) {
		if ((obj._anim) && (obj._anim.isAnimated())) { obj._anim.stop(); }
		obj._anim.onComplete.subscribe(obj._onEnd, obj);
		obj._anim.animate();
	} else {
		obj._end();
	}
};

GALILEO.util.GPageLoad.prototype._ajustar = function () {
    // getting the current viewport position and dimentions
    var vp = {top: YAHOO.util.Dom.getDocumentScrollTop(), left: YAHOO.util.Dom.getDocumentScrollLeft(), width: YAHOO.util.Dom.getViewportWidth (), height: YAHOO.util.Dom.getViewportHeight ()};
    YAHOO.util.Dom.setStyle(this._element, 'height', vp.height+'px');
    YAHOO.util.Dom.setStyle(this._element, 'width', vp.width+'px');
    YAHOO.util.Dom.setXY(this._element, [vp.left, vp.top]);
    
    // applying the corresponding position: centering the content...
    var size = YAHOO.util.Dom.getRegion(this._content);
    var oHeight = size.bottom - size.top;
    var oWidth = size.right - size.left;
    YAHOO.util.Dom.setXY(this._content, [vp.left + ((vp.width - oWidth) / 2), vp.top + ((vp.height - oHeight) / 2)]);
};

GALILEO.util.GPageLoad.prototype.showMask = function() {
	
	this._cargada = false;
	this._init(this);
};

GALILEO.util.GPageLoad.prototype.hideMask = function() {
	
	this._eventListener = false;
	this.end(null, this);
};

/*if (GALILEO.util.PageLoad.config.show) {

	GALILEO.util.objPageLoad = new GALILEO.util.GPageLoad();
	
	GALILEO.util.objPageLoad.invalidate = function(e) {
		
		var invalidatePageLoad = function() {
			if (GALILEO.util.objPageLoad) {
				GALILEO.util.objPageLoad.end(null, GALILEO.util.objPageLoad);
				GALILEO.util.objPageLoad = null;
			}
		};
		
		//invalidatePageLoad();
		setTimeout(invalidatePageLoad, 1500);
	};

	YAHOO.util.Event.addListener(window, 'load', GALILEO.util.objPageLoad.invalidate);
}*/