new Image().src = 'resources/img/loading.gif';

var AjaxForms = {
	eseguiLoader : function(f) {
		f2=f.bind(window);
		f2();

	},
	hide : function(o, opt) {
		if (opt.hide_mode == 'visibility') {
			o.hide();
		} else if (opt.hide_mode == 'display') {
			o.style.display = 'none';
		}
	},
	show : function(o, opt) {

		if (opt.hide_mode == 'visibility') {
			o.show();
		} else if (opt.hide_mode == 'display') {
			o.style.display = 'block';
		}
	},
	loadingZone : function(opt, state, srcObject) {
		if (srcObject.nodeName.toLowerCase() == "input") {
			srcObject.disabled = false;
		}
		switch (state) {
		case 'loading':
			if (opt.loader_start) {
				this.show($(opt.loader_start), opt);
			}
			if (opt.loader_error) {
				this.hide($(opt.loader_error), opt);
			}
			if (opt.loader_stop) {
				this.hide($(opt.loader_stop), opt);
			}
			break;
		case 'complete':
			if (opt.loader_start) {
				this.hide($(opt.loader_start), opt);
			}
			if (opt.loader_error) {
				this.hide($(opt.loader_error), opt);
			}
			if (opt.loader_stop) {
				this.show($(opt.loader_stop), opt);
			}
			break;
		case 'error':
			if (opt.loader_start) {
				this.hide($(opt.loader_start), opt);
			}
			if (opt.loader_error) {
				this.show($(opt.loader_error), opt);
			}
			if (opt.loader_stop) {
				this.hide($(opt.loader_stop), opt);
			}
			break;
		default:
			alert(state);
			break;
		}

	},
	createUploadIframe : function(id, opt) {

		ele = createNamedElement(document, "iframe", "if_" + id);

		ele.setAttribute("id", "if_" + id);

		ele.name = "if_" + id;

		$(ele).setAttribute("src", 'about:blank');

		if (!opt.debug || opt.debug.length == 0) {
			$(ele).setStyle( {
				display :'none'
			});
		} else {
			$(ele).setAttribute("height", "300");
			$(ele).setAttribute("widht", "300");
		}

		document.body.appendChild(ele);
		f = function(ele, opt) {
			Event.observe(ele, 'load', AjaxForms.frameLoaded
					.bindAsEventListener(ele, opt));

			if (opt.on_complete && typeof (opt.on_complete) == 'function') {
				Event.observe(ele, 'load', opt.on_complete.bindAsEventListener(
						this, ele));
			}
		};
		f.defer(ele, opt);

	},
	frameLoaded : function(src, opt) {

		if (this.contentDocument) {
			radice = this.contentDocument.documentElement;
		} else {
			oDoc = window.frames[this.id].document.documentElement;
			// HTML/BODY/html
			// radice = xmlNewDocument(oDoc.childNodes[1].firstChild);
			radice = oDoc.childNodes[1].firstChild;
		}

		AjaxForms.serverOpt(opt, radice);

		target = AjaxForms.getTarget(opt);

		if (opt.mode == 'remove-childs' || opt.mode == 'replace') {

			if (opt.effect) {

				if(!opt.time){
					opt.time=0.2;
				}
				while (target.hasChildNodes()) {
					target.removeChild(target.firstChild);
				}
				if (opt.mode == 'replace') {
					AjaxForms.putContents(opt, target, radice);
				}

				eval("new Effect." + opt.effect	+ "(target,{duration:opt.time})");

			} else {

				while (target.hasChildNodes()) {
					target.removeChild(target.firstChild);
				}
				if (opt.mode == 'replace') {
					AjaxForms.putContents(opt, target, radice);
				}
			}

		} else if (opt.mode == 'remove-me') {
			if (opt.time) {
				if (opt.effect) {
					eval("new Effect." + opt.effect
							+ "(target,{duration:opt.time})");
				} else {
					new Effect.BlindUp(target, {
						duration :opt.time
					});
				}
				setTimeout( function() {
					if (target)
						$(target).remove();
				}, (opt.time * 1000) + 100);
			} else if (opt.effect && opt.effect != 'none') {
				opt.time = 0.2;
				new Effect.BlindUp(target, {
					duration :opt.time
				});
				setTimeout( function() {
					if (target)
						$(target).remove();
				}, (opt.time * 1000) + 100);
			} else {
				if (target)
					$(target).remove();
			}
		} else if (opt.mode == 'none') {

		} else {
			AjaxForms.putContents(opt, target, radice);

			if (opt.mode == 'replace-me') {
				$(target).remove();
			}
		}
		if (opt.mode != 'none') {
			AjaxForms.evalScripts(radice);
		}

		AjaxForms.runCallbacks(opt,radice);
	},
	rimuoviDiv : function(i) {
		if ($("upl_" + i)) {
			new Effect.BlindUp($("upl_" + i), {
				duration :0.7,
				afterFinish :AjaxForms.rimuoviMainDiv
			});
		}
	},
	rimuoviMainDiv : function() {
		new Effect.BlindUp($('AjaxFormsUploadLoaders'), {
			duration :0.5,
			afterFinish : function() {
				if (AjaxForms.uploads.values().length == 0
						&& $('AjaxFormsUploadLoaders')) {
					$('AjaxFormsUploadLoaders').remove();
				}
			}
		});
	},
	updateStatus : function(iframe_id, requestId, compl) {
		new Ajax.Request(
				'../plugins/transformer/ajaxforms/uploadProgress.php?AjaxFormsR=' + Math
						.random(),
				{
					method :'post',
					parameters :'keys=' + AjaxForms.uploads.keys().join(','),
					onFailure : function(response) {
						AjaxForms.loadingZone(opt, 'error', srcObject);
					},
					onSuccess : function(transport) {

						headers = transport.getHeader("X-AjaxForms-Upload")
								.evalJSON();

						for (i in headers) {
							if (headers[i] == "complete") {
								AjaxForms.removeUpload(i);
								AjaxForms.removed.set(i, true);
								$("upl_" + i).addClassName(
										'AjaxForms_progress_complete');
								setTimeout(AjaxForms.rimuoviDiv.bind(this, i),
										2000);
							}

						}

						xp = new gXPath("//xhtml:div[starts-with(@id,'upl_')]");
						uploads = xp.evaluate(transport.responseXML.documentElement);
						if (uploads.length == 0) {
							AjaxForms.uploads = new Hash();
							AjaxForms.removed = new Hash();
							AjaxForms.checkUploaderStatus();
							setTimeout(AjaxForms.rimuoviMainDiv.bind(), 1000);
						} else {
							$A(uploads).each(function(it) {
										if (it.id) {
											key = it.id.replace("upl_", "");
											if (AjaxForms.removed.get(key)) {
												return;
											}

										}
										new_node = xmlImportNode(document,it, true);

										if ($(it.id)) {
											$('AjaxFormsUploadLoaders')
													.replaceChild(new_node,
															$(it.id));
										} else {
											$('AjaxFormsUploadLoaders')
													.appendChild(new_node);
										}
									});
						}
					}
				});
	},
	setDisableForm : function(theForm, st) {
		if ($(theForm))
			nodi = $(theForm).select('input[type="file"]',
					'input[type="submit"]');
		$A(nodi).each( function(it) {
			it.disabled = st;
		});
	},
	updater :null,
	uploads :new Hash(),
	removed :new Hash(),
	addUpload : function(id, complete) {
		setTimeout(AjaxForms.updateStatus, 1000);
		if (this.uploads.values().length == 0 && !this.updater) {
			this.updater = setInterval(AjaxForms.updateStatus, 5000);
		}
		this.uploads.set(id, complete);
	},
	removeUpload : function(id, transport) {
		complete = this.uploads.get(id);
		complete(transport, id);
		AjaxForms.uploads.unset(id);
		AjaxForms.checkUploaderStatus();
	},
	checkUploaderStatus : function() {
		if (AjaxForms.uploads.values().length == 0 && AjaxForms.updater) {
			clearInterval(AjaxForms.updater);
			AjaxForms.updater = null;
		}
	},
	checkUploads : function() {
		// return confirm("Uscire?");
	},
	startUpload : function(theForm, opt) {

		requestId = ('req_' + Math.random()).replace(".", "");

		AjaxForms.setDefaultOpts(opt);

		this.createUploadLoaders(requestId);
		this.createUploadIframe(requestId, opt);

		theForm.target = "if_" + requestId;
		$('apc_' + theForm.getAttribute('id')).value = requestId;

		if (opt.disable) {
			setTimeout( function() {
				AjaxForms.setDisableForm(theForm, true);
			}, 50);
		}
		if (typeof (opt.aftersubmit) == 'function') {
			setTimeout(opt.aftersubmit.bindAsEventListener(theForm), 50);
		}

		this.addUpload(requestId, function(transport, requestId) {
			AjaxForms.setDisableForm(theForm, false);
		});

	},
	createUploadLoaders : function(id, opt) {
		ele = $('AjaxFormsUploadLoaders');
		if (!ele) {
			ele = document.createElementN("div");
			ele.setAttribute("id", 'AjaxFormsUploadLoaders');
			$(ele).setStyle(
					{
						display :'block',
						position :Prototype.Browser.IE6 ? 'absolute' : 'fixed',
						textAlign :'center',
						top :Prototype.Browser.IE6 ? document.viewport
								.getScrollOffsets().top
								+ "px" : '0',
						padding :'1em',
						width :'150px',
						right :'0',
						border :'1px solid black',
						backgroundColor :'white'
					});
			document.body.appendChild(ele);
		}

		loader = document.createElementN("div");

		loader.setAttribute("id", 'upl_' + id);
		loader.setAttribute("class", 'uploading_ajax');
		loader.appendChild(document.createTextNode("Uploading..."));
		ele.appendChild(loader);

	},
	createLoaders : function(opt) {
		if (opt.loader_start == 'auto') {
			ele = $('AjaxFormsLoaderLoading');
			if (!ele) {
				ele = document.createElementN("div");
				ele.setAttribute("id", 'AjaxFormsLoaderLoading');

				img = document.createElementN("img");
				img.setAttribute("src", "resources/img/loading.gif");

				ele.appendChild(img);

				ele.appendChild(document.createElementN("br"));
				ele.appendChild(document.createTextNode("Loading..."));

			}

			$(ele).setStyle(
					{
						display :'none',
						position :Prototype.Browser.IE6 ? 'absolute' : 'fixed',
						textAlign :'center',
						top :Prototype.Browser.IE6 ? document.viewport
								.getScrollOffsets().top
								+ "px" : '0',
						padding :'1em',
						margin :'auto',
						border :'1px solid black',
						backgroundColor :'white'
					});
			width = $(ele).getWidth() ? $(ele).getWidth() : 90;
			$(ele).setStyle( {
				left :"" + ((document.viewport.getWidth() - width) / 2) + "px"
			});
			document.body.appendChild(ele);
		}
		if (opt.loader_error == 'auto') {

			ele = $('AjaxFormsLoaderErr');
			if (!ele) {
				ele = document.createElementN("div");
				ele.setAttribute("id", 'AjaxFormsLoaderErr');

				img = document.createElementN("img");
				img.setAttribute("src", "resources/img/icons/cancel.png");

				ele.appendChild(img);

				ele.appendChild(document.createElementN("br"));
				ele.appendChild(document.createTextNode("Errors..."));
			}
			$(ele).setStyle(
					{
						display :'none',
						'z-index' :'100',
						position :Prototype.Browser.IE6 ? 'absolute' : 'fixed',
						padding :'1em',
						top :Prototype.Browser.IE6 ? document.viewport
								.getScrollOffsets().top
								+ "px" : '0',
						textAlign :'center',
						border :'1px solid black',
						backgroundColor :'white',
						color :'black'
					});
			width = $(ele).getWidth() ? $(ele).getWidth() : 80;
			$(ele).setStyle( {
				left :"" + ((document.viewport.getWidth() - width) / 2) + "px"
			});

			document.body.appendChild(ele);
		}
	},
	putContents : function(opt, target, nodeSrc) {

		bd = new gXPath("html:body").evaluate(nodeSrc)[0];

		nodes = new gXPath(opt.xpath).evaluate(bd);

		nodi = new Array();
		if (opt.mode == 'replace-me') {
			$(target).style.display = 'none';
		}
		$A(nodes).each(function(n) {

							int_node = xmlImportNode(document, n, true);

							if (opt.mode == 'replace') {

								if (int_node.nodeType == document.ELEMENT_NODE) {
									nodi.push(int_node);
									nodi.push(int_node.style.visibility);
									int_node.style.visibility = 'hidden';
								}

								target.appendChild(int_node);

							} else if (opt.mode == 'append' || (opt.mode == 'prepend' && target.childNodes.length == 0)) {
								target.appendChild(int_node);

								if (opt.time && int_node.nodeType == document.ELEMENT_NODE) {
									opt.effect = opt.effect || "BlindDown";
									eval("new Effect." + opt.effect+ "(int_node,{duration:opt.time})");
								}

							} else if (opt.mode == 'prepend') {

								if (opt.time && int_node && int_node.nodeType == document.ELEMENT_NODE) {
									int_node.style.display = 'none';
								}

								target.insertBefore(int_node,target.firstChild);

								if (opt.time && int_node.nodeType == document.ELEMENT_NODE) {
									opt.effect = opt.effect || "BlindDown";
									eval("new Effect." + opt.effect + "(int_node,{duration:opt.time})");

								}
							} else if (opt.mode == 'before') {

								if (opt.time && int_node.nodeType == document.ELEMENT_NODE) {
									//int_node.style.display = 'none';
								}

								target.parentNode.insertBefore(int_node, target);

								if (opt.time && int_node.nodeType == document.ELEMENT_NODE) {
									opt.effect = opt.effect || "BlindDown";
									eval("new Effect." + opt.effect
											+ "(int_node,{duration:opt.time})");
								}
							} else if (opt.mode == 'after') {
								if (opt.time
										&& int_node.nodeType == document.ELEMENT_NODE) {
									//int_node.style.display = 'none';
								}
								if (target.nextSibling) {
									target.parentNode.insertBefore(int_node, target.nextSibling);
								} else {

									target.appendChild(int_node);
								}
								// Element.insert(target, { after: int_node });

								if (opt.time && int_node.nodeType == document.ELEMENT_NODE) {
									opt.effect = opt.effect || "BlindDown";
									eval("new Effect." + opt.effect
											+ "(int_node,{duration:opt.time})");
								}
							} else if (opt.mode == 'replace-me') {

								if (opt.time && opt.effect && int_node.nodeType == document.ELEMENT_NODE) {

									target.parentNode.insertBefore(int_node,target);



									eval("new Effect." + opt.effect	+ "(int_node,{duration:opt.time})");

								} else {
									target.parentNode.insertBefore(int_node,target);
								}
							}
						});

		if (opt.mode == 'replace') {
			setTimeout( function name() {
				ov = target.style.visibility;
				target.style.visibility = 'hidden';
				for ( var i = 0, len = nodi.length; i < len; i++) {
					nodi[i].style.visibility = nodi[++i];
				}
				target.style.visibility = ov;
			}, 1);
		}
	},
	serverOpt : function(opt, ele) {

		xp = new gXPath("html:head/html:aj-header");

		nodes = xp.evaluate(ele);

		if (nodes.length == 0)
			return;

		headers = nodes[0].firstChild.nodeValue.split("&");

		$A(headers).each( function(header) {
			data = header.split("=");

			if (data.length != 2)
				return;
			data[1] = unescape(data[1].trim());
			switch (data[0].trim()) {
			case "mode":
				opt.mode = data[1];
				break;
			case "effect":
				opt.effect = data[1];
				break;
			case "target":

				opt.target = data[1];
				break;
			case "xpath":
				if (data[1].length == 0) {
					break;
				}
				opt.xpath = data[1];
				break;
			case "time":
				opt.time = data[1];
				break;
			}
		});
	},
	getTarget : function(opt) {
		if (opt.target && opt.target.indexOf("xpath(") != -1) {
			xp = new gXPath(opt.target.substr(6, opt.target.length - 7));
			nodes = xp.evaluate(document.documentElement);
			if (nodes.length > 0) {
				return nodes[0];
			}
		}else if (opt.target && opt.target.indexOf("css:") != -1) {

			nodes = $$(opt.target.substr(4, opt.target.length - 4));

			if (nodes.length > 0) {
				return nodes[0];
			}
		} else {
			return $(opt.target);
		}
	},
	findFormParams : function(src, opt) {
		if (opt.form.length == 0
				&& (src.nodeName.toLowerCase() == "input" || src.nodeName
						.toLowerCase() == "select")) {

			if (src.form) {
				return Form.serialize(src.form, true);
				//return F$(src.form).serialize(true);
			}

		} else if (opt.form.indexOf("xpath(") != -1) {
			xp = new gXPath(opt.form.substr(6, opt.form.length - 7));
			nodes = xp.evaluate(document.documentElement);
			if (nodes.length > 0) {
				return Form.serialize(nodes.item[0], true);
				//return $(nodes[0]).serialize(true);
			}

		} else if (opt.form.length > 0 && $(opt.form)) {
			return Form.serialize(opt.form, true);
			//return $(opt.form).serialize(true);
		}
		return '';
	},
	onSubmit :new Array(),
	addOnSubmit : function(f) {
		this.onSubmit.push(f);
	},
	hs :new Hash(),

	evalScriptNode : function(current, nodes) {
		reg = /Event\s*\.\s*observe\s*\(\s*window\s*\,\s*\'load\'\s*\,/g;

		it = nodes[current];

		if (it.getAttribute("src")) {

			// controllo che lo script non sia gia incluso

			if (!AjaxForms.hs.get(it.getAttribute("src"))) {

				AjaxForms.hs.set(it.getAttribute("src"), true);

				script = document.createElement("script");
				script.setAttribute("src", it.getAttribute("src"));
				script.setAttribute('defer', 'false');
				script.setAttribute("type", it.getAttribute("type") ? it.getAttribute("type") : "text/javascript" );

				head.appendChild(script);
				Event.observe(script, 'load', function() {
					for (var i = current + 1; i < nodes.length; i++) {
						if (AjaxForms.evalScriptNode(i, nodes) == false) {
							break;
						}
					}
				});
				return false;
			}

		} else {


				if (it.childNodes && it.childNodes.length > 0) {
					script = '';
					for (ijj = 0; ijj<it.childNodes.length; ijj++ ){
						script+=it.childNodes[ijj].nodeValue;
					}
				} else if (it.nodeValue) {

					script = it.nodeValue;


				} else if (it && typeof (it) == 'string') {
					script = it;

				} else {
					script = "";

				}
				try {
					if (script.trim().length > 0) {

						window.eval(script.replace(reg, "AjaxForms.eseguiLoader("));
					}
				} catch (e) {
					alert(e.message +" in\n"+script);

					throw (e);
				}
			}

		return true;
	},
	evalScripts : function(ele, frame) {

		head = new gXPath("/xhtml:html/xhtml:head").evaluate(document.documentElement)[0];

		xp = new gXPath("xhtml:head/xhtml:link");

		$A(xp.evaluate(ele)).each( function(n) {
			if (!AjaxForms.hs.get(n.getAttribute("href")+n.getAttribute("type"))) {
				AjaxForms.hs.set(n.getAttribute("src")+n.getAttribute("type"), true);
				head.appendChild(xmlImportNode(document, n, true));
			}
		});

		xp = new gXPath("xhtml:head/xhtml:aj-script");

		nodes = xp.evaluate(ele);
		for (var i = 0; i < nodes.length; i++) {
			if (AjaxForms.evalScriptNode(i, nodes) == false) {
				break;
			}
		}
	},
	setDefaultOpts : function(opt) {
		if (!opt.mode || opt.mode.length < 4) {
			opt.mode = 'replace';
		}
		if (!opt.xpath || opt.xpath.length < 2) {
			opt.xpath = './html:*|./text()';
		}

		if (!opt.loader_start || opt.loader_start == '') {
			opt.loader_start = 'auto';
		}
		if (!opt.loader_error || opt.loader_error == '') {
			opt.loader_error = 'auto';
		}
		if (!opt.loader_end || opt.loader_end == '') {
			opt.loader_end = 'auto';
		}
	},
	submit : function(srcObject, opt) {
		$A(this.onSubmit).each( function(f) {
			if (typeof (f) == 'function')
				f(srcObject, opt);
		});

		AjaxForms.setDefaultOpts(opt);

		AjaxForms.createLoaders(opt);

		if (opt.loader_start == 'auto') {
			opt.loader_start = 'AjaxFormsLoaderLoading';
		}
		if (opt.loader_error == 'auto') {
			opt.loader_error = 'AjaxFormsLoaderErr';
		}
		if (!opt.hide_mode) {
			opt.hide_mode = 'display';
		}
		if (opt.time && opt.time == "0") {
			opt.time = false;
		}
		AjaxForms.loadingZone(opt, 'loading', srcObject);

		new Ajax.Request(opt.action,{
					parameters :AjaxForms.findFormParams(srcObject, opt),
					onFailure : function(response) {
						AjaxForms.loadingZone(opt, 'error', srcObject);
					},
					onSuccess : function(response) {
						if (opt.debug) {
							alert("debug\nmode:"
									+ opt.mode
									+ "\ntarget:"
									+ opt.target
									+ "\naction:"
									+ opt.action
									+ "\nPOST:"
									+ AjaxForms.findFormParams(srcObject, opt)
											.toQueryString() + "\nContet-type:"
									+ response.getHeader('Content-Type') + "\n"
									+ response.responseText);
						}
						AjaxForms.loadingZone(opt, 'complete', srcObject);

						AjaxForms.serverOpt(opt,response.responseXML.documentElement);

						if (response.getHeader('Content-Type').indexOf('text/xml') != -1) {
							if (opt.mode != 'none') {
								target = AjaxForms.getTarget(opt);
							}
							if (opt.mode == 'remove-childs'	|| opt.mode == 'replace') {

								if (opt.time && opt.effect) {



									while (target.hasChildNodes()) {
										target.removeChild(target.firstChild);
									}
									if (opt.mode == 'replace') {
										AjaxForms.putContents(opt,target,response.responseXML.documentElement);
									}

									eval("new Effect."+ opt.effect+ "(target,{duration:opt.time})");

								} else {

									while (target.hasChildNodes()) {
										target.removeChild(target.firstChild);
									}

									if (opt.mode == 'replace') {

										AjaxForms.putContents(	opt,target,	response.responseXML.documentElement);
									}
								}

							} else if (opt.mode == 'remove-me') {
								if (opt.time) {
									if (opt.effect) {
										eval("new Effect."
												+ opt.effect
												+ "(target,{duration:opt.time})");
									} else {
										new Effect.BlindUp(target, {
											duration :opt.time
										});
									}
									setTimeout( function() {
										if (target)
											$(target).remove();
									}, (opt.time * 1000) + 100);
								} else if (opt.effect && opt.effect != 'none') {
									opt.time = 0.2;
									new Effect.BlindUp(target, {
										duration :opt.time
									});
									setTimeout( function() {
										if (target)
											$(target).remove();
									}, (opt.time * 1000) + 100);
								} else {
									if (target)
										$(target).remove();
								}
							} else if (opt.mode == 'none') {

							} else {

									AjaxForms.putContents(opt, target,response.responseXML.documentElement);

									if(opt.mode == 'replace-me'){
										$(target).remove();
									}

							}

							if (opt.mode != 'none') {
								AjaxForms.evalScripts(response.responseXML.documentElement);
							}

							AjaxForms.runCallbacks(opt,response.responseXML);


						} else {
							alert("no xml response\n" + response.responseText);
						}
					}
				});
		return true;
	},
	runCallbacks:function(opt, response){
		fname = opt.mode.replace('-','_');
		eval("if (typeof(opt.on_"+fname+")=='function') { f=opt.on_"+fname+".bind(opt); f(response);}");
	}
};

Event.observe(window, 'load', function() {
	$A(document.getElementsByTagName('script')).each( function(script) {
		if (script.getAttribute("src")) {
			AjaxForms.hs.set(script.getAttribute("src"), true);
		}
	});
	$A(document.getElementsByTagName('link')).each( function(scriptTag) {

		if (scriptTag.getAttribute("href") && scriptTag.getAttribute("type")=="text/css" && scriptTag.getAttribute("rel")=="stylesheet") {
			AjaxForms.hs.set(scriptTag.getAttribute("href"), scriptTag.getAttribute("type"), true);
		}
	});
});

