var scriptToBeExecuted=null;
var objectToBeLoaded=0;
var j4fskipexecution=false;
var afterLoadingScript;
var currentSubmit=null;
var historyCounter=0;
var historyCache=new Hash();
var browserBackCacheSize=6;
var useIframe=false;
var dummyIframeContent;
// initialize ajax enabled form, first time the page is loaded
function initializej4fAjax(form,browserBackCacheSizeParm,dummyIframeContentParm){
	// setting browser history cache size
	if (browserBackCacheSizeParm!=null && browserBackCacheSizeParm!=undefined) browserBackCacheSize=browserBackCacheSizeParm;
	// setting dummi content for request via iframe (fileupload)
	dummyIframeContent=dummyIframeContentParm;
	// setting historyconunter to special value for caching history of first request
	var historyCounter='initj4fAjax';
	// caching first page
	historyCache.set('j4fajax_formId'+historyCounter,form.id);
	var	ajaxId=form.id.substring(0,form.id.length-5);
	var contentText=$(ajaxId+'__jeniaTemplate_container').innerHTML;
	historyCache.set('j4fajax_ajaxId'+historyCounter,ajaxId);
	historyCache.set('j4fajax_contentText'+historyCounter,contentText);
	// standard form initialization
	initializeAjaxForm(form);}
// initialize ajax enabled form, after each ajax request
function initializeAjaxForm(form){
	for(var i=0;i<form.elements.length;i++){
		// if the element is enabled and it has a name
		if(form.elements[i].name!=null&&!form.elements[i].disabled){
			// if the element is an input element
			if (form.elements[i].tagName.toUpperCase()=="INPUT"){
				// if the element is an input submit element 
				if (form.elements[i].type.toLowerCase()=="submit"){
					var el=form.elements[i];
					// saving old onclick event
					if (el.onclickSavej4f==null || el.onclickSavej4f==undefined){
						if (el.onclick==null || el.onclick==undefined)
							el.onclickSavej4f=false;
						else
							el.onclickSavej4f=el.onclick;
						// new onclick event
						el.onclick=function(){
							var el=this;
							currentSubmit=el.name;
							// executing previous onclick
							if (el.onclickSavej4f)
								return ret=el.onclickSavej4f();
							else 
								return true;}}}}}}
	var lis = getObjToBeLoaded(document.documentElement);
	for (var i=0;i<lis.length;i++){
		lis[i].j4floaded=true}}
// executing an ajax request about the included content
// return true if the form have to be submitted via standard http request
// return false if the form have was submitted via ajax
function performj4fajaxrequest(ajaxId,formId,onBeforeLoading,onAfterLoading){
	if (j4fskipexecution) {
		j4fskipexecution=false;
		return true;}
	window.onload=null;
	// executing script before loading
	if (onBeforeLoading!=null){
		eval(onBeforeLoading);}
	// saving script to be executed after loading
	afterLoadingScript=onAfterLoading;
	var form=$(formId);
	var ret=false;
	if (useIframe) {
		useIframe=false;
		// hidden iframe creation 
		var n = formId + '_j4f_iframe';
		var div = $(document.body).insert('<div id="d_'+n+'" style="visibility:hidden;display:none;"></div>');
		var iframe = div.insert('<iframe src="'+dummyIframeContent+'" id="'+n+'" name="'+n+'" style="visibility:hidden;display:none;"></iframe>');
		// set the form target to the new iframe
		form.target=n;
		// submitting the form
//		form.submit();
		ret=true;
	} else {
		// form serialization for ajax request
		var serializedForm = Form.serialize(form,{submit:(currentSubmit==null?false:currentSubmit),hash: false});
		// perform ajax request
		var myAjax = new Ajax.Request(form.action,
		    	{	method: form.method.toLowerCase(), 
		    		contentType: form.encoding,
		    		postBody: serializedForm,
			    	evalScripts: true,
		    		onSuccess: function (transport) {},
					onFailure: function (transport,exc) {
							alert("Unreachable server. ajax failure " + exc);},
					onException: function (transport,exc) {
							alert("Unreachable server. ajax exception " + exc);},
					onComplete: function (transport) {
							ajaxResponse(ajaxId,formId,transport);}});}
	currentSubmit=null;
	return ret;}
// method called from the iframe (if the request was done usig iframe - fileupload)
function iframej4fOnload(ajaxId,formId,contentText) {
	// add response to history
	j4fAddToCache(ajaxId,formId,contentText);
	// via al giro normale
	ajaxResponseContent(ajaxId,formId,contentText);}
