//	browser detection
function browser() {
	this.init();
}
browser.prototype = {
	_browser: null,
	_version: null,
	_os: null,
	init: function () {
		this._browser = this._search_string(this._data_browser) || "An unknown browser";
		this._version = this._search_version(navigator.userAgent)
			|| this._search_sersion(navigator.appVersion)
			|| "an unknown version";
		this._os = this._search_string(this._data_os) || "an unknown OS";
	},
	_search_string: function (data) {
		for (var i = 0; i < data.length; i++) {
			var data_string = data[i].string;
			var data_prop = data[i].prop;
			this.version_search_string = data[i].version_search || data[i].identity;
			if (data_string) {
				if (data_string.indexOf(data[i].substring) != -1)
					return data[i].identity;
			}
			else if (data_prop)
				return data[i].identity;
		}
	},
	_search_version: function (data_string) {
		var index = data_string.indexOf(this.version_search_string);
		if (index == -1) return;
		return parseFloat(data_string.substring(index + this.version_search_string.length + 1));
	},
	_data_browser: [
		{ 	string: navigator.userAgent,
			substring: "OmniWeb",
			version_search: "OmniWeb/",
			identity: "OmniWeb"
		},
		{
			string: navigator.vendor,
			substring: "Apple",
			identity: "Safari"
		},
		{
			prop: window.opera,
			identity: "Opera"
		},
		{
			string: navigator.vendor,
			substring: "iCab",
			identity: "iCab"
		},
		{
			string: navigator.vendor,
			substring: "KDE",
			identity: "Konqueror"
		},
		{
			string: navigator.userAgent,
			substring: "Firefox",
			identity: "Firefox"
		},
		{
			string: navigator.userAgent,
			substring: "Chrome",
			identity: "Chrome"
		},
		{
			string: navigator.vendor,
			substring: "Camino",
			identity: "Camino"
		},
		{		// for newer Netscapes (6+)
			string: navigator.userAgent,
			substring: "Netscape",
			identity: "Netscape"
		},
		{
			string: navigator.userAgent,
			substring: "MSIE",
			identity: "Explorer",
			version_search: "MSIE"
		},
		{
			string: navigator.userAgent,
			subString: "Gecko",
			identity: "Mozilla",
			versionSearch: "rv"
		},
		{ 		// for older Netscapes (4-)
			string: navigator.userAgent,
			substring: "Mozilla",
			identity: "Netscape",
			version_search: "Mozilla"
		}
	],
	_data_os : [
		{
			string: navigator.platform,
			substring: "Win",
			identity: "Windows"
		},
		{
			string: navigator.platform,
			substring: "Mac",
			identity: "Mac"
		},
		{
			string: navigator.platform,
			substring: "Linux",
			identity: "Linux"
		}
	],
	get_name: function() {
		return this._browser;
	},
	get_version: function() {
		return this._version;
	},
	get_os: function() {
		return this._os;
	},

	is_ie: function() {
		return this._browser == "Explorer";
	},
	is_mozilla: function() {
		return this._browser == "Firefox";
	},
	is_opera: function() {
		return this._browser == "Opera";
	},
	is_safari: function() {
		return this._browser == "Safari";
	},
	is_chrome: function() {
		return this._browser == "Chrome";
	}
}
browser = new browser();

//	mozilla extension
if (document.implementation.hasFeature("XPath", "3.0")) {
	XMLDocument.prototype.selectNodes = function(cXPathString, xNode) {
		if (!xNode) { xNode = this; }
		var oNSResolver = this.createNSResolver(this.documentElement)
		var aItems = this.evaluate(cXPathString, xNode, oNSResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)
		var aResult = [];
		for (var i = 0; i < aItems.snapshotLength; i++) {
			aResult[i] =  aItems.snapshotItem(i);
		}
		return aResult;
	}
	XMLDocument.prototype.selectSingleNode = function(cXPathString, xNode) {
		if (!xNode) { xNode = this; }

		var xItems = this.selectNodes(cXPathString, xNode);
		if (xItems.length > 0) {
			return xItems[0];
		} else {
			return null;
		}
	}

	Element.prototype.selectNodes = function(cXPathString) {
		if (this.ownerDocument.selectNodes) {
			return this.ownerDocument.selectNodes(cXPathString, this);
		} else {
			throw "For XML Elements Only";
		}
	}

	Element.prototype.selectSingleNode = function(cXPathString) {
		if (this.ownerDocument.selectSingleNode) {
			return this.ownerDocument.selectSingleNode(cXPathString, this);
		} else {
			throw "For XML Elements Only";
		}
	}
}


