/*
 * Copyright (c) 2008 Maximilian Antoni. All rights reserved.
 * http://www.maxantoni.de
 */
window.ajax = {
	
	submit: function(form) {
		var parameters = { "ajax_request": "true" };
		for(var i = 0, l = form.elements.length; i < l; i++) {
			var element = form.elements[i];
			element.disabled = true;
			if(!element.name) continue;
			if(element.type == "checkbox" || element.type == "radio") {
				if(element.checked) {
					parameters[element.name] = element.value;
				}
			}
			else {
				if(element.value) {
					parameters[element.name] = element.value;
				}
			}
		}
		ajax.post(form.action, parameters);
		for(var i = 0, l = form.elements.length; i < l; i++) {
			form.elements[i].disabled = false;
		}
		return false;
	},
	
	post: function(url, parameters) {
		var r = ajax.createHttpRequest();
		r.open("POST", url, false);
		var data = "";
		for(var key in parameters) {
			if(data != "") data += "&";
			data += key + "=" + encodeURI(parameters[key]).replace(/\+/g,"%2b");
		}
		r.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		try {
			r.send(data);
		}
		catch(e) {
			alert("Cannot send request:\n" + e.message);
			return false;
		}
		if(r.status !== 200) {
			alert("Cannot send request: " + r.status);
			return false;
		}
		if(!r.responseXML) {
			alert("Cannot parse XML:\n\n" + r.responseText);
			return false;
		}
		var commands = r.responseXML.getElementsByTagName("commands");
		if(!commands || commands.length == 0) {
			alert("No commands tag found!\n\n" + r.responseText);
			return false;
		}
		var commandList = commands[0].childNodes;
		for(var i = 0, l = commandList.length; i < l; i++) {
			var command = commandList[i];
			if(command.nodeType != 1) {
				continue;
			}
			var commandName = command.nodeName.toLowerCase();
			if(!ajax[commandName]) {
				alert("Unknown command \"" + commandName + "\".");
				return false;
			}
			try {
				ajax[commandName](command);
			}
			catch(e) {
				alert(e.message);
				return false;
			}
		}
		return false;
	},
	
	createHttpRequest: function() {
		return window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
	},
	
	append: function(command) {
		var parent = ajax.getNode(command, "parent");
		ajax.importContent(command, parent, null);
	},

	insert: function(command) {
		var parent = ajax.getNode(command, "parent");
		var before = ajax.getNode(command, "before");
		ajax.importContent(command, parent, before);
	},
	
	replace: function(command) {
		var node = ajax.getNode(command, "id");
		var parent = node.parentNode;
		var next = node.nextSibling;
		parent.removeChild(node);
		ajax.importContent(command, parent, next);
	},
	
	remove: function(command) {
		var node = ajax.getNode(command, "id");
		node.parentNode.removeChild(node);
	},
	
	script: function(command) {
		eval(ajax.getAttribute(command, "eval"));
	},
	
	getAttribute: function(command, attribute) {
		var value = command.getAttribute(attribute);
		if(value) {
			return value;			
		}
		throw new Error("Missing attribute \"" + attribute + "\" for command \"" + command.nodeName + "\".");
	},
	
	getNode: function(command, attribute) {
		var id = ajax.getAttribute(command, attribute);
		var node = document.getElementById(id);
		if(node) {
			return node;
		}
		throw new Error("Element with ID \"" + id + "\" not found.");
	},
	
	IMPORT_PROPERTIES: {
		"id": "id",
		"class": "className",
		"src": "src",
		"title": "title"
	},
	
	importContent: function(element, parent, before) {
		var nodes = element.childNodes;
		for(var i = 0; i < nodes.length; i++) {
			var node = nodes[i];
			switch(node.nodeType) {
			case 1:
				var n = document.createElement(nodes[i].nodeName);
				if(node.attributes && node.attributes.length > 0) {
					for(var j = 0, l = node.attributes.length; j < l; j++) {
						var a = node.attributes[j];
						var p = ajax.IMPORT_PROPERTIES[a.nodeName];
						if(p) n[p] = a.nodeValue;
						else n.setAttribute(a.nodeName, a.nodeValue);
					}
				}
				ajax.importContent(nodes[i], n, null);
				parent.insertBefore(n, before);
				break;
			case 3:
				parent.insertBefore(document.createTextNode(node.nodeValue), before);
				break;
			}
		}
	}
	
}
