function extractText(node)
{
	var ret='';
	for (var i=0; i < node.childNodes.length; i++)
		if (node.childNodes[i].nodeType == 3)
			ret+=node.childNodes[i].nodeValue;
	return ret;
}

function getResponse(xhr)
{
	var doc;
	//mission imbecile 3:
	if (window.ActiveXObject)
	{
		doc=new ActiveXObject('Microsoft.XMLDOM');
		doc.loadXML(xhr.responseText);
	}
	else
		doc=xhr.responseXML;

	//tales from the horror castle:
	var documentElement=null;
	for (var i=0; i < doc.childNodes.length; i++)
		if (doc.childNodes[i].nodeType == 1 && doc.childNodes[i].tagName == 'response')
		{
			documentElement=doc.childNodes[i];
			break;
		}
	if (documentElement != null)
	{
		var status=null, statusMessage=null;
		for (var i=0; i < documentElement.childNodes.length; i++)
			if (documentElement.childNodes[i].nodeType == 1)
				switch(documentElement.childNodes[i].tagName)
				{
					case 'status':
						status=extractText(documentElement.childNodes[i]) == 'true'
							? true
							: false;
						break;
					case 'status-message':
						statusMessage=extractText(documentElement.childNodes[i]) == ''
							? null
							: extractText(documentElement.childNodes[i]);
				}
		if (status != null && statusMessage != null)
			return {status:status, statusMessage:statusMessage};
	}
	return {status:false, statusMessage:'Niepoprawna odpowiedź serwera!'};
}

function sendForm(event, form)
{
	event=event || window.event;
	form=form || event.srcElement || event.target;
	while (form.tagName.toLowerCase() != 'form')
		form=form.parentNode;

	var button=null;
	var table=null;
	var messageCell=null;
	for (var i=0; i < form.elements.length; i++)
		if (form.elements[i].type == 'submit')
		{
			button=form.elements[i];
			break;
		}
	var result=form.getElementsByTagName('table');
	if (result.length == 1)
	{
		table=result[0];
		result=table.getElementsByTagName('tr');
		//spec says it returns elements in document order!
		if (result.length > 0)
		{
			result=result[0].getElementsByTagName('td');
			if (result.length > 0)
				messageCell=result[result.length - 1];
		}
	}

	if (button == null || table == null || messageCell == null)
		return true;

	var script=(form.action != null && form.action != ''
		? form.action
		: document.location.href).replace(/\.([^.]+)$/, '/form.$1');

	//mission imbecile:
	var xml=null;
	if (document.implementation && document.implementation.createDocument)
		xml=document.implementation.createDocument('', 'fields', null);
	else if (window.ActiveXObject)
	{
		xml=new ActiveXObject('Microsoft.XMLDOM');
		xml.appendChild(xml.createElement('fields'));
	}
	if (xml == null)
		return true;

	for (var i=0; i < form.elements.length; i++)
	{
		var field=form.elements[i];
		switch (field.tagName.toLowerCase())
		{
			case 'input':
				if (field.type == 'submit')
					break;
			case 'textarea':
			case 'select':
				var fieldElem=xml.createElement('field');
				var fieldNameElem=xml.createElement('name');
				fieldNameElem.appendChild(xml.createTextNode(field.name));
				var fieldValueElem=xml.createElement('value');
				if (field.tagName.toLowerCase() == 'input' && field.type == 'checkbox')
					fieldValueElem.appendChild(xml.createTextNode(field.checked ? field.value : ''));
				else
					fieldValueElem.appendChild(xml.createTextNode(field.value));
				fieldElem.appendChild(fieldNameElem);
				fieldElem.appendChild(fieldValueElem);
				xml.documentElement.appendChild(fieldElem);
				break;
		}
	}

	var xhr=null;
	//mission imbecile 2:
	if (window.ActiveXObject)
		xhr=new ActiveXObject('Microsoft.XMLHTTP')
	else if (window.XMLHttpRequest)
	{
		xhr=new XMLHttpRequest()
		xhr.overrideMimeType('text/xml; charset=utf-8');
	}
	if (xhr == null)
		return true;

	var oldButton=button.value;
	xhr.onreadystatechange=function()
		{
			if (xhr.readyState == 4)
			{
				if (xhr.status == 200)
				{
					var response=getResponse(xhr);
					if (response.status)
						table.parentNode.replaceChild(document.createTextNode(response.statusMessage), table);
					else
					{
						messageCell.innerHTML=response.statusMessage;
						button.disabled=false;
						button.value=oldButton;
					}
				}
				else
				{
					messageCell.innerHTML='Wystąpił błąd HTTTP '+xhr.status+' ('+xhr.statusText+')';
					button.disabled=false;
					button.value=oldButton;
				}
			}
		};


	xhr.open('POST', script);
	button.disabled=true;
	button.value='Proszę czekać...';
	xhr.send(xml);

	return false;
}

//magic
function ajaxifize()
{
	var forms=document.getElementsByTagName('form');
	for (var i=0; i < forms.length; i++)
	{
		var form=forms[i];
		if (form.className == 'form_ajax')
			//more magic
			(function()
			{
				var f=form;
				var victim=f.onsubmit;
				f.onsubmit=function()
				{
					return (typeof victim != 'function' || victim()) && sendForm(null, f);
				}
			})();
	}
}
