function xml_http_request() { this.init(); };
xml_http_request.prototype = {
	xmlhttp: null,
	xml: null,
	base_url : "index.php?module=xml",
    
	init: function() {
		try {
			this.xmlhttp = new XMLHttpRequest();
		} catch (e) {
			var msxml_xmlhttp_progids = new Array(
					"Microsoft.XMLHTTP"
					);
			for (var i = 0; i< msxml_xmlhttp_progids.length; i++) {
				try {
					this.xmlhttp = new ActiveXObject(msxml_xmlhttp_progids[i]);
				} catch (e) { }
			}
		}
	},

/*
	get_node_value : function (node_name, root_node) {
		if (root_node == undefined || root_node == null) root_node = this.xml;
		try {
			var node = root_node.getElementsByTagName(node_name)[0];
		} catch (e) {
			alert(e);
        }
		var value = "";
		if (node && node.hasChildNodes && node.firstChild) value = node.firstChild.nodeValue;
		return value;
	},

	get_child_nodes : function (name, root_node) {
		if (root_node == undefined || root_node == null) root_node = this.xml;
		if (name == undefined || name == null) return root_node.childNodes;
		else return root_node.getElementsByTagName(name);
	},
*/
	node2array: function (node) {
		if (node == undefined || node == null) node = this.xmlhttp.responseXML.documentElement;
		var child_node;
		var has_text = false;
		for (var i = 0; i < node.childNodes.length; i++) {
			var child_node = node.childNodes[i];
			if (child_node.nodeType == 3) has_text = true;
		}
		if (has_text || node.childNodes.length == 0) {
			if (node.hasChildNodes && node.firstChild) value = node.firstChild.nodeValue;
			else value = "";
			return value;
		}
		var result = new Array();
		for (var i = 0; i < node.childNodes.length; i++) {
			var child_node = node.childNodes[i];
			var map = new Object();			
			for (var j = 0; j < child_node.childNodes.length; j++) {
				var sub_child_node = child_node.childNodes[j];
				map[sub_child_node.nodeName] = this.node2array(sub_child_node);
			}
			result[result.length] = map;
		}
		return result;
	},

	get_text: function (url, callback) {
		if (callback == undefined || callback == null) {
			this.xmlhttp.open("GET", url, false);
			this.xmlhttp.send(null);
			if (this.xmlhttp.readyState == 4 && this.xmlhttp.status == 200) 
				return this.xmlhttp.responseText;
			else
				return null;
		} else {
			top_arguments = arguments;
			arguments_string = generate_function_arguments("top_arguments", arguments, 2);
			this.xmlhttp.open("GET", url, true);
			var temp_xmlhttp = this.xmlhttp;
			this.xmlhttp.onreadystatechange = function() {
				if (temp_xmlhttp.readyState == 4 && temp_xmlhttp.status == 200) {
					if (arguments_string == "") {
						arguments_string = "temp_xmlhttp.responseText";
					} else {
						arguments_string = "temp_xmlhttp.responseText, " + arguments_string;
					}
					eval("callback(" + arguments_string + ")");
				}
			}
			this.xmlhttp.send(null);
		}
	},

	get_xml2js: function (url, callback) {
		url = this.base_url + "&" + url;
		if (callback == undefined || callback == null) {
			this.xmlhttp.open("GET", url, false);
			this.xmlhttp.send(null);
			if (this.xmlhttp.readyState == 4 && this.xmlhttp.status == 200) 
				return this.node2array(this.xmlhttp.responseXML.documentElement);
			else
				return null;
		} else {
			top_arguments = arguments;
			arguments_string = generate_function_arguments("top_arguments", arguments, 2);
			this.xmlhttp.open("GET", url, true);
			var temp = this;
			this.xmlhttp.onreadystatechange = function() {
				if (temp.xmlhttp.readyState == 4 && temp.xmlhttp.status == 200) {
					var result = temp.node2array(temp.xmlhttp.responseXML.documentElement);
					if (arguments_string == "") {
						arguments_string = "result";
					} else {
						arguments_string = "result, " + arguments_string;
					}
					eval("callback(" + arguments_string + ")");
				}
			}
			this.xmlhttp.send(null);
		}
	},

	get_xml: function (action, callback) {
		var url = this.base_url + "&action=" + action;
		this.init();
		if (callback == undefined || callback == null) {
			this.xmlhttp.open("GET", url, false);
			this.xmlhttp.send(null);
			if (this.xmlhttp.readyState == 4 && this.xmlhttp.status == 200) return this.xmlhttp.responseXML;
			else return null;
		} else {
			top_arguments = arguments;
			arguments_string = generate_function_arguments("top_arguments", arguments, 2);
			this.xmlhttp.open("GET", url, true);
			var temp_xmlhttp = this.xmlhttp;
			this.xmlhttp.onreadystatechange = function() {
				if (temp_xmlhttp.readyState == 4 && temp_xmlhttp.status == 200) {
					if (arguments_string == "") {
						arguments_string = "temp_xmlhttp.responseXML";
					} else {
						arguments_string = "temp_xmlhttp.responseXML, " + arguments_string;
					}
					eval("callback(" + arguments_string + ")");
				}
			}
			this.xmlhttp.send(null);
		}
	},

	get_xslt: function (url, callback) {
		this.init();
		if (callback == undefined || callback == null) {
			this.xmlhttp.open("GET", url, false);
			this.xmlhttp.send(null);
			if (this.xmlhttp.readyState == 4 && this.xmlhttp.status == 200)
				return xslt_from_xml(this.xmlhttp.responseXML);
			else return null;
		} else {
			top_arguments = arguments;
			arguments_string = generate_function_arguments("top_arguments", arguments, 2);
			this.xmlhttp.open("GET", url, true);
			var temp_xmlhttp = this.xmlhttp;
			this.xmlhttp.onreadystatechange = function() {
				if (temp_xmlhttp.readyState == 4 && temp_xmlhttp.status == 200) {
					var xslt = xslt_from_xml(temp_xmlhttp.responseXML);
					if (arguments_string == "") {
						arguments_string = "xslt";
					} else {
						arguments_string = "xslt," + arguments_string;
					}
					eval("callback(" + arguments_string + ")");
				}
			}
			this.xmlhttp.send(null);
		}
	}
}

