//----------------------------------------
//
//	(c)	2008/2009 - THP
//
//	2009.01.28	thp	ajout wrapper
//	2008.04.01	thp	creation
//	2009.01.15	thp	ajout fonctionnalite auto WRAPPER liant chemin et callback
//
//----------------------------------------

function	ajlInit	(ltimeout, linterval)	{	_ajl_init(ltimeout, linterval);	}
function	ajlOnCanceled(fnotifier)		{	window._ajl_notifyCanceled=fnotifier;	}
function	ajlOnChecked(fnotifier)			{	window._ajl_notifyChecked=fnotifier;	}
function	ajlDump	()						{	return _ajl_dump();}

function	ajlQuery(sRequestPage, tRequestParams, penv, ssig)				{	return _ajl_addTransaction(_ajl_wrapperFunction, 'POST', sRequestPage, tRequestParams, penv, ssig);}
function	ajlPost	(fnotifier, sRequestPage, tRequestParams, penv, ssig)	{	return _ajl_addTransaction(fnotifier, 'POST', sRequestPage, tRequestParams, penv, ssig);}
function	ajlGet	(fnotifier, sRequestPage, tRequestParams, penv, ssig)	{	return _ajl_addTransaction(fnotifier, 'GET',  sRequestPage, tRequestParams, penv, ssig);}

function	ajlBatchReset()							{	_ajl_batchReset();}
function	ajlBatchAdd(tRequestParams)				{	_ajl_batchAdd(tRequestParams);}
function	ajlBatchExec(sRequestPage, penv, ssig)	{	_ajl_batchExec(_ajl_wrapperFunction, sRequestPage, penv, ssig);}

function	ajlCancel(itransaction)			{	return _ajl_cancelTransaction(itransaction);	}
function	ajlCancelSigned(ssig)			{	return _ajl_cancelTransaction(_ajl_find(ssig));	}

function	ajlGetChildsCount(proot)		{	return _ajlNodesCount(proot);			}
function	ajlGetChild(proot, spath)		{	return _ajl_getRoot(proot, spath);		}
function	ajlGetData(pnode)				{	return _ajl_getData(pnode);				}
function	ajlGetChildData(proot, spath)	{	var p=ajlGetChild(proot, spath); if (p) return _ajl_getData(p);	return "";}
function	ajlGetAttribute(pnode, skey)	{	return _ajl_getAttribute(pnode, skey);	}

function	ajlAddWrapper(spath, fcallback)	{	_ajl_wrapperAdd(spath, fcallback);		}
function	ajlRemoveWrapper(spath)			{	_ajl_wrapperRemove(spath);				}
function	ajlCapsuleWrapper(fcallbackBegin, fcallbackEnd)	{_ajl_wrapperCaps(fcallbackBegin, fcallbackEnd);}


//----------------------------------------

var _ajl_code			=	0;
var _ajl_itransaction	=	0;
var _ajl_maxtransactions=	20;		//	nb	de transactions //
var	_ajl_timeOut		=	10000;	//	10 sec de timeout par defaut
var _ajl_ttransactions	=	false;
var _ajl_globals		=	this;	//	dans un contexte _ajl_globals
var	_ajl_notifyCanceled	=	false;
var _ajl_notifyChecked	=	false;
var	_ajl_timeInterval	=	500;	//	intervalle de controle

var _ajl_wrapperOnEvent	=	new Array();	//	wrapper de messages
var	_ajl_wrapperOnBegin	=	false;
var	_ajl_wrapperOnEnd	=	false;

//----------------------------------------

function	ajlParam(sname, svalue)
{
	this.name = sname;
	this.value = svalue;
}

//----------------------------------------

function	_ajl_init(ltimeout, linterval)
{
var i;

	if (ltimeout)	_ajl_timeOut = ltimeout;
	if (linterval)	_ajl_timeInterval = linterval;

	_ajl_ttransactions	=	new Array(_ajl_maxtransactions);

	for(i=0; i<_ajl_maxtransactions; i++) _ajl_ttransactions[i] = new _ajl_TransObject();
	
	setInterval ("_ajl_cleanDeath()", _ajl_timeInterval);
}

//----------------------------------------

function	_ajl_TransObject()
{
	this.m_fnotifier	=	false;
	this.m_ptransaction	=	false;
	this.m_penv			=	false;
	this.m_ldatestart	=	0;
	this.m_ldateend		=	0;
	this.m_bpending		=	0;
	this.m_request		=	"";
	this.m_signature	=	"";
}

//----------------------------------------