function clone(obj) {
	var result;
	if (typeof obj != "object") {
		result = obj;
	} else {
		result = new Object();
		for (var i in obj) {
			result[i] = clone(obj[i]);
		}
	}
	return result;
}

function extend(source, destination) {
	for (var i in destination.prototype) {
		if (source.prototype[i] === undefined) {
			source.prototype[i] = clone(destination.prototype[i]);
		}
	}
}

//	basic xmlhttp class (the real workhorse)
function xmlhttp_basic() {
	this.init();
}
xmlhttp_basic.prototype = {
	xmlhttp: null,
	abort: function() {
		return this.xmlhttp.abort();
	},
	init: function() {
	},
	get_all_response_headers: function() {
		return this.xmlhttp.getAllResponseHeaders();
	},
	get_ready_state: function() {
		return this.xmlhttp.readyState;
	},
	get_response_header: function(header) {
		return this.xmlhttp.getResponseHeader(header);
	},
	get_response_text: function() {
		return this.xmlhttp.responseText;
	},
	get_response_xml: function() {
		return this.xmlhttp.responseXML;
	},
	get_status: function() {
		return this.xmlhttp.status;
	},
	open: function(method, url, async, user, password) {
		if (user !== undefined) {
			return this.xmlhttp.open(method, url, async, user, password);
		} else {
			return this.xmlhttp.open(method, url, async);
		}
	},
	send: function(data) {
		return this.xmlhttp.send(data);
	},
	set_onreadystatechange: function(onreadystatechange) {
		this.xmlhttp.onreadystatechange = onreadystatechange;
	},
	set_request_header: function(header, value) {
		return this.xmlhttp.setRequestHeader(header, value);
	}
}

//	implementation of the xmlhttp for ie
function xmlhttp_ie() {
	this.init();
}
xmlhttp_ie.prototype = {
	base: xmlhttp_basic.prototype,
	init: function() {
		try {
			this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		} catch (e) {
		}
	}
}
extend(xmlhttp_ie, xmlhttp_basic);


//	implementation of the xmlhttp for mozilla
function xmlhttp_mozilla() {
	this.init();
}
xmlhttp_mozilla.prototype = {
	base: xmlhttp_basic.prototype,
	init: function() {
		try {
			this.xmlhttp = new XMLHttpRequest();
		} catch (e) {
		}
	}
}
extend(xmlhttp_mozilla, xmlhttp_basic);

//	implementation of the xmlhttp for opera
function xmlhttp_opera() {
	this.init();
}
xmlhttp_opera.prototype = {
	base: xmlhttp_basic.prototype,
	init: function() {
		try {
			this.xmlhttp = new XMLHttpRequest();
		} catch (e) {
		}
	}
}
extend(xmlhttp_opera, xmlhttp_basic);



function https(number_of_objects) { this.init(number_of_objects); };