// if the server give back an error,the page content is "anonymous",interpreting the page content to view it
function getBodyContent(ctx){
	var ret="";
	var init=0;
	var end=0; 
	// searching for body tag start
	init=ctx.indexOf('<body');
	if (init!=-1){
		// searching for body tag end
		end=ctx.indexOf('</body>');
		var x = ctx.substring(init,end);
		init=x.indexOf('>') + 1;
		if (end!=-1 && init<x.length){
			// this is only the body content
			ret=x.substring(init);
		}else{
			ret="empty " + tagName;}}
	return ret;}
// managing browser back button
function manageAjaxBack(historyCounter){
	// verifying history callback parameter
	// if historyCounter=='' the method was called on initialize of page
	if (historyCounter=='') historyCounter='initj4fAjax';
	else historyCounter=parseInt(historyCounter.substring('j4fajax_historyCounter_'.length),10);
	// keep ajaxId from cache
	var ajaxId=historyCache.get('j4fajax_ajaxId'+historyCounter);
	// if ajaxId is null, we don't have history backpoint into cache, nothing to do...
	if (ajaxId==null) return;
	// keep formId from cache
	var formId=historyCache.get('j4fajax_formId'+historyCounter);
	// keep contentText from cache
	var contentText=historyCache.get('j4fajax_contentText'+historyCounter);
	// updating page with cached context
	ajaxResponseContent(ajaxId,formId,contentText);
}
// add response to history
function j4fAddToCache(ajaxId,formId,contentText) {
	// setting content into cache
	historyCache.set('j4fajax_contentText'+historyCounter,contentText);
	// setting formId into cache
	historyCache.set('j4fajax_formId'+historyCounter,formId);
	// setting ajaxId into cache
	historyCache.set('j4fajax_ajaxId'+historyCounter,ajaxId);
	// adding history pointback
	dhtmlHistory.add('j4fajax_historyCounter_'+historyCounter);
	// managing history cache size
	historyCounter++;
	if (historyCounter>browserBackCacheSize) historyCounter=0;
}
// reading ajax response from transport
function ajaxResponse(ajaxId,formId,transport){
	// having response text
	var contentText=transport.responseText;
	// add response to history
	j4fAddToCache(ajaxId,formId,contentText);
	// managing server response
	ajaxResponseContent(ajaxId,formId,contentText);
}
// managing server response 
function ajaxResponseContent(ajaxId,formId,contentText){
	// if in the request was added the hidden parameter _j4fajaxToBeDeleted we have to delete it
	var r=$('_j4fajaxToBeDeleted');
	if (r!=null){
		if (r!=null && r.parentNode!=null) r.parentNode.removeChild(r);}

	try{
		if (contentText==null || contentText.length==""){
			contentText="<form id='"+ajaxId+"_form'>Unreachable server. Empty message received from server <form/>"
		}else{
			init=contentText.indexOf('<form ');
			if (init==-1) init=contentText.indexOf('<FORM ');
			if (init==-1){
				contentText="<form id='"+ajaxId+"_form'>"+getBodyContent(contentText)+"<form/>";
			}else{
				end=contentText.indexOf('</form>');
				if (end==-1) end=contentText.indexOf('</FORM>');
				if (init>=0 && end>=0 && end>init){
					contentText=contentText.substring(init,end+('</form>'.length));
				}else{
					contentText="<form id='"+ajaxId+"_form'>"+getBodyContent(contentText)+"<form/>";}}}
	}catch (error){
		contentText="<form id='"+ajaxId+"_form'>Unreachable server. Error = " + error + "<form/>";}

	// if the resnponse was valid
	if (contentText!=null){
		// replacing templtate area
		$(ajaxId+'__jeniaTemplate_container').innerHTML=contentText;			
		// managing specials dom elements
		manageObj($(ajaxId+'_form'));}}