function	_ajl_dump()
{
var i;
var sdump;
var ldateend, ldatestart, lduration;
var pdate	=	new Date();
var ldate	=	pdate.getTime();

	sdump = "<table border=1 width=100%>";
	sdump += "<tr><td width=50>code</td><td width=120>date</td><td width=120>duree</td><td width=70>etat</td><td>requete</td></tr>";

	for(i=0; i<_ajl_maxtransactions; i++)
	{
		ldateend	= _ajl_ttransactions[i].m_ldateend;if(ldateend<=0)ldateend = ldate;
		ldatestart	= _ajl_ttransactions[i].m_ldatestart;if(ldatestart<=0)ldatestart = ldate;
		lduration	= ldateend - ldatestart;
		
		sdump	+=	"<tr>";
		sdump	+=	"<td>"+(_ajl_ttransactions[i].m_signature)+"</td>";
		sdump	+=	"<td align=right>"+(_ajl_ttransactions[i].m_ldatestart)+"</td>";
		sdump	+=	"<td align=right>"+(lduration)+" ms </td>";
		sdump	+=	"<td align=center>"+(_ajl_ttransactions[i].m_bpending	? 'pending':'-')+"</td>";
		sdump	+=	"<td>"+(_ajl_ttransactions[i].m_request)+"</td>";
		sdump	+=	"</tr>";
		
	}
	sdump += "</table>";
	return sdump;
}

//----------------------------------------

function	_ajl_cleanDeath()
{

var itransaction;
var pdate	=	new Date();
var ldate	=	pdate.getTime();
var ldateend, ldatestart, lduration;
var ncanceled = 0;

	for(itransaction=0; itransaction < _ajl_maxtransactions; itransaction++)
	{
		ldateend	= _ajl_ttransactions[itransaction].m_ldateend;		if(ldateend<=0)		ldateend = ldate;
		ldatestart	= _ajl_ttransactions[itransaction].m_ldatestart;
		lduration	= ldateend - ldatestart;

		if (_ajl_ttransactions[itransaction].m_bpending && lduration>_ajl_timeOut)
		{
		
			_ajl_cancelTransaction(itransaction);
			ncanceled ++;
		}
	}

	if (ncanceled)
	if (window._ajl_notifyCanceled)	window._ajl_notifyCanceled();
	if (window._ajl_notifyChecked)	window._ajl_notifyChecked();
}

//----------------------------------------

function	_ajl_createThread(fnotifier, penv, ssig)
{
var itrans;
var strans;
var pdate	=	new Date();
var ntest=100;

	while ((ntest--) && (_ajl_ttransactions[_ajl_itransaction].m_bpending))
	{
		_ajl_itransaction = (_ajl_itransaction+1) % _ajl_maxtransactions;
	}
	if (_ajl_ttransactions[_ajl_itransaction].m_bpending) return -1;

	itrans = _ajl_itransaction;
 
	_ajl_globals.ptrans= false;//_ajl_ttransactions[itrans].m_ptransaction; recup de trans ne marche pas
	if (!_ajl_globals.ptrans)
	{
		if (window.XMLHttpRequest) 
		{
			_ajl_globals.ptrans = new XMLHttpRequest();
		}
		else if (window.ActiveXObject) 
		{
			_ajl_globals.ptrans = new ActiveXObject("Microsoft.XMLHTTP");
			try 
			{
				_ajl_globals.ptrans = new ActiveXObject("Msxml2.XMLHTTP");
			} 
			catch (e) 
			{
				_ajl_globals.ptrans = new ActiveXObject("Microsoft.XMLHTTP");
			}   
		}
		if (!_ajl_globals.ptrans)
		{
			return false;
		}
	}
	 

	_ajl_ttransactions[itrans].m_bpending	=	1;
	_ajl_ttransactions[itrans].m_fnotifier	=	fnotifier;
	_ajl_ttransactions[itrans].m_ptransaction=	_ajl_globals.ptrans;
	_ajl_ttransactions[itrans].m_penv		=	penv;
	_ajl_ttransactions[itrans].m_ldatestart	=	pdate.getTime();
	_ajl_ttransactions[itrans].m_ldateend	=	-1;
	_ajl_ttransactions[itrans].m_request	=	"";
	_ajl_ttransactions[itrans].m_signature	=	ssig;
	
 	_ajl_itransaction = (_ajl_itransaction+1) % _ajl_maxtransactions;
	
	_ajl_globals.eval ( "_ajl_ttransactions["+itrans+"].m_ptransaction.onreadystatechange = function () {_ajl_notifier ( "+itrans+" ) ;};" );
    return itrans;
}

//----------------------------------------

function _ajl_find(ssig)
{
	return -1;
}
//----------------------------------------

