/**
		#########################
		# X.A.L.P. Client CORE  #
		#########################
		Xalp Client Core Routine File
		
		Author  : Luigi Di Biasi
		E-mail  : luigi@dibiasi.it
		Require : Javascript/Dom level 1 Compatibile web browser

	    La versione 3.0 non supporta più le chiamate a _xalpRequestRemotePage
	    e _xalpRequestParseXMLPage. Tali funzioni si basavano sull'oggetto Webclient
	    e sono state eliminate. 
	    
	    	       
        Versione 3.0 ANSI + UNICODE Support
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^       
**/

        
        // Contatore delle chiamate effettuate
        var _xalpInvocationC = 0;
        // Contatore delle chiamate in attesa
        var _xalpCallPending = 0;
        // Oggetto [ID_Chiamata]->[timer]
        var _xalpCallArray = new Array();
		
		// Funzione principale. Invoca una funzione remota asincrona.
        function invoke(serviceURI, serviceParam, funct, delay, debug, hideXIPBAR)
		{

		    if (!_checkInvoke(serviceURI, serviceParam, funct, delay, debug, hideXIPBAR)) { return false; }
				return _prepareInvoke(serviceURI, serviceParam, funct, delay, debug, hideXIPBAR);
		}

        // Controlla che la chiamata possa essere effettuata senza problemi.
		function _checkInvoke(serviceURI, serviceParam, funct, delay, debug, hideXIPBAR)
		{
			if(serviceParam.length==null)
			{
					alert("I parametri vanno passati come array con indici di tipo String anche se si tratta di 1 solo parametro!!\n Metodo invoke terminato in modo anomalo");
					return false;					
			} else { return true; }
		}
	 
        // Prepara la chiamata asincrona.
		function _prepareInvoke(serviceURI,serviceParam,funct,delay,debug,hideXIPBAR)
		{
            // Aggiorna il numero chiamata. (Usato per il commit)
		    _xalpInvocationC += 1;

		    // Mostra la barra di attesa. (se no viene passato il parametro hideXIPBAR)
            if (hideXIPBAR==null) _xalp_internal_ShowPBar();

		    // Imposta il gestore del timeout nel caso in cui il servizio non effettui
		    // il commit.
		    if (delay != null)
		    {_xalpRRPTimeoutTimer = setTimeout('_xalpInvokeTimeOut(' + _xalpInvocationC + ')',delay); }
		    else {
		        _xalpRRPTimeoutTimer = setTimeout('_xalpInvokeTimeOut(' + _xalpInvocationC + ')', 1000);
		    }
    
		  	// impostiamo la stringa x il get sul servizio da invocare. 
			serviceParam['_callofTime']=new Date().getSeconds();
			serviceParam['reqN'] = _xalpInvocationC;

			var pArg = "?xalpInvoke=true&auth=8885&funct=" + funct;

			// Utilizza l'header (HEAD) 
			var theHead = document.getElementsByTagName("head").item(0);
			for (tJ in serviceParam) {
			    pArg = pArg + "&" + tJ + "=" + serviceParam[tJ];			
			}

            if (debug!=null)
			    prompt('',serviceURI + pArg);
						
            // Modifica il DOM in modo da richiamare il servizio remoto.
   			var toLoad = document.createElement("script");
			toLoad.setAttribute("language","javascript");
			toLoad.setAttribute("type","text/javascript");
			toLoad.setAttribute("src",serviceURI+pArg);
			toLoad.setAttribute("__xalpServiceCallInvokeId",_xalpInvocationC);
            theHead.appendChild(toLoad);
            _xalpCallPending += 1;


            // Salva il riferimento alla chiamata xalp all'interno dell'array
            // delle chiamate.
            _xalpCallArray[_xalpInvocationC] = new Array();
            _xalpCallArray[_xalpInvocationC]['timer'] = _xalpRRPTimeoutTimer;
            _xalpCallArray[_xalpInvocationC]['script'] = toLoad;
            
			
		}		
            
            // Questa funzione rileva eventuali timeout di chiamate ai servizi remoti
            function _xalpInvokeTimeOut(_callID) {

                // Se scatta questo evento una chiamata è andata in timeout.
                if (_xalpCallArray != null) {
                    if (_xalpCallArray[_callID] != null) {
                        _xalpCallArray[_callID]['timer'] = null;
                    }
                }
                _xalpCallPending -= 1;
                if (_xalpCallPending < 0) _xalpCallPending = 0;
                if (_xalpCallPending == 0) 
                {
                    _xalp__internal_HidePBar();
                }
                _xalp__internal_DeatchScript(_callID);
            }

        
            // Questa funzione permette di cancellare il contenuto dell'elemento passato.
            function CleanDiv(divElement)
            {
                var numOfItem = divElement.childNodes.length;	
		        var tmp;
		        for (j = 0; j < numOfItem; j++) {
		        tmp = divElement.childNodes.item(j);
    		        divElement.removeChild(tmp);
    		    }	    
            }


            // Questa funzione si occupa di pulire la memoria occupata dalle
            // chiamate. Disattiva i timer di timeout per la chiamata su cui
            // e stato effettuato il commit
		    function _commitCall(reqN)
		    {
               		// Disattiva il timeout appena ritorna la chiamata
		        clearTimeout(_xalpCallArray[reqN]);

		        // Determina se nascondere la barra di loading.
	    	        _xalpCallPending -= 1;
        	    if (_xalpCallPending < 0) _xalpCallPending = 0;
        	    if (_xalpCallPending == 0) {_xalp__internal_HidePBar(); }

        	        // Pulisce memoria dallo script di chiamata.
	        	    _xalp__internal_DeatchScript(reqN);
    	        	    
		    }




		    // Funzione interna per effettuare il detach dell'oggetto script
		    // dal dom della pagina
		    function _xalp__internal_DeatchScript(reqN) 
		    {		        
			if (_xalpCallArray!=null) 
			{ 
				if (_xalpCallArray[reqN]!=null) 
				{
		        		var TheHead = document.getElementsByTagName("head").item(0);
				        var ToDelete = _xalpCallArray[reqN]['script'];
			                // Cancella l'elemento di script dalla memoria.
				        if (ToDelete != null) 
					{ 
				       		  TheHead.removeChild(ToDelete); 
			        	}	        
				        // Pulisce memoria
		        		_xalpCallArray[reqN] = null;
				}
			}
		        TheHead = null;ToDelete = null;        
		    }
        


		    // Questa funzione nasconde la barra di attesa se è stata definita all'interno
          	   // dell'applicazione.
		    function _xalp__internal_HidePBar() {
		        var _myWait = document.getElementById("__xalpW32_xalpPageRequestWaitDiv");
		        if (_myWait != null)
		            _myWait.style.visibility = "hidden";
		    }


		    // Questa funzione visualizza la barra di attesa se è stata definita all'interno
		    // dell'applicazione.
		    function _xalp_internal_ShowPBar() {
		        // Visualizza la barra di attesa( se definita all'interno della pagina chiamante)
		        var _myWait = document.getElementById("__xalpW32_xalpPageRequestWaitDiv");
		        if (_myWait != null)
		            _myWait.style.visibility = "visible"; // visibile x mostrare caricamento in corso
		    }