// managing specials dom elements
function manageObj(ajaxEle){
	// loading list of object that have to be managed
	var lis = getObjToBeLoaded(ajaxEle);
	for (var i=0;i<lis.length;i++){
		// for each special object,manage it
		manageHtmlObj(lis[i],ajaxEle);}
	// if there are no more special objects,i will execute post loading javascript
	if (objectToBeLoaded==0){
		// if there is a post loading javascript,i will execute it
		if (scriptToBeExecuted!=null){
			try {
				eval(scriptToBeExecuted);
			}catch(scriptToBeExecutederror){alert('error on loadign script : scriptToBeExecuted = ' + scriptToBeExecuted + ' : ' + scriptToBeExecutederror);}
			scriptToBeExecuted=null;}
		// if there is an application post loading javascript,i will execute it
		if (afterLoadingScript!=null){
			try {
				eval(afterLoadingScript);
			}catch(afterLoadingScripterror){alert('error on loadign script : afterLoadingScripterror = ' + afterLoadingScript + ' : ' + afterLoadingScripterror);}}
		initializeAjaxForm(ajaxEle);
		try {
			if (window.onload!=null && window.onload!=undefined)
				window.onload();
		}catch(onloaderror){alert('error on onload script = ' + window.onload + ' : ' + onloaderror);}
		var ifr=$('d_'+ajaxEle.id + '_j4f_iframe');
		if (ifr!=null) ifr.remove();}}
// managing special html dom elements
function manageHtmlObj(obj,ajaxEle){
	// SCRIPT objects are special dom elements,managing
	if (obj.tagName == 'SCRIPT'){
		// it's an embedded script?
		if (obj.src==null || obj.src==''){
			// if the embedded script is not already be loaded?
			if (!obj.j4floaded){
				// creating a new script element
				var script=document.createElement("script");
				if(!Prototype.Browser.IE){
					// in browser differents from IE we have to ...
					txt=obj.innerHTML;
					// inspect for tag content
					if (txt.indexOf("<!--")==0){
						// if tag start with an xml comment,i will remove it
						txt=txt.substring(4);
						txt=txt.substring(0,txt.length-3);}
					// in all cases i need to set the innerHTML
					script.innerHTML=txt;
				}else{
					// in IE we only have to set text
					script.text=obj.text;}
				// setting the new created tag with original properties
				script.type=obj.type;
				script.language=obj.language;
				script.id=obj.id;
				// setting the special properties to understand that the tag was already managed
				script.j4floaded=true;
				obj.j4floaded=true;
				try{
					// trying to replace original element with the new
					obj.parentNode.replaceChild(script,obj);
				}catch(error){
					// if we can't i will put the script into head
					document.getElementsByTagName("head").item(0).appendChild(script);}}
		}else{
			// it's an external script!
			if (!obj.j4floaded){
				// we have to wait for loading
				loadObj(obj,ajaxEle);
				// this method will be called again after loading of external script
				return;}}
	// LINK objects are special dom elements,managing
	}else if (obj.tagName=='LINK'){
		// if the element is not loaded in head
		if (!obj.j4floaded){
			// we have to wait loading
			loadObj(obj,ajaxEle);
			// this method will be called again after loading of external script
			return;}
	// STYLE objects are special dom elements,managing
	}else if (obj.tagName=='STYLE'){
		// it's an embedded style?
		if (obj.href==null || obj.href==''){
			// creating the embedded style inside the re-created form
			ajaxEle.appendChild(obj);
		}else{
			// it's an external script!
			if (!obj.j4floaded){
				// we have to wait for loading
				loadObj(obj,ajaxEle);
				// this method will be called again after loading of external script
				return;}}}}
// loading single special html dom element
function loadObj(oldObj,ajaxEle){
	if (oldObj.parentNode==null) return;
	// searching for all element of the same type to understand if the element (non embedded) is already loaded
	var litip=document.getElementsByTagName(oldObj.tagName.toLowerCase());
	for (var j=0;j<litip.length;j++){
		// removing the old element
		if ((oldObj.tagName=='SCRIPT' && litip[j].src==oldObj.src) ||
			(oldObj.tagName=='LINK' && litip[j].href==oldObj.href) ||
			(oldObj.tagName=='STYLE' && litip[j].href==oldObj.href)){
				if (litip[j].j4floaded) return;}}
	// in browser different from IE only special html dom elements are SCRIPT,loading will update conuter only for these types
	if(!Prototype.Browser.IE){
		if (oldObj.tagName=='SCRIPT')
			objectToBeLoaded++;
	}else{
		objectToBeLoaded++;}
	// we will clone the original obj to load
	var newObj=createObj(oldObj);
	newObj.j4fcontentId=ajaxEle.id;
	Element.remove(oldObj);
	// in the clone we have to set the readystatechange callback event
	newObj.onload=newObj.onreadystatechange=objLoaded;
	// retriving head element
	var head=document.getElementsByTagName('head')[0];
	// for adding cloned element in it,all NON embedded resources will be placed in head
	head.appendChild(newObj);}
