//Copyright (c) 2004-2008 Anastasis Societa' Cooperativa,Bologna,Italy - www.anastasis.it
//	This copyright notice must stay intact for use.

function Anastasis()
{		
	//--------- funzioni "private" usate solo dal costruttore -------------//
	var getBaseUrl=function()
	{
		var ss=document.getElementsByTagName("script");
		for(var index=0; index<ss.length; index++) 
		{
			if(ss[index].src && ss[index].src.match(/Anastasis\.js/i))
			{
				try //Mozilla
				{
					return "/"+ss[index].src.match(/.*:\/\/[\.\w\d-]*\/(.*)Anastasis\.js/i)[1];
				}catch(e) //IE
				{
					try
					{
						var url=ss[index].src.match(/(.*)Anastasis\.js/i)[1];
						//L'url potrebbe essere relativo, dobbiamo farlo assoluto
						if(url && url.match(/^\.\./)) 
						{
							var dove=window.location.toString();
							dove=dove=dove.match(/(.*)\/.*/);
							if(dove &&  dove[1])
								url=dove[1]+"/"+url;
						}
						return url;
					}catch(e){alert("Impossibile inizializzare base_url"); return "";}
				}
			}
		}
	}
	
	var identifyBrowser=function(anastasis)
	{
		var agt = navigator.userAgent.toLowerCase();
	
		// Internet Explorer
		if ( agt.indexOf("msie") != -1 && agt.indexOf("mac") == -1 && agt.indexOf("opera") == -1 )
		{
			var sBrowserVersion = navigator.appVersion.match(/MSIE (.\..)/)[1] ;
			if ( sBrowserVersion >= 5.5 ) anastasis.is_ie=true;
			if ( sBrowserVersion >= 7 ) anastasis.is_ie7=true;
		}
	
		// Gecko - Mozilla Firefox (Opera 9 tries to behave like Gecko at this point).
		if (navigator.product == "Gecko" && navigator.productSub >= 20030210 && !( typeof(opera) == 'object' && opera.postError ) )
			anastasis.is_gecko=true;
	}
	
	//-------------variabili------------------//
	this.is_ie=false;
	this.is_ie7=false;
	this.is_gecko=false;
	identifyBrowser(this);	
	this.base_url=getBaseUrl();	
	if(window.location.href.match(/(https?:\/\/[^\/]+\/).*/)) this.domain=window.location.href.match(/(http:\/\/[^\/]+\/).*/)[1];
	if(window.location.href.match(/https?:\/\/[^\/]+\/[^\/]+\/.*/)) this.servletContext=window.location.href.match(/https?:\/\/[^\/]+\/([^\/]+)\/.*/)[1];	
	this.systemScripts=new Array();
		
	this.ajax=new Anastasis.Ajax();	
	//----------------------------------------//
		
	var me=this;
	//this.loadScript("Utils",function(){me.utils=new Anastasis.Utils();},true);
	this.syncLoadScript("Utils",true);
	this.utils=new Anastasis.Utils();
	this.syncLoadScript("Dialog",true);			
}


/**
 * Carica uno script; a caricamento avvenuto esegue l'azione passata onload.
 * Problema: IE non supporta il parametro onload degli script --> bisogna caricare gli script con Ajax!
 * @param src String; l'indirizzo dello script (o solo il nome se è di sistema - cioè nella stessa cartella di questo js)
 * @param onload Function; una funzione di callback
 * @param system Boolean; specifica se è uno script di sistema oppure no
 */
Anastasis.prototype.loadScript=function(src,onload,system)
{		
	
	//Se il file è già stato caricato, ci sarà l'elemento corrispondente --> fine
	for(var i in this.systemScripts)
		if(this.systemScripts[i]==src) return;			
	
	this.systemScripts.push(src);
	
	if(system) src=this.base_url+src+".js";
	
	/*
	var head = document.getElementsByTagName("head")[0];
	var script = document.createElement("script");
	script.type = "text/javascript";
	script.src = src;
	script.onload = onload;
	head.appendChild(script);
	*/
	
	var onReceived=function(text)
	{		
		try{eval(text);} catch(e){alert("Anastasis.loadScript-onReceived\n"+src+"\n"+e+"\n"+text);}
		if (typeof onload == "function") onload();
	}
		
	this.ajax.send(new Object(),src,"GET",false,true,onReceived);
	
}