function	_ajl_cancelTransaction(itransaction)
{
	if (itransaction>0 && _ajl_ttransactions[itransaction].m_bpending)
	{
		var pdate	=	new Date();

		_ajl_ttransactions[itransaction].m_ptransaction.abort();
		_ajl_ttransactions[itransaction].m_ptransaction	=	false;
		_ajl_ttransactions[itransaction].m_ldateend		=	pdate.getTime();
		_ajl_ttransactions[itransaction].m_bpending		=	0;
	}
}

//----------------------------------------

function	_ajl_addTransaction(fnotifier, sRequestType, sRequestPage, tRequestParams, penv, ssig)
{
var itrans, ptrans;
var sparams="";
var iparams;
var pdate	=	new Date();

	sparams = "dte=" + pdate.getTime();

	if (tRequestParams)
	{
		for(iparam=0; iparam < tRequestParams.length; iparam++)
		{
			sparams	+=	"&" + tRequestParams[iparam].name + "=" + escape(tRequestParams[iparam].value);
		}
	}
	
//debug ( sRequestPage + "?" + sparams);

	itrans = _ajl_createThread(fnotifier, penv, ssig);
	if (itrans<0) return -1;
	
	_ajl_ttransactions[itrans].m_request = sRequestPage;
	
	
	if (sRequestType.toLowerCase() == "get")
	{
		_ajl_ttransactions[itrans].m_ptransaction.open("GET", sRequestPage + "?" + sparams ,true);
		_ajl_ttransactions[itrans].m_ptransaction.send(null);
   	}
	else
	if (sRequestType.toLowerCase() == "post")
	{
		_ajl_ttransactions[itrans].m_ptransaction.open("POST", sRequestPage, true); 
		_ajl_ttransactions[itrans].m_ptransaction.setRequestHeader("Method", "POST " + sRequestPage + " HTTP/1.1");
		_ajl_ttransactions[itrans].m_ptransaction.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		_ajl_ttransactions[itrans].m_ptransaction.send(sparams); 
	}
	else
	{
		return -1;
	}		
	
	return iparam;	
}

//----------------------------------------

function _ajl_notifier(itrans) 
{		
var pdate	=	new Date();

	// On ne fait quelque chose que si on a tout reçu et que le serveur est ok


	if(_ajl_ttransactions[itrans].m_ptransaction.readyState == 4 && _ajl_ttransactions[itrans].m_ptransaction.status == 200)
	{
		
		_ajl_ttransactions[itrans].m_ldateend	=	pdate.getTime();
		var pxml = _ajl_ttransactions[itrans].m_ptransaction.responseXML;
		if(pxml && pxml.documentElement ) pxml= cleanXML(pxml.documentElement);
		_ajl_ttransactions[itrans].m_fnotifier(
				_ajl_ttransactions[itrans],
				pxml,
				_ajl_ttransactions[itrans].m_ptransaction.responseText
			);
		_ajl_ttransactions[itrans].m_ptransaction	=	false;
		_ajl_ttransactions[itrans].m_bpending		=	0;
	}	
	else
	{
		//_ajl_ttransactions[itrans].m_bpending		=	0;
		//_ajl_ttransactions[itrans].m_ptransaction	=	false;
	}
}

//----------------------------------------
// developpez.com - nettoie DOM : IE et FF different, => arbre different => nettoie
// ex. de la FAQ javascript : |--list |--" " |--tel | |--nom | | |--"abdcef" | |--id | |--"123" |--" " |--tel | |--nom | | |--"xyz" | |--id | |--"124" |--" "
//----------------------------------------

function _xml_clean(o)
{
	if(!o.data.replace(/\s/g,''))	o.parentNode.removeChild(o);
}
function cleanXML(v)
{
	var o,i;
	var t=v.getElementsByTagName('*');
	for(i=0;i<t.length;i++)
	{
		o=t[i].previousSibling;	if(o && o.nodeType==3)	_xml_clean(o);
		o=t[i].nextSibling;		if(o && o.nodeType==3)	_xml_clean(o);
	}
	return v;
}

//----------------------------------------
// parcours arbre donnees
//----------------------------------------

function	_ajl_getName (pxml)
{
	return pxml.tagName;
}
function	_ajl_getRoot (pxml, spath)
{
	var tPath = spath.split('/');
	var iPath = 0;
	var nPath = tPath.length;
	
	if ( tPath[iPath]==pxml.tagName) 
	{
		return _ajlParsePath(pxml, tPath, nPath, iPath+1);
	}
		
	return _ajlParsePath(pxml, tPath, nPath, 0);
}