https.prototype = {
	https: [], // array of xml_http_request instances
	init: function(number_of_objects) {
		if (number_of_objects) {
			for (var i = 0; i < number_of_objects; i++) {
				this.add_new_object();
			}
		}
	},

	get_free_object_index: function() {
		for (var i = 0; i < this.https.length; i++) {
			if (!this.https[i].is_busy()) {
				return i;
			}
		}
		this.add_new_object();	//	all objects are busy now, new object is required
		return this.https.length - 1;
	},

	add_new_object: function() {
		this.https.push(new xml_http_request("automatically created object #" + this.https.length, this));
	},

	get_object: function(params) {
		if (!params.type) {
			params.type = "text2js";
		}
		if (!params.method) {
			params.method = "post";
		}
		if (!params.arguments) {
			params.arguments = [];
		}
		if (!/^(text|xml2js|xml|xslt|text2js)$/.test(params.type)) {
			alert("Unsupported object_name: " + params.type);
			return;
		}
		if (!/^(get|post)$/i.test(params.method)) {
			alert("Unsupported method: " + params.method);
		}
		var object_index = this.get_free_object_index();
		var url = params.url;
		if (!url) {
//			url = this.get_url(params.type, params.call_id, params.parameters, params.query);
			url = this.get_url(params.type, params.call_id);
		}
		var data = this.get_data(params.parameters, params.query);
		this.https[object_index].top_arguments = [ ];
		if (params.arguments) {
			this.https[object_index].top_arguments = params.arguments;
		}
		this.https[object_index].name = params.name;
		return this.https[object_index].get_object({type: params.type, url: url, method: params.method, data: data, login: params.login, password: params.password, callback: params.callback, callback_object: params.callback_object});
	},

	abort: function(names) {
		if (names && typeof names != "object") {
			names = [ names ];
		}
		for (var i = 0; i < this.https.length; i++) {
			if (this.https[i].is_busy() && (!names || (names && array_search(this.https[i].name, names) !== false))) {
				this.https[i].abort();
			}
		}
	},

	get_url: function(type, call_id) {
		if (!/^(text|xml2js|xml|xslt|text2js)$/.test(type)) {
			alert("Unsupported type: " + type);
			return false;
		}
		var parameters = {};
		if (type == "text2js") {
			parameters.type = "json";
		} else if (type == "xml") {
			parameters.type = "xml";
		} else if (type == "xslt") {
			parameters.type = "xsl";
		}
		parameters.module = call_id;
		var url = "index.php?" + generate_post_query(parameters);
		return url;
	},

	get_data: function(parameters, query) {
		if (parameters == undefined) {
			parameters = {};
		}
		var data = generate_post_query(parameters);
		if (query) {
			data = data + "&" + query;
		}
		return data;
	},

	get_number_of_busy_objects: function() {
		var result = 0;
		for (var i = 0; i < this.https.length; i++) {
			if (this.https[i].is_busy()) {
				result++;
			}
		}
		return result;
	},

	update_indicator: function() {
		if (this.indicator) {
			var number_of_busy_objects = this.get_number_of_busy_objects();
			if (number_of_busy_objects) {
				//this.indicator.title = language.requests_in_progress + " " + number_of_busy_objects;
				//this.indicator.alt = number_of_busy_objects;
				this.indicator.style.visibility = "visible";
			} else {
				this.indicator.style.visibility = "hidden";
			}
		}
	}

};

var https = new https();

