/** 
 * Objeto RPCForm que encapsula en formulario con el que se envian
 * los datos al servidor
 *   <!-- Formulario para enviar los datos via RPC al servidor -->
 *   <form name='rpcForm' action='<%=XMLProperties.getProperty("p03","rpcDispatcher/url")%>' method='post'>  
 *       <input type='hidden' name='xmlRPC' value=''/>				<!-- Datos a enviar al servidor -->
 *       <input type='hidden' name='xmlRPCProtocolData value=''/>	<!-- Datos de protocolo (otros datos) -->
 *		 <input type='hidden' name='RPCToken' value=''/>			<!-- Token -->
 *       <iframe name='hiddenIFrame' width='0' height='0'></iframe> <!-- Iframe oculto de comunicacion -->
 *   </form>
 */
function RPCForm(formName) {
	//Atributos:
        var oForm;	// El form html con el que se hace la comunicacion rpc
        var arrayProtolData;	// Datos de protocolo (son simplemente pares (nombre:valor) que se envian
        						// al servidor como XML
	//Métodos:       
        this.sendRPCCall = RPCForm_sendRPCCall;	//Métodos de envio de datos al servidor.    
       	this.addProtocolData = RPCForm_addProtocolData;		// Añade un dato de protocolo a la llamada RPC

	// Inicializacion
		if (formName == null) {
			alert("RPCForm(): El nombre del form no es valido");
			return;
		}
		this.oForm = document.all(formName);
		if (this.oForm == null) {
			alert("RPCForm():No se ha definido el formulario '" + formName + "' revisa el codigo html e incluye el xtag:rpcForm con el atributo name='" + formName + "'");
			return;
		}
		if (this.oForm.tagName != "FORM") {
			alert("RPCForm(): " + formName + " no es un formulario. Revisa el codigo html");
			return;
		}
}
/**
 * Envia la llamada rpcCall al servidor y el resultado se 
 * muestra en target 
 */
function RPCForm_sendRPCCall(rpcCall,target) {
	if (rpcCall == null) alert("RPCForm:sendRPCCall():La llamada RPC es nula..");
	// Obtener la llamada RPC
	this.oForm.xmlRPC.value = rpcCall.toXML();
	if (target != null) this.oForm.target = target;
	// Obtener los datos de protocolo
	if (this.arrayProtocolData != null) {
		var strProtocol = "<?xml version='1.0' encoding='ISO-8859-1'?><map>";
		for (var i=0; i < this.arrayProtocolData.length; i++) 
			strProtocol += this.arrayProtocolData[i].toXML();
		strProtocol += "</map>";
		this.oForm.xmlRPCProtocolData.value = strProtocol;
	}
	this.oForm.submit();
	this.oForm.target = "";	// Volver a poner el target a la posicion inicial
}
/**
 * Añade un elemento RPCProtocolData
 */
function RPCForm_addProtocolData(newNombre,newValor) {
	var oRPCProtocolData = new RPCProtocolData(newNombre,newValor);
	if (oRPCProtocolData != null) {
		if (this.arrayProtolData == null) this.arrayProtocolData = new Array();
		this.arrayProtocolData[this.arrayProtocolData.length] = oRPCProtocolData;
	}
}
//____________________________________________________________________________________\\
/** 
 * Objeto RPCProtocolData
 * Es simplemente un par de valores (nombre:valor) con datos de protocolo de la 
 * llamada RPC
 */
function RPCProtocolData(newNombre,newValor) {
	// Atributos 
		var nombre;		// Nombre de la propiedad
		var valor;		// Valor de la propiedad
	// Inicializacion
		if (arguments.length != 2 || newNombre == "") {
			alert("RPCProtocolData: El nombre o el valor no son validos");
			return null;
		}
		this.nombre = newNombre;
		this.valor = newValor;
	// Funciones
		this.toXML = RPCProtocolData_getXML;
}
function RPCProtocolData_getXML() {
	var strXML = "";
	strXML += "<" + this.nombre;
	if (this.valor == null || this.valor.length == 0) {
		strXML += "/>";
	} else {
		strXML += ">" + this.valor + "</" + this.nombre + ">";
	}
	//alert(strXML);
	return strXML; 
}



//____________________________________________________________________________________\\
/**
 * JavaScript para crear llamadas a funcion RPC con el formato XML:
 * <rpcCall module='____'>
 *      <function name='____'>
 *          <param name='___' type='___'><![CDATA[ ______ ]]</param>
 *          <param name='___' type='___'><![CDATA[ ______ ]]</param>
 *          .........
 *      </function>
 * </rpcCall>
 */

//***********************************************************************************//
//   Clase functionElement.  
//***********************************************************************************//
function  RPC (newModuleName) {
  //Atributos:
        var functionArray;
		var moduleName;
		
		// Inicializacion
		this.functionArray = new Array();
		if (newModuleName == null) {
			this.moduleName = "";
		} else {
			this.moduleName = newModuleName;
       	}
  //Métodos:       
        //Métodos de manejo de funciones.
        this.addFunction = RPC_addFunction;
        this.getFunctionAt = RPC_getFunctionAt;
        this.removeFunction = RPC_removeFunction;  
        this.getFunctionsCount = RPC_getFunctionsCount; 
        
        
        //Métodos para el manejo del RPC     
        this.getModuleName = RPC_getModuleName;
        this.setModuleName = RPC_setModuleName;
        this.toXML = RPC_getXMLRPCElement;
}
 


 
// Nombre del modulo
function RPC_getModuleName() {
   return this.moduleName;  
}   
function RPC_setModuleName(inModuleName){
   this.moduleName = inModuleName;  
}
 