function	_ajl_getAttribute(pnode, skey)
{
var pattr = pnode.attributes[skey];
	if(pattr) return pattr.nodeValue;
	return false;
}
function	_ajl_getData(pnode)
{
	if (!pnode.childNodes || pnode.childNodes.length!=1)	return "";
	return pnode.childNodes[0].data;
}

function	_ajlNodesCount(pscanNode)
{
	if (!pscanNode.childNodes)			return 0;
	return (pscanNode.childNodes.length);
}

function	_ajlParsePath(pParent, tPath, nPath, iPath)
{
	if (iPath>=nPath)		return pParent;

	var stagName= tPath[iPath].replace(']', '');
	var	tTab	= stagName.split('[');
	var searchTag		= tTab[0];
	var searchIndexed	= (tTab.length>1);
	var searchIndex		= parseInt(tTab[1]);
	var	searchKeyName	= false;
	var searchKeyValue	= false;
	var tKey;
	var pattr;
	
	if (searchIndexed)
	{
		tKey	= tTab[1].split('=');
		if(tKey.length>1)
		{
			searchKeyName	=	tKey[0];
			searchKeyValue	=	tKey[1];
		}
	}
	
	var pscanNode;
	var	pnode = pParent.firstChild;
	var inode = 0;
	while (pnode)
	{	
		if (pnode.tagName==searchTag) 
		{
			if (searchIndexed)
			{
				if(searchKeyName)
				{
					pscanNode = pnode;
					while(pscanNode)
					{
						pattr = pscanNode.attributes[searchKeyName];
						if(pattr && pattr.nodeValue==searchKeyValue)
							return _ajlParsePath(pscanNode, tPath, nPath, iPath+1);				

						pscanNode = pscanNode.nextSibling;
					}
					return 0;
				}
				else
				{
					pscanNode = pnode.parentNode;
					if (!pscanNode.childNodes || searchIndex>=pscanNode.childNodes.length) return 0;
					return _ajlParsePath(pscanNode.childNodes[searchIndex], tPath, nPath, iPath+1);
				}
			}				
			return _ajlParsePath(pnode, tPath, nPath, iPath+1);
		}
		inode++;
		pnode = pnode.nextSibling;
	}
	return 0;	
}

//----------------------------------------
var	_ajl_batchTable;

function	_ajl_batchReset()
{
	_ajl_batchTable	=	new Array();
}
function	_ajl_batchAdd(tRequestParams)
{
	_ajl_batchTable	[_ajl_batchTable.length] = tRequestParams	;
}
function	_ajl_batchExec(pcallback, sRequestPage, penv, ssig)
{
var i, j, n;
var t;
	
	n = 0;
	t = new Array();
	for(i=0; i<_ajl_batchTable.length; i++)
	{
		t[n]	=	 new ajlParam('aj_K['+i+']',1);
		n++;
		for(j=0; j< _ajl_batchTable[i].length; j++)
		{
			t[n]	=	 _ajl_batchTable[i][j];
			t[n].name	=	'aj_V['+i+']['+t[n].name+']';
			n++;
		}
	}
	_ajl_addTransaction(pcallback, 'POST', sRequestPage, t, penv, ssig);
	_ajl_batchReset();
}

//----------------------------------------

function	_ajl_wrapperNode(spath, fcallback)
{
	this.mspath		=	spath;
	this.mfcallback	=	fcallback;
}

function	_ajl_wrapperCaps(fcallbackBegin, fcallbackEnd)
{
	_ajl_wrapperOnBegin	=	fcallbackBegin;
	_ajl_wrapperOnEnd	=	fcallbackEnd;
}

function	_ajl_wrapperAdd(spath, fcallback)
{
	_ajl_wrapperOnEvent[_ajl_wrapperOnEvent.length]	=	new _ajl_wrapperNode(spath, fcallback);
}

function	_ajl_wrapperRemove(spath)
{
	_ajl_wrapperOnEvent[_ajl_wrapperOnEvent.length]	=	false;
}

function	_ajl_wrapperFunction(pTrans, pXml, pText)
{
var i;
var pnode;

	if(_ajl_wrapperOnEvent.length==0) return;
	
	if(_ajl_wrapperOnBegin)_ajl_wrapperOnBegin	();
	for(i=0; i<_ajl_wrapperOnEvent.length; i++)
	{
		if(pnode	= ajlGetChild(pXml, _ajl_wrapperOnEvent[i].mspath))
			_ajl_wrapperOnEvent[i].mfcallback(pnode);
	}
	if(_ajl_wrapperOnEnd)_ajl_wrapperOnEnd	();
}