//	main ajax class
function xml_http_request(object_name, parent) { this.set_object_name(object_name); this.set_parent(parent); this.init(); };
xml_http_request.prototype = {
	xmlhttp: null,
	xml: null,
	busy: false,
	current_url: "",
	object_name: "",
	parent: null,	//	points to the objects container, may be null
	question_mark: "&",	//	set question_mark to "&" if you use mod_rewrites, otherwise it shoud be "?"

	set_object_name: function(object_name) {
		if (object_name == "" || object_name == undefined || object_name == null) {
			object_name = "anonymous";
		}
		this.object_name = object_name;
	},

	set_parent: function(parent) {
		if (parent) {
			this.parent = parent;
		}
	},

	check_busy: function() {
		if (this.busy) {
			alert("DEBUG: the object " + this.object_name + " is busy now with " + this.current_url);
		}
	},

	is_busy: function() {
		return this.busy;
	},

	set_busy: function(url) {
		this.busy = true;
		this.current_url = url;
		this.update_indicator();
	},

	clear_busy: function() {
		this.busy = false;
		this.update_indicator();
	},

	update_indicator: function() {
		if (this.parent) {
			this.parent.update_indicator();
		}
	},

	init: function() {
		this.check_busy();
		this.clear_busy();
		if (this.xmlhttp) {
			delete this.xmlhttp;
		}
		if (browser.is_opera()) {
			this.xmlhttp = new xmlhttp_opera();
		} else if (browser.is_ie()) {
			this.xmlhttp = new xmlhttp_ie();
		} else if (browser.is_mozilla() || browser.is_safari() || browser.is_chrome()) {
			this.xmlhttp = new xmlhttp_mozilla();
		} else {
			alert("your browser is not supported");
		}
	},

	abort: function() {
		this.clear_busy();
		if (this.xmlhttp) {
			this.xmlhttp.abort();
		}
	},

	node2array: function (node) {
		if (node == undefined || node == null) node = this.xml;
		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;
	},

	callback: function(params) {
		if (window.exiting) {
			return;
		}
		var top_arguments = this.top_arguments;
		var callback_arguments = [];
		var callback_arguments_string = [];
		if (params.exception) {
			callback_arguments[0] = false;
		} else if (params.type == "text") {
			callback_arguments[0] = this.xmlhttp.get_response_text();
		} else if (params.type == "xml2js") {
			callback_arguments[0] = this.node2array(this.xmlhttp.get_response_xml().documentElement);
		} else if (params.type == "xml") {
			if (this.xmlhttp.get_response_text() == "<refresh_needed />") {
				this.handle_refresh_needed();
				return;
			}
			callback_arguments[0] = this.xmlhttp.get_response_xml();
		} else if (params.type == "xslt") {
			if (this.xmlhttp.get_response_text() == "<refresh_needed />") {
				this.handle_refresh_needed();
				return;
			}
			callback_arguments[0] = xslt_from_xml(this.xmlhttp.get_response_xml());
		} else if (params.type == "text2js") {
			try {
				eval("callback_arguments[0] = " + this.xmlhttp.get_response_text());
			} catch(e) {
				alert(e + "\n\nSource code is:\n\n" + this.xmlhttp.get_response_text());
				return;
			}
			if (callback_arguments[0].refresh_needed) {
				this.handle_refresh_needed();
				return;
			}
		} else {
			alert("There's an error in javascript code!\nUnknown type: " + type);
			return;
		}
		if (!params.callback) {
			return callback_arguments[0];
		}

		for (var i = 0; i < top_arguments.length; i++) {
			callback_arguments[callback_arguments.length] = top_arguments[i];
		}
		for (var i = 0; i < callback_arguments.length; i++) {
			callback_arguments_string[callback_arguments_string.length] = "callback_arguments[" + i + "]";
		}
		this.clear_busy();
		if (!params.callback_object) {
			eval("params.callback(" + callback_arguments_string.join(", ") + ")");
		} else {
			eval("params.callback_object['" + params.callback + "'](" + callback_arguments_string.join(", ") + ")");
		}
	},

	get_object: function(params) {
		this.init();
		this.set_busy(params.url);
		if (params.data === "" || params.data === undefined) {
			params.data = null;
		}
		params.method = params.method.toUpperCase();
		if (params.method == "GET" && params.data !== null) {
			if (params.url.search(/\?/) == -1) {
				params.url = params.url + this.question_mark;
			} else {
				params.url = params.url + "&";
			}
			params.url = params.url + params.data;
			params.data = null;
		} else if (params.method == "POST" && params.data === null) {
			params.method = "GET";	//	411 Content-Length required problem workaround
		}
		if (!params.callback) {
			this.xmlhttp.open(params.method, params.url, false, params.login, params.password);
			this.xmlhttp.set_request_header("Content-type", "application/x-www-form-urlencoded");
			this.xmlhttp.send(params.data);
			this.clear_busy();
			if (this.xmlhttp.get_ready_state() == 4 && this.xmlhttp.get_status() == 200)
				return this.callback(params);
			else
	 			return null;
		} else {
			this.xmlhttp.open(params.method, params.url, true, params.login, params.password);
			this.xmlhttp.set_request_header("Content-type", "application/x-www-form-urlencoded");
			var th = this;
			this.xmlhttp.set_onreadystatechange(function() {
				var ready = false;
				var error = false;
				try {
					if (th.xmlhttp.get_ready_state() == 4 && th.xmlhttp.get_status() == 200) {
						ready = true;
					}
				} catch (e) {
//					alert(e);
					error = e;
				}
				if (ready) { th.callback(params); }
				else if (error) { params.exception = error; th.callback(params); }
			});
			this.xmlhttp.send(params.data);
		}
	},
	handle_refresh_needed: function() {
		if (window.is_popup){
			parent.exiting = true;
			parent.https.abort();
			parent.location.href = parent.location.href;
		} else {
			window.exiting = true;
			https.abort();
			window.location.href = window.location.href;
		}
	}
}

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;
	}
}