// Numero de funciones de la llamada
function RPC_getFunctionsCount() {  
    return this.functionArray.length;
}
 
// Funcion en la posicion 
function RPC_getFunctionAt(pos){
    return this.functionArray[pos];
}
 
// Introducir función en la llamada
function RPC_addFunction(element){
   this.functionArray[this.functionArray.length] = element;
}
 
// Eleminar función de la llamada
function RPC_removeFunction(element){
	 var pos=0;
	 var encontrado=false;
	 var itemArrayNew = new Array(this.functionArray.length-1);
	 for(i=0;i< this.functionArray.length;i++) {
		 if( this.functionArray[i]!= element) {
			 itemArrayNew[pos]=this.functionArray[i];
			 pos++;    
		 } else encontrado=true;
	}
}
  
  
// Obtener el XML de la llamada
function RPC_getXMLRPCElement() {
	var listaFuncionesElement = "";
	var strXML = "<?xml version='1.0' encoding='ISO-8859-1'?>" ;

	for (i=0; i<this.functionArray.length; i++)  
            listaFuncionesElement +=  this.functionArray[i].toXML();
	
	//Crear el documento XML que contendrá la llamada RPC	
	strXML += "<rpcCall module='" + this.moduleName + "'>";
	strXML +=   listaFuncionesElement;
	strXML += "</rpcCall>";
	//alert(strXML);
	return strXML; 
}          


//***********************************************************************************//
//   Clase FunctionElement.  
//***********************************************************************************//
 
function FunctionElement(newFunctionName) {
  //Atributos:
        var listaParams;
        var name;
        
  //Inicializacion
        this.listaParams = new Array();
        if (newFunctionName == null) {
        	this.name = "";
        } else {
        	this.name = newFunctionName;
        }
        
  //Métodos: 
        this.addParam = FunctionElement_addParam;
        this.getParamAt = FunctionElement_getParamAt;
        this.removeParam = FunctionElement_removeParam;  
        this.toXML = FunctionElement_getXMLFunctionElement;
        this.getName = FunctionElement_getFunctionName;
        this.setName = FunctionElement_setFunctionName;
 
}


// Nombre de la funcion
function FunctionElement_getFunctionName() {
    return this.name;
}
function FunctionElement_setFunctionName(inName) {
    this.name = inName;
}
 
//Metodo  elementAt de la Clase FunctionElement.
function FunctionElement_addParam(element) {	
    this.listaParams[this.listaParams.length] = element;
}
// Parametro en la posicion 
function FunctionElement_getParamAt(pos){
    return this.listaParams[pos];
}
 
// Elimina un paramtero de la funcion
function FunctionElement_removeParam(element) {
     var pos=0;
     var encontrado=false;
     var itemArrayNew = new Array(this.listaParams.length-1);
     for(i=0;i< this.listaParams.length;i++){
             if( this.listaParams[i]!= element){
                     itemArrayNew[pos]=this.listaParams[i];
                     pos++;    
             }else encontrado=true;
    }
}

// Devuelve el XML de la funcion 
function FunctionElement_getXMLFunctionElement() {
    var listaXMLParams="";
    
    for (i=0;i<this.listaParams.length;i++)
        listaXMLParams += this.listaParams[i].toXML();
        
   return "<function name='" + this.name +"'>" + listaXMLParams + "</function>" 
 }
     

//***********************************************************************************//
//   Clase Parametro.  
//***********************************************************************************//
    
function Parametro(name,type,value) {   
       var name;
       var type;
       var value   
    
  //Constructor
        this.name = name;
        this.type = type;
        this.value = value;
  //Metodos
        this.getName = Parametro_getParamName;
        this.setName = Parametro_setParamName;
        this.getType = Parametro_getParamType;
        this.setType = Parametro_setParamType;
        this.getValue = Parametro_getParamValue;
        this.setValue = Parametro_setParamValue;
        this.toXML = Parametro_getXMLParamElement;
}
       
// Devuelve el Parámetro según la Sintaxis XML.        
function Parametro_getXMLParamElement() {
    // OJO!! Devolver siempre envuelto en CDATA por lo que pueda pasar
	//return "<param name='"+ this.name + "' type='" + this.type + "'>" + "<![CDATA[" + this.value + "]]>" + "</param>"    
	return "<param name='"+ this.name + "' type='" + this.type + "'>" + this.value + "</param>"		
}  

// Devuelve el nombre del nombre del parametro
function Parametro_getParamName() {
    return this.name;
}
function Parametro_setParamName(inName) {
    this.name = inName;
}

// Devuelve el tipo del parametro
function Parametro_getParamType() {
    return this.type;
}
function Parametro_setParamType(inType) {
	this.type = inType;
}

// Devuelve el valor del parametro
function Parametro_getParamValue() {
	return this.value;
}
function Parametro_setParamValue(inValue) {
	this.value = inValue;
}







// EJEMPLO DE USO//


function  ejemploRPC(){
	alert("Pulse intro para construir la llamada RPC.....");
	
	var funcion1 = new FunctionElement("funcion1"); 
	funcion1.addParam( new Parametro("Parametro1","integer","25") );
	funcion1.addParam( new Parametro("Parametro2","float","25.55") );
	
	var funcion2 = new FunctionElement("funcion2"); 
	funcion2.addParam( new Parametro("Parametro3","String","Parametro2") );
	funcion2.addParam( new Parametro("Parametro4","boolean","true") );
	
	var rpcCall = new RPC("moduloX");   
	rpcCall.addFunction(funcion1);
	rpcCall.addFunction(funcion2);
	
	alert (rpcCall.toXML());
	document.formulario.hiddenRPC.value = rpcCall.toXML();  
}               