Anastasis.prototype.loadScriptSequence=function(scripts,callback,system)
{
	var questo=this;
	if(scripts.length==1)
		this.loadScript(scripts[0],callback,system);
	else
	{
		var next=[];
		for(var index=1; index<scripts.length; index++) 
		{
			next[index-1]=scripts[index];
		}		
		this.loadScript(scripts[0],function(){questo.loadScriptSequence(next,callback,system);},system);
	}			
}


Anastasis.prototype.syncLoadScript=function(src,system)
{
	if(system) src=this.base_url+src+".js";	
	
	text=this.ajax.send(new Object(),src,"GET",false,false);
	eval(text);
	
}

Anastasis.prototype.loadStyle = function(url) 
{		
	var head=document.getElementsByTagName("head")[0];
	var link = document.createElement("link");
	link.type = "text/css";
	link.rel="stylesheet";
	link.href=url;
	head.appendChild(link);	
}



//-------------------------------------------------//
/**
 * Classe Ajax.
 * Gestisce la comunicazione Ajax; espone un solo metodo: send.
 */
Anastasis.Ajax=function ()
{
	this.iframe=null;
	this.iframeActionQueue=new Array();
	this.iframePostQueue=new Array();
	this.iframeWaitingForReply=false;
}

//------------GLOBAL FUNCTIONS-------------------------------//

