/********************************************************************************************<script>
                        Nombre: funcionesXML.js
                        Descripción: script de cliente utilizado para el tratamiento de los xml
********************************************************************************************/

/************ MÉTODOS PARA EL TRATAMIENTO DEL XML DEPENDIENDO DEL EXPLORADOR*****************/
if( document.implementation.hasFeature("XPath", "3.0") ){
	XMLDocument.prototype.selectNodes = function(cXPathString, xNode){
		if( !xNode ) {
			xNode = this;
		}
		var oNSResolver = this.createNSResolver(this.documentElement)
		var aItems = this.evaluate(cXPathString, xNode, oNSResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)
		var aResult = [];
		for( var i = 0; i < aItems.snapshotLength; i++){
			aResult[i] =  aItems.snapshotItem(i);
		}
		return aResult;
	}
	XMLDocument.prototype.selectSingleNode = function(cXPathString, xNode){
		if( !xNode ){
			 xNode = this;
		}

		var xItems = this.selectNodes(cXPathString, xNode);
		if( xItems.length > 0 ){
			return xItems[0];
		}else{
			return null;
		}
	}
	Element.prototype.selectNodes = function(cXPathString){
		if(this.ownerDocument.selectNodes){
			return this.ownerDocument.selectNodes(cXPathString, this);
		}else{
			return this.selectNodes(cXPathString, this);
		}
	}

	Element.prototype.selectSingleNode = function(cXPathString){
		if(this.ownerDocument.selectSingleNode){
			return this.ownerDocument.selectSingleNode(cXPathString, this);
		}else{
			return this.selectSingleNode(cXPathString, this)
		}
	}
}

//Miramos que tipo de explorador tenemos
function esExplorer() {
	if (window.ActiveXObject) { // de lo contrario utilizar el control ActiveX para IE5.x y IE6.x
		return true;
	} else {// para IE7, Mozilla, Safari,
		return false;
	}
}

//Método que crea el objeto de XML
function getXMLHttpRequest(){
	var aVersions = ["MSXML2.XMLHttp.5.0",
        	"MSXML2.XMLHttp.4.0","MSXML2.XMLHttp.3.0",
	        "MSXML2.XMLHttp","Microsoft.XMLHttp"];
	if (esExplorer()){
		// de lo contrario utilizar el control ActiveX para IE5.x y IE6.x
		for (var i = 0; i < aVersions.length; i++) {
			try {
				var oXmlHttp = new ActiveXObject(aVersions[i]);
				return oXmlHttp;
			}catch (error) {
					//no necesitamos hacer nada especial
			}
		}
	} else {
		// para IE7, Mozilla, Safari, etc: que usen el objeto nativo
		return new XMLHttpRequest();
	}
}

//Creamos el documento según tipo de explorador.
function getXMLDocument(sTexto){
	// code for IE
	var doc;
	if (esExplorer()){
		doc = new ActiveXObject("Microsoft.XMLDOM");
		doc.async="false";
		doc.loadXML(sTexto);
	}else{// code for Mozilla, Firefox, Opera, etc.
		var parser = new DOMParser();
		doc = parser.parseFromString(sTexto,"text/xml");
	}
	return doc;
}

//Pasa el nodo o documento a tipo string
function getStringFromDocument(nodo) {
	if(esExplorer()){
		return nodo.xml;
	}else{
		return (new XMLSerializer()).serializeToString(nodo);
	}
}

//Método que realiza una petición XMLHTTP al servidor
function enviarAServlet(oXML, sMensaje, sURL, sFuncion, bOcultarPanel, idPagina){
	/*if(bOcultarPanel==null){
		bOcultarPanel = true;
	}
	
	mostrarPanelProceso(sMensaje, idPagina);*/

	var objXMLReq = getXMLHttpRequest();
	objXMLReq.open("POST", sURL, true);

	objXMLReq.onreadystatechange = function() {
		if (objXMLReq.readyState==4) {
			try{
				var oResult = objXMLReq.responseXML;
				var sXML = getStringFromDocument(oResult);
				sXML = convertir_Texto_A_AASCII(sXML);
				var objXML  = getXMLDocument(sXML);
				eval(sFuncion+"(objXML);");
			}catch(error){
				if (esExplorer()){
					mostrarPanelError("ERROR","ERROR",error.description,"onclick_linkContinuar()");
				}else{
					mostrarPanelError("ERROR","ERROR",error,"onclick_linkContinuar()");
				}
			}
			/*if (bOcultarPanel){
				ocultarPanelProceso();
			}*/
		}
	}

	if ( oXML.selectNodes("//ERRORES").length>0 ){
		var oNodo = oXML.selectNodes("//ERRORES")[0].parentNode;
		oNodo.removeChild( oXML.selectNodes("//ERRORES")[0] );
		aniadirNodo(oNodo, "ERRORES", null);
	}

	if ( oXML.selectNodes("//PARAMETROS/@CODERROR").length>0 ){
		asignaValor(oXML.selectNodes("//PARAMETROS/@CODERROR")[0],"");
	}

	objXMLReq.send(oXML);
}