//	perfoming xslt transformation
function xslt_transform(xml_source, xslt_source, container, parameters) {
	var temp = document.getElementById("temp_container");
	if (!temp) {
		alert("Temp container is missing");
		return;
	}
	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) {
			var parameter = parameters[property];
			xslt_processor.addParameter(property, parameter, "");
		}
		xslt_processor.transform();
		temp.innerHTML = xslt_processor.output;
		if (container.innerHTML != temp.innerHTML) {
			container.innerHTML = temp.innerHTML;
		}
		temp.innerHTML = "";
	} catch (e) {
		try {
			var xslt_processor = new XSLTProcessor();
			xslt_processor.importStylesheet(xslt_source);
			for (var property in parameters) {
				var parameter = parameters[property];
				xslt_processor.setParameter(null, property, parameter);
			}
			var result = xslt_processor.transformToFragment(xml_source, document);
//			container.appendChild(result);

			temp.innerHTML = "";
			temp.appendChild(result);
			if (container.innerHTML != temp.innerHTML) {
				container.innerHTML = temp.innerHTML;
			}
			temp.innerHTML = "";
		} catch (e) {
			//alert("Your browser still not supported");
		}
	}
}

//	xml manipulations
function remove_node_from_xml(xml, name) {
	if (!xml) {
		return false;
	}
	var root = xml.documentElement;
	if (!root) {
		root = xml;
	}
	if (name == undefined) {
		name = "js";
	}
	var old_node = root.selectSingleNode(name);
	if (old_node) {
		old_node.parentNode.removeChild(old_node);
	}
	return true;
}

function add_js2xml(xml, js, name) {
	if (name == undefined) {
		name = "js";
	}
	if (!xml) {
		return null;
	}
	var root = xml.documentElement;
	if (!root) {
		root = xml;
	}
	root.appendChild(object2node(xml, js, name));
}

function replace_js_in_xml(xml, js, name) {
	if (name == undefined) {
		name = "js";
	}
	remove_node_from_xml(xml, name);
	add_js2xml(xml, js, name);
}

function object2node(xml, obj, name) {
	var root = xml.documentElement;
	if (!root) {
		root = xml;
	}
	var node = root.ownerDocument.createElement(name);

	if (obj === undefined || obj === null || obj === false) {
		obj = "";
	} else if (obj === true) {
		obj = "1";
	}

	var type = typeof obj;
	if (type == "object") {
		if (typeof obj.join == "function") {	//	array
			for (var i in obj) {
				for (var j in obj[i]) {
					node.appendChild(object2node(xml, obj[i][j], j));
				}
			}
		} else {	//	object
			for (var i in obj) {
				node.appendChild(object2node(xml, obj[i], i));
			}
		}
	} else {
		node.appendChild(root.ownerDocument.createTextNode(obj));
	}
	return node;
}

function add_options2xml(xml, options, name) {
	if (!remove_node_from_xml(xml, name)) {
		return;
	}
	var root = xml.documentElement;
	if (!root) {
		root = xml;
	}
	var js_node = root.ownerDocument.createElement(name);
	var temp_node;
	var attribute;
	for (var i in options) {
		temp_node = xml.createElement("option");
		attribute = xml.createAttribute("value");
		attribute.value = i;
		temp_node.attributes.setNamedItem(attribute);
		temp_node.appendChild(root.ownerDocument.createTextNode(options[i]));
		js_node.appendChild(temp_node);
	}
	root.appendChild(js_node);
}

function xml2string(xml) {
	if (xml == null || xml == undefined) {
		return null;
	}
	if (document.all) {
		return xml.xml;
	} else {
		try {
			return (new XMLSerializer()).serializeToString(xml);
		} catch (e) {
			return false;
		}
	}
}

function string2xml(string) {
	var xml;
	if (document.all) {
		xml = new ActiveXObject("Msxml2.DOMDocument.3.0");
		xml.loadXML(string);
	} else {
		var dom_parser = new DOMParser();
		xml = dom_parser.parseFromString(string, "application/xml");
	}
	return xml;
}