Anastasis.Ajax.selectSingleNode=function(xmlElement,node)
{	
	node=node.split(/\//);		
	var currentElement=xmlElement;
	for(var i=0;i<node.length;i++)
	{
		if(!currentElement) break;
		var child=currentElement.firstChild;	
		if(!child) 	currentElement=null;
		while(child)
		{						
			if(child.tagName && child.tagName==node[i])
			{
				currentElement=child;
				break;
			}
			else 
			{ 
				currentElement=null;
			}
			child=child.nextSibling;
		}	
	}		
	return currentElement;
	
}

Anastasis.Ajax.getText=function(xmlElement)
{
	if(xmlElement.textContent)			//Mozilla
		return xmlElement.textContent;
	if(xmlElement.text) 				//IE
		return xmlElement.text;		
	else if(xmlElement.firstChild && xmlElement.firstChild.nodeType==4)
	{
		if(xmlElement.firstChild.textContent)			//Mozilla
			return xmlElement.firstChild.textContent;
		if(xmlElement.firstChild.text) 
			return xmlElement.firstChild.text;		//IE
	}
	else if(xmlElement.firstChild && xmlElement.firstChild.nodeType==8)	//Problema di Mozilla che vede CDATA come commenti
	{
		if(xmlElement.firstChild.textContent)			//Mozilla
			return xmlElement.firstChild.textContent.replace(/^\[CDATA\[/,'').replace(/\]\]$/,'');		
	}
}

//---------------------------METODI-PUBBLICI---------------------------//
/**
* Invio sincrono o asincrono di dati via XMLHttp; i primi due parametri sono obbligatori, gli altri opzionali
* Se è sincrono, restituisce l'output della pagina receiver sotto forma di testo
* @param param Object; param[id]=contenuto, dove id è l'id che avrà nella queryString
* @param receiver String; l'indirizzo a cui mandarlo
* @param method String; se non specificato è POST
* @param xmldoc Boolean; se true ritona un Document Xml, altrimenti una semplice stringa
* @param async Boolean; asincrono? se false non ritorna nulla!
* @param callback Function; se il metodo è asincrono, la funzione che gestisce l'arrivo della risposta (opzionale)
*/
Anastasis.Ajax.prototype.send=function (param,receiver,method,xmldoc,async,callback)
{
  if(method!="GET" && method!="POST") method="POST";
  try
  {             
    var xmlHttp=this.getSender();

	//Apre la "connessione"
    xmlHttp.open(method,receiver,async);    //(method, url, async)
    if(method=="POST")
    	xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=ISO-8859-1");
    else
    	xmlHttp.setRequestHeader("Content-Type","text/plain; charset=ISO-8859-1");
    
    
    //Compone la richiesta da inviare
    var qs="";
    var tmp;
    var primo=false;
    for(var par in param)
    {
      if(!primo) primo=true; else qs+="&";    
      tmp=encodeURIComponent(param[par]); //Encode con tutti i % 
      tmp=tmp.replace(/&/g,"%26");   //Sostituisce gli &, perrhcè encodeURI non lo fa      
      qs+=par+"="+tmp; //Attenzione alla sostituzione degli &!!!
    }        
    
    if(async)
    {
    	var ajax=this;
    	if(xmldoc)
	    	xmlHttp.onreadystatechange=function()
	    		{	    			
	    			if(xmlHttp.readyState==4 && callback)
	    				callback(xmlHttp.responseXML);
	    		}
	    else
	    	xmlHttp.onreadystatechange=function()
	    		{
	    			if(xmlHttp.readyState==4 && callback)
	    				callback(xmlHttp.responseText);
	    		}
    }
    
    xmlHttp.send(qs);
    
    if(!async)
    {
	    var response;
	    if(xmldoc)
	    	{
	    		var contentType=xmlHttp.getResponseHeader("Content-Type");
	    		//contentType=contentType.toLowerCase();
	    		if(!(contentType && (contentType.match(/application\/xml/) || contentType.match(/text\/xml/))))
	    			{
	    				this.errore("send","Si richiedeva una risposta XML ma il Content-Type dichiarato non corrisponde.\nContent-type: "+contentType+"\nText: "+xmlHttp.responseText);
	    				//prova comunque a parserizzarla...
	    				response=Anastasis.Utils.parseXML(xmlHttp.responseText);
	    			}
	    		else
		    		response = xmlHttp.responseXML;
	    	}
	    else
	    	response = xmlHttp.responseText;
	    return response;
    }   
    
  }catch(err){this.errore("send",err);}
}

/**
 * Funzione che invia un form in background.
 * Quando riceve la risposta, la passa alla funzione di callback che gli viene passata.
 * NB: l'oggetto passato alla funzione di callback, nel caso che la risposta sia xml,
 * 		è un oggetto XMLElement già parserizzato. In tutti gli altri casi è una semplice stringa.
 * 
 * @param id_form l'id del form da inviare
 * @param callback la funzione di callback chiamata passandole la risposta come primo parametro
 */

Anastasis.Ajax.prototype.sendForm=function(id_form,callback)
{
	var form=document.getElementById(id_form);
	this.createIFrame();
	form.target=this.iframe.name;	
	this.iframeActionQueue.push(function(rep){callback(rep);});
	this.doSendForm(form);
}



//---------------------------METODI-PRIVATI---------------------------//

/*
 * Crea un nuov oggetto xmlHTTP (va rifatto ogni volta)
 */
Anastasis.Ajax.prototype.getSender=function ()
{
	var xmlHttp=null;
	
	if(window.XMLHttpRequest)//IE 7, Firefox
		try
		{
			xmlHttp=new XMLHttpRequest();                            
		}catch(e){this.errore("resetSender",e);}	
	else //IE 6
	{
		try { xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");}         //IE nuovi
	    catch (e) 
	    { try { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); }    //IE vecchi
	      catch (E){this.errore("resetSender",e+"\n"+E);}                        
	    }
	}
	
	return xmlHttp;
}

Anastasis.Ajax.prototype.errore=function(metodo,err)
{
	alert("[Ajax."+metodo+"]\n"+err);
}

Anastasis.Ajax.prototype.createIFrame=function()
{		
		if(this.iframe){ return; }
		
		var iframe = null;
		
		var ifrstr = '<iframe name="anastasis_ajax_iframe" src="'+anastasis.base_url+'blank_src.html" onload="parent.anastasis.ajax.onloadedIFrame();">';
		var div=document.createElement("div");
		div.innerHTML=ifrstr;
		iframe = div.firstChild;		
				
		this.iframe = iframe;

		iframe.style.position = "absolute";
		iframe.style.left = iframe.style.top = "-1000px";
		iframe.style.height = iframe.style.width = "0px";
		
		document.body.appendChild(iframe);
}

Anastasis.Ajax.prototype.doSendForm=function(form)
{
	if(this.iframeWaitingForReply)
		this.iframePostQueue.push(form);
	else
	{
		this.iframeWaitingForReply=true;
		form.submit();
	}
}

Anastasis.Ajax.prototype.onloadedIFrame=function()
{
	var rep="";
		
	if(anastasis.is_ie && this.iframe.contentWindow.document.XMLDocument)			//E' un doc XML e siamo in IE
		rep=this.iframe.contentWindow.document.XMLDocument;
	else if(anastasis.is_gecko && this.iframe.contentWindow.document.firstChild && this.iframe.contentWindow.document.firstChild.nodeType==1)	//E' un doc XML e siamo in Mozilla
	{
			rep=this.iframe.contentWindow.document.firstChild;			
	}
	else
	try
	{
			rep=this.iframe.contentWindow.document.body.innerHTML;
	}	catch(e){}
					
	
	if(rep.match && rep.match("BLANK_ANASTASIS_IFRAME")) return;	//primo caricamento dell'iframe (anche se non avviene sempre)				
	
	try
	{
		var callback=this.iframeActionQueue.shift();
		callback(rep);
	}
	catch(e){this.errore("onloadedIframe",e.toString());}
		
	
	//Ora vediamo se c'erano altri form in attesa di essere inviati e li inviamo
	this.iframeWaitingForReply=false;
	var next=this.iframePostQueue.shift();
	if(next)
		this.doSendForm(next);	
}

//------------CLASS XMESSAGE--------------------------//
/**
 * Wrapper per XMessage in X-serena
 */
Anastasis.XMessage=function()
{
	this.message=null;
	this.type="";
	this.error="";	
}

	//----------GLOBAL FUNCTIONS-----------------------//

/**
 * Funzione statica che ritorna in XMessaggio a partire ad un element XML
 */
Anastasis.XMessage.buildXMessage=function(xmldoc)
{
	msg=new Anastasis.XMessage();

/*	
	alert("QUA");
	var aa=Anastasis.Ajax.selectSingleNode(xmldoc,"serena");
	alert("Node type: "+aa.nodeType);
	alert("TAGNAME: "+aa.tagName);
	return;
*/
	if(xmldoc.tagName!="serena")
	{
		xmldoc=Anastasis.Ajax.selectSingleNode(xmldoc,"serena");
		if(!xmldoc)
		{
			msg.type="error";
			msg.error="XML ricevuto non inizia con tag serena";
			return msg;
		}
	}
	if(!Anastasis.Ajax.selectSingleNode(xmldoc,"service"))
	{
		msg.type="error";
		msg.error="XML ricevuto non contiene serena/service";
		return msg;
	}
	
	msg.message=Anastasis.Ajax.selectSingleNode(xmldoc,"service/_system_message");
	if(!msg.message)
	{
		msg.type="error";
		msg.error="XML ricevuto non contiene service/_system_message";
		return msg;
	}		
	
	msg.type=Anastasis.Ajax.selectSingleNode(msg.message,"type");
	if(msg.type) msg.type=Anastasis.Ajax.getText(msg.type);		
	
	if(msg.type=="error" && Anastasis.Ajax.selectSingleNode(msg.message,"error"))
		msg.error=Anastasis.Ajax.getText(Anastasis.Ajax.selectSingleNode(msg.message,"error"));
		
	return msg;
}

	//-----------PUBLIC FUNCTIONS----------------------//

Anastasis.XMessage.prototype.getContentOf=function(element)
{
	var el=Anastasis.Ajax.selectSingleNode(this.message,element);	
	if(el) return Anastasis.Ajax.getText(el);
	else return null;
}

Anastasis.XMessage.prototype.isErrorMessage=function()
{
	return (this.type=="error");
}

Anastasis.XMessage.prototype.isOkMessage=function()
{
	return (this.type=="ok");
}
//-----------------------------------------------------------------------------//

window.anastasis=new Anastasis();