function xslt_from_xml(xml) {
	if (document.all) {
		var xslt = new ActiveXObject("MSXML2.FreeThreadedDOMDocument");
		xslt.async = false;
		xslt.loadXML(xml.xml);
		return xslt;
	} else {
		return xml;
	}
}

function xslt_transform(xml_source, xslt_source, container, parameters) {
	try {
		var xsl_template = new ActiveXObject("MSXML2.XSLTemplate");
		xsl_template.stylesheet = xslt_source;
		var xslt_processor = xsl_template.createProcessor();
		xslt_processor.input = xml_source;
		for (var property in parameters) {
			xslt_processor.addParameter(property, parameters[property], "");
		}
		xslt_processor.transform();
		container.innerHTML = xslt_processor.output;
	} catch (e) {
		try {
			var xslt_processor = new XSLTProcessor();
			xslt_processor.importStylesheet(xslt_source);
			for (var property in parameters) {
				xslt_processor.setParameter(null, property, parameters[property]);
			}
			var result = xslt_processor.transformToFragment(xml_source, document);
			container.innerHTML="";
			container.appendChild(result);
		} catch (e) {
			alert("Your browser still not supported yet");
		}
	}
}

function generate_function_arguments(arguments_name, arguments_list, index_of_first) {
	var length = arguments.length;
	var function_parameters = new Array();
	for (var i = index_of_first; i < arguments_list.length; i++) {
		function_parameters[function_parameters.length] = arguments_name + "[" + i + "]";
	}
	return function_parameters.join(",");
}

function set_inner_html(element, value) {
	var el = document.getElementById(element);
	if (!el) return false;
	el.innerHTML = value;
	return true;
}

function add_js2xml(xml, js) {
	var reg = new RegExp;
	var root = xml.documentElement;
	for (var i = root.childNodes.length - 1; i >= 0; i--) {
		if (root.childNodes[i].nodeName == "js") {
			root.removeChild(root.childNodes[i]);
			break;
		}
	}
	var js_node = xml.createElement("js");
	var variable_node, variable_text;
	for (var i in js) {
		var variable = js[i];
		if (typeof(js[i])!='object') continue;
		variable_node = xml.createElement(variable.name);
		variable_text = xml.createTextNode(variable.value);
		variable_node.appendChild(variable_text);
		js_node.appendChild(variable_node);
	}
	root.appendChild(js_node);
}

function not_text_child_length(obj) {
	var length = 0;
	var result = obj.firstChild;
	for (; result; result = result.nextSibling) {
		if (result.nodeType != 3) length++;
	}
	return length;
}

function not_text_child_by_index(obj, index) {
	//	when damn mozilla gets white spaces it creates new node, while IE does not
	var i = -1;
	var result = obj.firstChild;
	for (; result; result = result.nextSibling) {
		if (result.nodeType != 3) i++;
		if (i == index) break;
	}
	return result;
}

function not_text_next_subling_by_index(obj, index) {
	var i = -1;
	var result = obj.nextSibling;
	for (; result; result = result.nextSibling) {
		if (result.nodeType != 3) i++;
		if (i == index) break;
	}
	return result;
}

function not_text_previous_subling_by_index(obj, index) {
	var i = -1;
	var result = obj.previousSibling;
	for (; result; result = result.previousSibling) {
		if (result.nodeType != 3) i++;
		if (i == index) break;
	}
	return result;
}