// method to clone a special html dom element
function createObj(oldObj){
	if (oldObj.tagName=='SCRIPT'){
		var script=document.createElement("script");
		script.src=oldObj.src;
		script.type=oldObj.type;
		script.language=oldObj.language;
		script.id=oldObj.id;
		return script;
	}else if (oldObj.tagName=='LINK'){
		var link=document.createElement("link");
		link.href=oldObj.href;
		link.type=oldObj.type;
		link.rel=oldObj.rel;
		link.id=oldObj.id;
		return link;
	}else if (oldObj.tagName == 'STYLE'){
		var style=document.createElement("style");
		style.href=oldObj.href;
		style.type=oldObj.type;
		style.id=oldObj.id;
		return style;}}
// callback method for loading of special html dom elements 
function objLoaded(event){
	// if the browser is different from IE
	if(!Prototype.Browser.IE){
		// wich is the element that fire the event?
		var x=event.currentTarget;
		x.j4floaded=true;
		// wich is the event?
		if(event.type=='load'){
			// if the event is load,then decrement the object loading counter and restart special html dom elements managing
			try{
				objectToBeLoaded--;
				manageObj($(x.j4fcontentId));
			}catch(error){}}
	}else{
		// if the browser is IE
		// wich is the element that fire the event?
		if (!event) var event = window.event
		var x=event.srcElement;
		x.j4floaded=true;
		// wich is the event?
		if(x.readyState=='complete' || x.readyState=='loaded'){
			// if the event is loaded or complete,then decrement the object loading counter and restart special html dom elements managing
			try{
				objectToBeLoaded--;
				manageObj($(x.j4fcontentId));
			}catch(error){}}}}
// creating list of object that have to be managed
function getObjToBeLoaded(ajaxEle){
	var ret=new Array();
	var retI=0;
	// in browser differents from IE special elements are also LINK and STYLE
	if(!Prototype.Browser.IE){
		retI=addTypes('link',ret,retI,ajaxEle);
		retI=addTypes('style',ret,retI,ajaxEle);}
	// in all browsers special elements are SCRIPT
	retI=addTypes('script',ret,retI,ajaxEle);
	return ret;}
// adding all elements of specific type into a list
function addTypes(type,ret,retI,ajaxEle){
	var lis=document.getElementsByTagName(type);
	for (var k=0;k<lis.length;k++){
		if (Element.descendantOf(lis.item(k),ajaxEle)){
			ret[retI]=lis.item(k);
			retI++;}}
	return retI;}
// --- start of utility methods ---
// method to submit an onchange inside an ajax region
function onchangeInsideAjax(inputElement) {
	var form=inputElement.form;	
	var formId=form.id;
	var	ajaxId=formId.substring(0,formId.length-5);
	var ret=true; 
	if(form.onsubmit)
		ret=form.onsubmit();
	if (ret==true || ret==undefined) 
		form.submit();
	return false;}
// running a form NOT in the ajax section inside a template section
// after running the form we will execute the script
function runInsideAjaxAndExecute(ajaxId,scripttbe,formId,onBeforeLoading,onAfterLoading){
	scriptToBeExecuted=scripttbe;
	return runInsideAjax(ajaxId,formId,onBeforeLoading,onAfterLoading);}
// running a form NOT in the ajax section inside a template section
function runInsideAjax(ajaxId,formId,onBeforeLoading,onAfterLoading){
	if (formId==null || formId==undefined){
		alert("you have to specify at least 2 parameters in runInsideAjax");
		return false;}
	// getting the form that will be executed inside ajax
	var form=$(formId);
	// if not yet set,i will set the special attributes for ajax requests
	if (form.elements['_j4fajax']==null || form.elements['_j4fajax']==undefined){
		var i=document.createElement("input");
		i.type="hidden";
		i.name="_j4fajax";
		i.id="_j4fajaxToBeDeleted";
		i.value=ajaxId+'_insideAjax';
		form.appendChild(i);
	}else{
		form.elements['_j4fajax'].value=ajaxId;}
	// saving old onsubmit
	if (form.onsubmitAjax==null || form.onsubmitAjax==undefined){
		form.onsubmitAjax=form.onsubmit;
		// forcing new onsubmit
		form.onsubmit=function(){
			return submitInsideAjax(ajaxId,formId,onBeforeLoading,onAfterLoading);}}
	// after execution of the form we need to reset the form
	scriptToBeExecuted="$('"+formId+"').reset();"+(scriptToBeExecuted==null?"":scriptToBeExecuted);
	return true;}
