	DOM = (document.getElementById);
	IE4 = (document.all);
	NN4 = (document.layers);
	
	function isHTMLForm(form) {
		if (typeof(form) != "undefined") {
			if (form.elements) {
				return true;
			}
		}
		return false;
	}
	
	function isHTMLText(element) {
		if (typeof(element) != "undefined") {
			return (element.type && element.type == "text");
		}
		return false;
	}
	
	function isHTMLFile(element) {
		if (typeof(element) != "undefined") {
			return (element.type && element.type == "file");
		}
		return false;
	}
	
	function isHTMLHidden(element) {
		if (typeof(element) != "undefined") {
			if (element.type) {
				return (element.type == "hidden");
			}
		}
		return false;
	}

	function isHTMLSelect(list) {
		if (typeof(list) != "undefined") {
			if (list.options) {
				return true;
			}
		}
		return false;
	}
	
	function isHTMLSelectMultiple(list) {
		if (isHTMLSelect(list)) {
			return (list.type == "select-multiple");
		}
		return false;
	}
	
	function isHTMLCheckbox(box) {
		if (typeof(box) != "undefined") {
			if (box.type == "checkbox") {
				return true;
			}
		}
		return false;
	}
	
	function isHTMLTextArea(area) {
		if (typeof(area) != "undefined") {
			if (area.type == "textarea") {
				return true;
			}
		}
		return false;
	}
	
	function isHTMLRadio(radio) {
		if (typeof(radio) != "undefined") {
			if (radio.type == "radio") {
				return true;
			}
		}
		return false;
	}
	
	function getFormInput(form, name, value) {
		if (isHTMLForm(form)) {
			var i;
			for (i=0;i<form.length;i++) {
				var element = form.elements[i];
				if (element.name == name) {
					if (typeof(value) == "undefined" ||
							(typeof(value) != "undefined" && element.value == value)) {
						return element;
					}
				}
			}
		}
		return null;
	}
	
	function getFormElementIndex(input) {
		if (isHTMLForm(input.form)) {
			var form = input.form;
			for (var i=0;i<form.length;i++) {
				if (form.elements[i] == input) {
					return i;
				}
			}
		}
		return -1;
	}
	
	// HTML Checkbox functions
	function getSelectedCheckboxGroupValues(form, groupName) {
		if (isHTMLForm(form)) {
			values = new Array();
			for (var i=0;i<form.length;i++) {
				var element = form.elements[i];
				if (isHTMLCheckbox(element) && element.name == groupName && element.checked) {
					values[values.length] = element.value;
				}
			}
			return values;
		}
		return null;
	}
	
	function getGroupedCheckboxes(form, groupName) {
		if (isHTMLForm(form)) {
			boxes = new Array();
			for (var i=0;i<form.length;i++) {
				var element = form.elements[i];
				if (isHTMLCheckbox(element) && element.name == groupName) {
					boxes[boxes.length] = element;
				}
			}
			return boxes;
		}
		return null;
	}
	
	function selectAllCheckboxGroup(form, groupName, selectAll) {
		var group = getGroupedCheckboxes(form, groupName);
		if (group != null) {
			for (var i=0;i<group.length;i++) {
				var box = group[i];
				box.checked = selectAll;
			}
		}
	}
	
	// HTML Radio functions
	function getSelectedRadioValue(form, name) {
		if (isHTMLForm(form)) {
			for (var i=0;i<form.length;i++) {
				var element = form.elements[i];
				if (isHTMLRadio(element) && element.name == name && element.checked) {
					return element.value;
				}
			}
		}
		return null;
	}

	function selectRadioButton(form, name, value) {
		var element = getFormInput(form, name, value);
		if (isHTMLRadio(element)) {
			element.checked = true;
		}
	}

	// HTML Select functions
	function insertToList(fromList, toList) {
		if (fromList == null || toList == null) {
			return false;
		}
		var selected = getSelectedOptions(fromList);
		if (selected.length > 0) {
			// Get old options
			var selectedIndex = getFirstSelectedIndex(toList);
			var moveItems = new Array();
			if (toList.length > 0 && selectedIndex > -1) {
				for (i=selectedIndex;i<toList.length;i++) {
					moveItems[moveItems.length] = toList.options[i];
				}
			}
			// Insert new options
			var index = (selectedIndex > -1) ? selectedIndex : toList.length;
			for (i=0;i<selected.length;i++) {
				var insert = index + i;
				var fromOption = selected[i];
				var option = new Option();
				option.text = fromOption.text;
				option.value = fromOption.value;
				toList.options[insert] = option;
			}
			// Insert old options
			for (a=0;a<moveItems.length;a++) {
				var insert = index + selected.length + a;
				var fromOption = moveItems[a]; 
				var option = new Option();
				option.text = fromOption.text;
				option.value = fromOption.value;
				toList.options[insert] = option;
			}
			if (selectedIndex > -1) {
				toList.selectedIndex = selected.length + selectedIndex;
			}
			return true;
		}
		return false;
	}
	
	function removeFromList(list) {
		if (list != null) {
			if (list.selectedIndex > -1) {
				for (i=0;i<list.length;i++) {
					if (list.options[i].selected) {
						list.options[i] = null;
						i --;
					}
				}
				list.selectedIndex = -1;
			}
			return true;
		}
		return false;
	}
	
	function moveUp(list) {
		var selected = getSelectedOptions(list);
		var selectedIndexes = getSelectedIndexes(list);
		if (list.selectedIndex > 0 && selected.length > 0) {
			if (selectedIndexes.length > 1) {
				for (i=1;i<selectedIndexes.length;i++) {
					if (selectedIndexes[i] - selectedIndexes[i - 1] > 1) {
						return;
					}
				}
			}
			var selectedIndex = getFirstSelectedIndex(list);
			var option = new Option();
			option.text = list.options[selectedIndex - 1].text;
			option.value = list.options[selectedIndex - 1].value;
			for (i=0;i<selected.length;i++) {
				var index = selectedIndex - 1 + i;
				var option1 = new Option();
				option1.text = selected[i].text;
				option1.value = selected[i].value;
				option1.selected = true;
				list[index] = option1;
			}
			list[selectedIndex + selected.length - 1] = option;
		}
	}
	
	function moveDown(list) {
		var selected = getSelectedOptions(list);
		var selectedIndexes = getSelectedIndexes(list);
		if (selected.length > 0 && list.selectedIndex > -1 && list.selectedIndex + selected.length - 1 < list.length - 1) {
			if (selectedIndexes.length > 1) {
				for (i=1;i<selectedIndexes.length;i++) {
					if (selectedIndexes[i] - selectedIndexes[i - 1] > 1) {
						return;
					}
				}
			}
			var selectedIndex = getFirstSelectedIndex(list);
			var option = new Option();
			option.text = list.options[selectedIndex + selected.length].text;
			option.value = list.options[selectedIndex + selected.length].value;
			for (i=0;i<selected.length;i++) {
				var index = selectedIndex + 1 + i;
				var option1 = new Option();
				option1.text = selected[i].text;
				option1.value = selected[i].value;
				option1.selected = true;
				list[index] = option1;
			}
			list[selectedIndex] = option;
		}
	}
	
	function getSelectedOptions(list) {
		var selected = [];
		if (typeof(list) == "object" && list.options) {
			if (list.selectedIndex > -1) {
				var selected = new Array();
				for (i=0;i<list.length;i++) {
					var option = list.options[i];
					if (option.selected) {
						selected[selected.length] = option;
					}
				}
			}
		}
		return selected;
	}
	
	function getSelectedIndexes(list) {
		var selected = [];
		if (typeof(list) == "object" && list.options) {
			if (list.selectedIndex > -1) {
				var selected = new Array();
				for (i=0;i<list.length;i++) {
					var option = list.options[i];
					if (option.selected) {
						selected[selected.length] = i;
					}
				}
			}
		}
		return selected;
	}
	
	function getFirstSelectedIndex(list) {
		return getSelectedIndex(list, 0);
	}
	
	function getSelectedIndex(list, start) {
		var index = -1;
		if (typeof(list) == "object" && list.options) {
			if (typeof(start) != "undefined") {
				if (start < 0) {
					start = 0;
				} else if (start > list.length - 1) {
					return index;
				}
			} else {
				start = 0;
			}
			for (i=start;i<list.length;i++) {
				var element = list.options[i];
				if (element.selected) {
					index = i;
					break;
				}
			}
		}
		return index;
	}
	
	function selectOptionText(list, text) {
		var indexes = findOptionText(list, text);
		if (indexes != null) {
			list.selectedIndex = -1;
			for (var i=0;i<indexes.length;i++) {
				var index = indexes[i];
				list.options[index].selected = true;
				if (!isHTMLSelectMultiple(list)) {
					return;
				}
			}
		}
	}
	
	function selectOptionValue(list, value) {
		var indexes = findOptionValue(list, value);
		if (indexes != null) {
			list.selectedIndex = -1;
			for (var i=0;i<indexes.length;i++) {
				var index = indexes[i];
				list.options[index].selected = true;
				if (!isHTMLSelectMultiple(list)) {
					return;
				}
			}
		}
	}
	
	function findOptionValue(list, value) {
		var indexes = null;
		if (isHTMLSelect(list)) {
			indexes = new Array();
			for (var i=0;i<list.length;i++) {
				if (list.options[i].value == value) {
					indexes[indexes.length] = i;
				}
			}
		}
		return indexes;
	}
	
	function findOptionText(list, text) {
		var indexes = null;
		if (isHTMLSelect(list)) {
			indexes = new Array();
			for (var i=0;i<list.length;i++) {
				if (list.options[i].text == text) {
					indexes[indexes.length] = i;
				}
			}
		}
		return indexes;
	}
	
	// For multiple select list
	function selectAllOptions(list, select) {
		// If "select" is not provided, follow the meaning of the function's name
		select = (typeof(select) == "undefined") ? true : select;
		if (isHTMLSelect(list)) {
			if (!select) {
				list.selectedIndex = -1;
			} else {
				var i;
				for (i=0;i<list.length;i++) {
					list.options[i].selected = select;
				}
			}
		}
	}

	function resetInputFile(oldFile) {
		if (isHTMLFile(oldFile) && DOM) {
			var form = oldFile.form;
			var inputName = oldFile.name;
			// We have to find the DOM node in order to do replaceChild()
			// otherwise, it would complain child/object not found
			var nodes = document.getElementsByName(inputName);
			for (var n=0; n<nodes.length; n++) {
				var node = nodes[n];
				if (node.tagName.toLowerCase() == "input" && node.getAttribute("type") == "file") {
					var newFile = document.createElement("INPUT");
					newFile.type = "file";
					if (IE4) {
						newFile.mergeAttributes(node, false);
					} else {
						for (var a=0; a<node.attributes.length; a++) {
							var attr = node.attributes[a];
							if (attr.nodeName != "value" && attr.nodeName != "height" && attr.nodeValue != null) {
								newFile.setAttribute(attr.nodeName, attr.nodeValue);
							}
						}
					}
					var parentNode = node.parentNode;
					try {
						parentNode.replaceChild(newFile, node);
						return true;
					} catch (e) {
					}
					break;
				}
			}
		}
		return false;
	}
	
	function resetInputFiles(form) {
		if (isHTMLForm(form)) {
			if (DOM) {
				var formLength = form.length;
				for (var e=0;e<formLength;e++) {
					var element = form.elements[e];
					if (isHTMLFile(element)) {
						resetInputFile(element);
					}
				}
			} else {
				// record values
				var dupForm = {};
				for (var e=0; e<form.length; e++) {
					var element = form.elements[e];
					var elementName = element.name;
					var elementType = element.type;
					if (elementType != "file") {
						var elementValues = new Array();
						if (dupForm[elementName]) {
							elementValues = dupForm[elementName];
						}
						if (elementType == "select-one") {
							elementValues[elementValues.length] = element.selectedIndex;
						} else if (elementType == "select-multilpe") {
							for (var p=0; p<element.length; p++) {
								var option = element.options[p];
								if (option.selected) {
									elementValues[elementValues.length] = p;
								}
							}
						} else if (elementType == "checkbox" || elementType == "radio") {
							if (element.checked) {
								elementValues[elementValues.length] = element.value;
							}
						} else {
							// anything else, text, hidden, textarea, etc
							elementValues[elementValues.length] = element.value;
						}
						dupForm[elementName] = elementValues;
					}
				}
				form.reset();
				// Put values back
				for (e=0; e<form.length; e++) {
					element = form.elements[e];
					elementName = element.name;
					elementType = element.type;
					if (elementType != "file") {
						if (dupForm[elementName]) {
							elementValues = dupForm[elementName];
							if (elementType == "select-one") {
								if (elementValues[0] < element.length) {
									element.selectedIndex = elementValues[0];
								}
							} else if (elementType == "select-multiple") {
								for (p=0; p<elementValues.length; p++) {
									var index = elementValues[p];
									if (index < element.length) {
										element.options[index].selected = true;
									}
								}
							} else if (elementType == "checkbox" || elementType == "radio") {
								if (arrayContains(elementValues, element.value)) {
									element.checked = true;
								}
							} else if (elementType != "reset" && elementType != "button" && elementType != "submit") {
								// anything else
								element.value = elementValues[0];
								elementValues[0] = null;
								dupForm[elementName] = elementValues;
							}
						}
					}
				}
			}
		}
	}

	// Style functions
	function setStyleDisplay(obj, display) {
		if (typeof(obj) == "string") {
			var obj = getElementById(obj);
		} else if (typeof(obj) != "object") {
			return;
		}
		if (obj != null && obj.tagName) {
			if (DOM || IE4) {
				obj.style.display = display ? "inline" : "none";
			} else if (NN4) {
				value = !display ? "hide" : "inherit";
				obj.visibility = value;
			}
		}
	}
	
	function getStyleDisplay(id) {
		var obj = getElementById(id);
		if (obj != null) {
			if (DOM || IE4) {
				return obj.style.display;
			} else if (NN4) {
				return obj.visibility;
			}
		}
		return "";
	}
	
	function getStyleDisplayBool(id) {
		var display = getStyleDisplay(id);
		return (display != "none" && display != "hide");
	}

	function focusFirstChildInput(element) {
		if (typeof(element) == "object") {
			var inputs = element.getElementsByTagName("INPUT");
			for (var t=0;t<inputs.length;t++) {
				var input = inputs[t];
				if (input.type.indexOf("text") == 0 || input.type.indexOf("select") == 0) {
					input.focus();
					break;
				}
			}
		}
	}
	
	function getImageByName(name) {
		if (IE4) {
			return document.images[name];
		} else if (DOM) {
			var imgs = document.getElementsByName(name);
			if (imgs.length > 0) {
				return imgs[0];
			}
		} else if (NN4) {
			return document[name];
		}
		return null;
	}
	
	function removeAllChildNodes(node) {
		if (DOM) {
			while (true) {
				if (node.childNodes.length > 0) {
					node.removeChild(node.childNodes[0]);
				} else {
					break;
				}
			}
		}
	}
	
	function copyChildNodes(fromNode, toNode, replaceChildNodes) {
		if (DOM) {
			if (typeof(fromNode) == "object" && typeof(toNode) == "object") {
				if (replaceChildNodes) {
					removeAllChildNodes(toNode);
				}
				for (var c=0;c<fromNode.childNodes.length;c++) {
					toNode.appendChild(fromNode.childNodes[c].cloneNode(true));
				}
			}
		}
	}
	
	function getChildNodeIndex(element) {
		var i = -1;
		if (DOM && typeof(element) == "object") {
			if (element.parentNode != null) {
				for (var c=0;c<element.parentNode.childNodes.length;c++) {
					if (element.parentNode.childNodes[c] == element) {
						i = c;
						break;
					}
				}
			}
		}
		return i;
	}
	
	function searchParentNodeByTagName(element, parentTagName) {
		var n = null;
		if (typeof(element) == "object" && element.parentNode) {
			n = element;
			while (true) {
				if (n.parentNode != null) {
					n = n.parentNode;
					if (n.tagName == parentTagName) {
						break;
					}
				} else {
					n = null;
					break;
				}
			}
		}
		return n;
	}
	
	function getElementById(id) {
		if (DOM) {
			return document.getElementById(id);
		} else if (IE4) {
			return document.all(id);
		} else if (NN4) {
			return document.layers[id];
		}
		return null;
	}