//	real browser emulation
function htmlspecialchars(str) {
	if (typeof str == "undefined") {
		str = "";
	}
	return str.replace(/\"/g, "&quot;");
}

function full_htmlspecialchars(str) {
	if (typeof str == "undefined") {
		str = "";
	}
	return str.replace(/&/g, "&amp;").replace(/\"/g, "&quot;").replace(/>/g, "&gt;").replace(/</g, "&lt;");
}

function full_htmlspecialchars_decode(str) {
	if (typeof str == "undefined") {
		str = "";
	}
	return str.replace(/&amp;/g, "&").replace(/&qoute;/g, "\"").replace(/&gt;/g, ">").replace(/&lt;/g, "<");
}


function form2object(form, include_disabled_elements) {
	var element;
	var successfull_elements = {};
	for (var i = 0; i < form.elements.length; i++) {
		element = form.elements[i];
		if (element.type.toLowerCase() == "checkbox" && !element.checked) {
			continue;
		}
		if (element.disabled && !include_disabled_elements) {
			continue;
		}
		successfull_elements[element.name] = element.value;
	}
	return successfull_elements;
}

function form2query(form) {
	var element;
	var successfull_elements = [];
	for (var i = 0; i < form.elements.length; i++) {
		element = form.elements[i];
		if (element.type.toLowerCase() == "checkbox" && !element.checked) {
			continue;
		}
		if (element.disabled) {
//			continue;
		}
		successfull_elements[successfull_elements.length] = element.name + "=" + encodeURIComponent(element.value);
	}
	return successfull_elements.join("&");
}

function generate_post_query(par) {
	var pairs = [];
	var pair_name;
	for (var name in par) {
		if (par.hasOwnProperty(name)) {
			var encoded_name = encodeURIComponent(name);
			var type = typeof par[name];
			if (type == "string" || type == "number") {
				pairs.push(encoded_name + "=" + encodeURIComponent(par[name]));
			} else {
				for (var i = 0; i < par[name].length; i++) {
					pairs.push(encoded_name + "=" + encodeURIComponent(par[name][i]));
				}
			}
		}
	}
	return pairs.join("&");
}

var load_object_params;

function load_objects(result, object_name, callback, object_index) {
	if (result == null && object_name == null) {	//	initial call
		for (var i = 0; i < load_object_params.length; i++) {
			https.get_object({type: load_object_params[i].type, call_id: load_object_params[i].call_id, callback: load_objects, arguments: [load_object_params[i].object, callback, i]});
		}
	} else {
		eval(object_name + "=result");
		load_object_params[object_index].loaded = true;
		for (var i = 0; i < load_object_params.length; i++) {
			if (!load_object_params[i].loaded) {
				return;
			}
		}
		callback();
	}
}

function xml2object(xml) {
	var result = new Object();
	var node_name;
	var node_value;
	var child_node;

	for (var i = 0; i < xml.attributes.length; i++) {
		if (!result.attributes) {
			result.attributes = new Object();
		}
		result.attributes[xml.attributes[i].nodeName] = xml.attributes[i].nodeValue;
	}

	for (var i = 0; i < xml.childNodes.length; i++) {
		child_node = xml.childNodes[i];
		node_name = child_node.nodeName;
		node_value = child_node.nodeValue;

		if (child_node.nodeType == 1) {	//	element
			node_value = xml2object(child_node);
			if (!result.content) {
				result.content = new Object();
			}
			if (result.content[node_name] === undefined && typeof result.content.join != "function") {
				result.content[node_name] = node_value;
			} else if (typeof result.content.join == "function") {
				result.content.push(node_value);
			} else {
				result.content = new Array(result.content[node_name], node_value);
			}
//		} else if (child_node.nodeType == 2) {	//	attribute
//			if (!result.attributes) {
//				result.attributes = new Object();
//			}
//			result.attributes[node_name] = node_value;
		} else if (child_node.nodeType == 3) {	//	text
			result.value = node_value;
		}
	}
	return result;
}

function get_form_parameters(form, do_not_ignore_disabled) {
	var result = {};
	for (var i = 0; i < form.elements.length; i++) {
		var element = form.elements[i];
		if (element.disabled && !do_not_ignore_disabled) {
			continue;
		}
		if (element.tagName.toLowerCase() == "input") {
			if ((element.type.toLowerCase() == "checkbox" || element.type.toLowerCase() == "radio") && !element.checked) {
				continue;
			}
		}
		if (result[element.name] === undefined) {
			result[element.name] = element.value;
		} else {
			if (typeof result[element.name].join !== "function") {
				result[element.name] = [ result[element.name] ];
			}
			result[element.name].push(element.value);
		}
	}
	return result;
}