// onsubmit method for runinsideajax function
function submitInsideAjax(ajaxId,formId,onBeforeLoading,onAfterLoading){
	var form=$(formId);
	// restore previous onsubmit
	form.onsubmit=form.onsubmitAjax;
	var ret=true; 
	// executing previous onsubmit
	if (form.onsubmitAjax) 
		ret=form.onsubmitAjax();
	// reset onsubmit saving variable
	form.onsubmitAjax=null;
	if (ret==true || ret==undefined) return performj4fajaxrequest(ajaxId,formId,onBeforeLoading,onAfterLoading);
	else return ret;}
// method to be called for file upload 
function runFileUpload(ajaxId){
	var formId;
	if (ajaxId.indexOf('_form')!=-1) 
		ajaxId=ajaxId.substring(0,ajaxId.length-5);
	formId=ajaxId+'_form';
	var form=$(formId);
	form.encoding="multipart/form-data";
	form.insert('<input type="hidden" id="_j4fajax_iframe" name="_j4fajax_iframe" value="true"/>');
	useIframe=true;
	return true}
// running an extra ajax request
function saveAjaxForExtra(ajaxId,onBeforeLoading){
	// calculating form
	var formId;
	if (ajaxId.indexOf('_form')!=-1) 
		ajaxId=ajaxId.substring(0,ajaxId.length-5);
	formId=ajaxId+'_form';
	var form=$(formId);
	// saving previous onsubmit
	if (form.onsubmitAjax==null || form.onsubmitAjax==undefined){
		form.onsubmitAjax=form.onsubmit;
		form.onsubmit=function(){
			return submitOutsideAjax(ajaxId,formId,onBeforeLoading);}}
	return true;}
// running an extra ajax request
function restoreAjaxForExtra(ajaxId,onAfterLoading){
	// calculating form
	var formId;
	if (ajaxId.indexOf('_form')!=-1) 
		ajaxId=ajaxId.substring(0,ajaxId.length-5);
	formId=ajaxId+'_form';
	// executing script after loading
	if (onAfterLoading!=null && onAfterLoading!=undefined){
		eval(onAfterLoading);}
	initializeAjaxForm($(formId));
	try {
		if (window.onload!=null && window.onload!=undefined)
			window.onload();
	}catch(onloaderror){}	
	return true;}
// running a temnplate form outside ajax section
function runOutsideAjax(ajaxId,onBeforeLoading){
	// calculating form
	var formId;
	if (ajaxId.indexOf('_form')!=-1) 
		ajaxId=ajaxId.substring(0,ajaxId.length-5);
	formId=ajaxId+'_form';
	var form=$(formId);
	form.elements['_j4fajax'].value=ajaxId+'_outsideAjax';
	if (form.onsubmitAjax==null && form.onsubmitAjax==undefined){
		form.onsubmitAjax=form.onsubmit;
		form.onsubmit=function(){
			return submitOutsideAjax(ajaxId,formId,onBeforeLoading);}}
	return true;}
// onsubmit method for runoutsideajax function
function submitOutsideAjax(ajaxId,formId,onBeforeLoading){
	// executing script before loading
	if (onBeforeLoading!=null && onBeforeLoading!=undefined){
		eval(onBeforeLoading);}
	var form=$(formId);
	// restore previous onsubmit
	form.onsubmit=form.onsubmitAjax;
	j4fskipexecution=true;
	var ret=true; 
	// executing previous onsubmit
	if (form.onsubmitAjax) 
		ret=form.onsubmitAjax();
	// reset onsubmit saving variable
	form.onsubmitAjax=null;
	return ret;}
// running a temnplate form into a popup frame
function runIntoPopupFrame(ajaxId,onBeforeLoading,onAfterLoading){
	var formId;
	if (ajaxId.indexOf('_form')!=-1) 
		ajaxId=ajaxId.substring(0,ajaxId.length-5);
	formId=ajaxId+'_form';
	runOutsideAjax(ajaxId,onBeforeLoading,onAfterLoading);
	if (PF_postSub==null)
		PF_postSub="$('"+formId+"').elements['_j4fajax'].value='"+ajaxId+"';"+
					"window.frames['__jeniaPopupFrameTarget'].focus();"+
					"eval('"+onAfterLoading+"');"+
					"try{"+
						"window.top.status='Finished';"+
					"}catch(error){};";
	else
		PF_postSub=PF_postSub+
					"$('"+formId+"').elements['_j4fajax'].value='"+ajaxId+"';"+
					"window.frames['__jeniaPopupFrameTarget'].focus();"+
					"eval('"+onAfterLoading+"');"+
					"try{"+
						"window.top.status='Finished';"+
					"}catch(error){};";}