//Cargamos el xsl de la página a partir de un xml recibido.
//IMPORTANTE: En la página donde llama al método se debe añadir un div (contenedor)
//xmlDatos --> Documento del xml (instancia)
//pagXslDatos --> Nombre y ruta al del xsl
//contenedor --> Nombre del elemento HTML contenedor
function cargarXSL(xmlDatos, pagXslDatos, contenedor){
	if (esExplorer()) { //IE
		var datosDeTransformacion = getXMLDocument("");
		datosDeTransformacion.async = false;
		// Se carga el XSL de transformación
		datosDeTransformacion.load(pagXslDatos);
		document.getElementById(contenedor).innerHTML = xmlDatos.transformNode(datosDeTransformacion);
	} else { //mozilla/netscape
		var procesador = new XSLTProcessor();
		var documentoXSL = document.implementation.createDocument("", "", null);
		documentoXSL.async = false;
		documentoXSL.load(pagXslDatos);
		procesador.importStylesheet(documentoXSL);
		var sResultado = new XMLSerializer().serializeToString(procesador.transformToDocument(xmlDatos))
		document.getElementById(contenedor).innerHTML = sResultado;
	}
}

/************ MÉTODOS PARA LA GESTIÓN DE XML *****************/
//Crea un xml, volcándole la cadena recibida como primer parámetro y obtiene
//los nodos que tienen por nombre el recibido en el segundo parámetro
function obtenerNodos(sXml, sNombreNodos) {
	var objXML = getXMLDocument(sXml);
	return objXML.selectNodes("//" + sNombreNodos);
}

//Crea un nuevo nodo, con sus atributos y sus valores
function crearNodo(xml, nombreNodo, valorNodo, aAtributos, aValores) {
	var nuevoNodo = xml.createElement(nombreNodo);
	nuevoNodo.text = valorNodo;
	aniadirAtributos(nuevoNodo, aAtributos, aValores);
	return nuevoNodo;
}

//Añade un nuevo nodo a un nodo xml
function aniadirNodo(nodoPadre, nombreNodo, valorNodo) {
	var nuevoNodo = nodoPadre.ownerDocument.createElement(nombreNodo);
	asignaValor(nuevoNodo, valorNodo);
	nodoPadre.appendChild(nuevoNodo);
	return nuevoNodo;
}

//Añade un nuevo atributo a un nodo xml
function aniadirAtributo(nodoPadre,nombreAtributo,valorAtributo) {
	var nuevoAtributo = null;
	if (esExplorer()) {
		nuevoAtributo = nodoPadre.setAttribute(nombreAtributo, valorAtributo);
	} else {
		nuevoAtributo = nodoPadre.ownerDocument.createAttribute(nombreAtributo);
		nuevoAtributo.value = valorAtributo;
		nodoPadre.attributes.setNamedItem(nuevoAtributo);
	}
	
	return nuevoAtributo;
}

//Añade atributos y sus valores a un nodo
function aniadirAtributos(nodoPadre, aAtributos, aValores) {
	for (var i = 0; i < aAtributos.length; i++) {
		if(aValores==null || aValores[i]==null) {
			aniadirAtributo(nodoPadre,aAtributos[i],"");
		} else {
			aniadirAtributo(nodoPadre, aAtributos[i], aValores[i]);
		}
	}
}

//Vuelca los atributos del nodo origen al nodo destino
function volcarAtributos(nodoOrigen, nodoDestino) {
	for (var i = 0;i<nodoOrigen.attributes.length;i++) {
		if(nodoDestino.attributes.getNamedItem(nodoOrigen.attributes(i).nodeName)!=null)
			nodoDestino.attributes.getNamedItem(nodoOrigen.attributes(i).nodeName).text=nodoOrigen.attributes(i).text;
	}
}

//Retorna el valor de un nodo, si no existe retorna null;
function dameValor(node){
	try{
		if(esExplorer()){
			return node.text;
		}else{
			return node.textContent;
		}
	}catch(e){
		return null;
	}
}

//Asigna el valor de un nodo, si no existe retorna null;
function asignaValor(node, valor){
	try{
		if(esExplorer()){
			node.text = valor;
		}else{
			node.textContent = valor;
		}
	}catch(e){
		return null;
	}
}

function eliminarNodo(nodo)
{
     // Se elimina el nodo y se devuelve el nodo eliminado
     return nodo.parentNode.removeChild(nodo);
}

function eliminarNodosHijo(nodo)
{
     // mientras el nodo tenga hijos
    var numHijos = nodo.childNodes.length;
    for (var i = numHijos - 1; i >= 0; i--) {
		var nHijo = nodo.childNodes[i];
		if (nHijo.nodeType == 1) {
			eliminarNodo(nHijo);
		}
    }
}

//Función que convierte los datos
//true - De texto a ASCII
//false - De ASCII a texto
function convertirTexto(texto, conversion){
	var carEspecial = crearCaracteresEspeciales();
	var totalCaracteres = carEspecial.length;
	for (var i=0; i<totalCaracteres; i++)
	{
		if (conversion) {
			texto = eval("texto.replace(/"+carEspecial[i][0]+"/g, \""+carEspecial[i][1]+"\");");
		} else {
			texto = eval("texto.replace(/"+carEspecial[i][1]+"/g, \""+carEspecial[i][0]+"\");");
		}
	}
	return texto;
}

//Función que convierte de texto a ASCII
function convertir_Texto_A_AASCII(texto){
	return convertirTexto(texto, true);
}
//Función que convierte de texto a ASCII
function convertir_AASCII_A_Texto(texto){
	return convertirTexto(texto, false);
}

