// $Revision: 2893 $
var isIE = document.all != null;
var isMozilla = window.navigator != null && window.navigator.appName == "Netscape";
var isWebKit = window.navigator != null && window.navigator.userAgent.indexOf("WebKit") >= 0;

if (isIE) {
    var agt = window.navigator.userAgent.toLowerCase();
    var iePos = agt.indexOf('msie');
    var ieVersion = parseInt(agt.substring(iePos + 5, agt.indexOf(';', iePos)));
}

// Set by application
var LOADSCRIPT_URL = "GetScript.dynamic";
var DO_OPEN_EXTERNAL_WINDOWS = true;
var TARGET_EXTERNAL = null;
var TARGET_PDF = null;
var TARGET_APP = null;

// ErrorReporter object
function ErrorReporter() {
	this.enabled = new Object();
	this.enabled["Util.js"] = true;
	this.enabled["Form.js"] = true;
	this.enabled["OpenClose.js"] = true;
	this.enabled["Dialog.js"] = true;
	this.enabled["Profile.js"] = true;
	this.enabled["Validation.js"] = true;
	this.enabled["LoadScript.js"] = true;
	this.enabled["DynamicUpdate.js"] = false;
}

// examples:
//  errorReporter.Report("Util.js", "TogglePane: containerId '" + containerId + "' not found.");
//  errorReporter.Report("Util.js", "SetTextSize(\"" + size + "\")", e);
ErrorReporter.prototype.Report = function(fileName, message, exception) {
	var isEnabled = this.enabled[fileName];
	if (isEnabled == null || isEnabled == true) {
		var msg = fileName + " Error:\n\n";
		if (exception) {
			msg += exception.name + ": " + exception.message + "\n";
		}
		msg += message;
		alert(fold(msg));
		Busy(false);
	}
}

// global error reporter for all JavaScript
var errorReporter = new ErrorReporter();

// Url object
function Url(urlstring) {
	this.url = urlstring;
	this.length = urlstring.length;
}

Url.prototype.Uri = function() {
	var qPos = this.url.indexOf('?');
	return (qPos < 0) ? this.url : this.url.substring(0, qPos);
}

Url.prototype.QueryString = function() {
	var qPos = this.url.indexOf('?');
	return (qPos < 0) ? "" : this.url.substring(qPos + 1);
}

Url.prototype.toString = function() {
	return this.url;
}

// value is either a single value:
//   return url + ('?' or '&') + 'name=value'
// or an array of values:
//   return url + ('?' or '&') + 'name=value[1]' + '&' + 'name=value[2]' + ...
Url.prototype.Append = function(name, value) {
	if (arguments.length < 2) {
		return this.url;
	}
	if (Array.prototype.isPrototypeOf(value)) {
		for (var i = 0; i < value.length; i++) {
			this.Append(name, value[i]);
		}
	} else {
		if (this.url.indexOf('?') < 0) {
			this.url += '?';
		} else if (this.url.substring(this.url.length - 1) != "&") {
			this.url += '&';
		}
		this.url += encodeURIComponent(name) + '=' + encodeURIComponent(value.toString());
	}
	this.length = this.url.length;
    return this.url;
}

Url.prototype.AppendElementValues = function(element) {
	var name = element.name;
	if (name == null) {
		return this.url;
	}
	return this.Append(name, getFormElementValues(element));
}

Url.prototype.AppendFormParams = function(form, formParams) {
	// if no formParams, append all the form's parameter values
	if (formParams == null || formParams.length == 0) {
		for (var i = 0; i < form.elements.length; i++) {
			this.AppendElementValues(form.elements[i]);
		}
	} else {
		for (var i = 0; i < formParams.length; i++) {
			this.Append(formParams[i], getFormParameterValues(form, formParams[i]));
		}
	}
	return this.url;
}

// Append dynamic=<random number> to url - Identify this as a dynamic request.
// The random number makes the URL unique, so that the browser fetches the
// contents regardless of the cache mode (problem seen on IE6).
Url.prototype.MakeDynamic = function() {
	return this.Append("dynamic", Math.random());
}

// IdsBySubstring object
function IdsBySubstring() {
    this.currentIndex = 0;
    this.currentSubstring = "";
}

IdsBySubstring.prototype.AddIds = function() {
    var i;
    for (i = 0; i < arguments.length; i += 2) {
        substring = arguments[i].toLowerCase();
        id = unEscape(arguments[i + 1]);
        if (this[substring] == null) {
            this[substring] = new Array(id);
        } else {
            this[substring].push(id);
        }
    }
}

IdsBySubstring.prototype.GetId = function(substring) {
    substring = substring.toLowerCase();
    if (substring != this.currentSubstring) {
        this.currentSubstring = substring;
        this.currentIndex = 0;
    }
    return this.GetNextId(substring);
}

IdsBySubstring.prototype.HasNext = function() {
    var a = this[this.currentSubstring];
    if (a == null) {
        return false;
    }
    if (a.length <= this.currentIndex) {
        return false;
    }
    return true;
}

IdsBySubstring.prototype.GetNextId = function(substring) {
    if (substring == null) {
        substring = this.currentSubstring;
    }
    var a = this[substring];
    if (a == null) {
        return null;
    }
    if (a.length <= this.currentIndex) {
        return null;
    }
    return a[this.currentIndex++];
}

function InputKeyup(ibs, ancestorId, containerId, nextButtonId, event) {
    if (event == null) {
        event = window.event;
    }
    var inp = GetTarget(event);
    var id = ibs.GetId(inp.value);
    if (id != null) {
        ScrollIntoViewAbsolute(containerId, false, 10);
        ScrollIntoView(id, ancestorId, containerId, 0, true);
    }
    var nextButton = getElement(unEscape(nextButtonId));
    if (nextButton != null) {
        nextButton.disabled = !ibs.HasNext();
    }
    if (event.stopPropagation) {
        event.stopPropagation();
    } else {
        event.cancelBubble = true;
    }
}

function Next(ibs, ancestorId, containerId, nextButtonId, event) {
    if (event == null) {
        event = window.event;
    }
    var id = ibs.GetNextId();
    if (id != null) {
        ScrollIntoViewAbsolute(containerId, false, 10);
        ScrollIntoView(id, ancestorId, containerId, 0, true);
    }
    var nextButton = getElement(unEscape(nextButtonId));
    nextButton.disabled = !ibs.HasNext();

    if (event.stopPropagation) {
        event.stopPropagation();
    } else {
        event.cancelBubble = true;
    }
}

function GetPageWidth() {
	if (window.top.document.documentElement && window.top.document.documentElement.clientWidth !== undefined) {
		return window.top.document.documentElement.clientWidth;
	}
	return 0;
}

function GetPageHeight() {
	if (window.top.document.documentElement && window.top.document.documentElement.clientHeight !== undefined) {
		return window.top.document.documentElement.clientHeight;
	}
	return 0;
}

function GetScrollLeft() {
	if (window.top.pageXOffset !== undefined) {
		return window.top.pageXOffset;
	} else if (window.top.document.documentElement.scrollLeft !== undefined && window.top.document.documentElement.scrollLeft > 0) {
		return window.top.document.documentElement.scrollLeft;
	} else if (window.top.document.body.scrollLeft !== undefined) {
		return window.top.document.body.scrollLeft;
	}
	return 0;
}

function GetScrollTop() {
	if (window.top.pageYOffset !== undefined) {
		return window.top.pageYOffset;
	} else if (window.top.document.documentElement.scrollTop !== undefined && window.top.document.documentElement.scrollTop > 0) {
		return window.top.document.documentElement.scrollTop;
	} else if (window.top.document.body.scrollTop !== undefined) {
		return window.top.document.body.scrollTop;
	}
	return 0;
}

function GetScrollWidth() {
	if (window.top.document.documentElement && window.top.document.documentElement.scrollWidth !== undefined) {
		return window.top.document.documentElement.scrollWidth;
	} else if (window.top.document.body.scrollWidth > window.top.document.body.offsetWidth) {
		return window.top.document.body.scrollWidth;
	} else {
		return window.top.document.body.offsetWidth;
	}
}

function GetScrollHeight() {
	if (window.top.document.documentElement && window.top.document.documentElement.scrollHeight !== undefined) {
		return window.top.document.documentElement.scrollHeight;
	} else if (window.top.document.body.scrollHeight > window.top.document.body.offsetHeight) {
		return window.top.document.body.scrollHeight;
	} else {
		return window.top.document.body.offsetHeight;
	}
}

function ScrollIntoView(elementId, ancestorId, containerId, offset, top, delay) {
	if (offset == null) {
		offset = 0;
	}
	if (delay != null) {
		var ancestorIdString = (ancestorId == null) ? "null" : ancestorId;
		var containerIdString = (containerId == null) ? "null" : containerId;
		var offsetString = (offset == null) ? "null" : offset;
		var topString = (top == null) ? "false" : top.toString();
		var command = "ScrollIntoView('" + elementId + "', '" + ancestorIdString + "', '" + containerIdString + "', " + offsetString + ", " + topString  + ")";
		window.setTimeout(command, delay);
		return;
	}
	var container;
	if (elementId == null) {
		if (containerId == null) {
			return;
		}
		// scroll container to top
		container = getElement(unescape(containerId));
		container.scrollTop = 0;
		return;
	}
	var elem = getElement(unescape(elementId));
	if (elem == null) {
		return;
	}
	if (containerId == null) {
		if (offset != 0 && top) {
			offset = -offset;
		}
		elem.scrollIntoView(top);
		if (offset != 0) {
			window.scrollBy(0, offset);
		}
		return;
	}
	container = getElement(unescape(containerId));
	if (container == null) {
		return;
	}
	var ancestor;
	if (ancestorId == null) {
		return;
	}
	ancestor = getElement(unescape(ancestorId));
	if (ancestor == null) {
		return;
	}
	var ancestorTop = AbsTop(ancestor, true);
	var elementTop = AbsTop(elem, true);
	var containerTop = AbsTop(container, true);

	var relTop = elementTop - ancestorTop;
	container.scrollTop = relTop - offset;
	return;
}

function ScrollIntoViewAbsolute(id, top, offset, delay) {
	if (delay != null) {
		var topString = (top == null) ? "false" : top.toString();
		var command = "ScrollIntoViewAbsolute(\"" + id + "\", " + topString + ", " + offset + ")";
		window.setTimeout(command, delay);
		return;
	}
	var elem = getElement(id);
	if (elem == null) {
		return;
	}
	DoScrollIntoViewAbsolute(elem, top, offset);
}

function DoScrollIntoViewAbsolute(elem, top, offset) {
	if (offset == null) {
		offset = 0;
	}
	var offsetTop = elem.offsetTop;
	var parent = elem;
	while (parent.offsetParent != null) {
		parent = parent.offsetParent;
		offsetTop += parent.offsetTop;
	}
	var scrollTop = GetScrollTop(); 
	var scrollLeft = GetScrollLeft(); 
	var pageHeight = GetPageHeight();
	var offsetHeight = 0;
	if (!top) {
		offsetHeight = elem.offsetHeight;
	} 
	if (offsetTop + offsetHeight > scrollTop && offsetTop + offsetHeight < scrollTop + pageHeight - offset) {
		// more than offset is already visible
	} else if (offsetTop + offsetHeight > scrollTop + pageHeight - offset) {
		// off screen at the bottom, or less than offset visible
		window.scrollTo(scrollLeft, offsetTop + offsetHeight + offset - pageHeight);
	} else if (offsetTop < scrollTop) {
		// off screen at the top
		window.scrollTo(scrollLeft, offsetTop + offsetHeight - offset);
	}
}

function ScrollParentIntoView(id, top) {
	var object = getElement(id);
	if (object != null) {
		var parent = object.parentNode;
		if (parent != null) {
			parent.scrollIntoView(top);
		}
	}
}

function SetScrollTop(id, scrollTop) {
	if (id == null) {
		if (window.top.document.documentElement && window.top.document.documentElement.scrollTop !== undefined) {
			window.top.document.documentElement.scrollTop = scrollTop;
		}
	} else {
		var object = getElement(id);
		if (object != null) {
			object.scrollTop = scrollTop;
		}
	}
}

function IsVisible(id, doRecurse) {
	var element = getElement(id);
	if (element == null) {
		return false;
	}
	return IsVisibleElement(element, doRecurse);
}

function IsVisibleElement(element, doRecurse) {
	if (element == null) {
		return false;
	}
    var visible = (element.style == null) || (element.style.display != "none" && element.style.visibility != "hidden");
    if (!visible || !doRecurse) {
        return visible;
    }
    var parent = element.parentNode;
    return (parent == null) || IsVisibleElement(parent, true);
}

function Display(id, doDisplay) {
	try {
		var element = getElement(id);
		if (element == null) {
			return;
		}
		DoDisplay(element, doDisplay);
	} catch(e) {
		Busy(false);
		errorReporter.Report("Util.js", "Display('" + id + "', " + doDisplay + ")");
	}
}

function DoDisplay(element, doDisplay) {
	try {
		element.style.display = doDisplay ? "" : "none";
	} catch(e) {
		Busy(false);
		errorReporter.Report("Util.js", "DoDisplay(element '" + element.id + "', " + doDisplay + ")");
	}
}

function Disable(id, doDisable) {
	try {
		var element = getElement(id);
		if (element == null) {
			return;
		}
		DoDisable(element, doDisable);
	} catch(e) {
		Busy(false);
		errorReporter.Report("Util.js", "Disable('" + id + "', " + doDisable + ")");
	}
}

function DoDisable(element, doDisable) {
	try {
		element.disabled = doDisable;
	} catch(e) {
		Busy(false);
		errorReporter.Report("Util.js", "DoDisable(element '" + element.id + "', " + doDisable + ")");
	}
}

function escape(s) {
	if (s != null) {
		return(s.replace(/\\/g, "\\\\").replace(/'/g, "\\'"));
	} else {
		return(s);
	}
}

function unEscape(s) {
	if (s != null) {
		return(s.replace(/\\'/g, "'").replace(/\\\\/g, "\\"));
	} else {
		return(s);
	}
}

// get the element in this or the top window
function getElement(id) {
	id = unEscape(id);
	var element = document.getElementById(id);
	if (element == null && window.top != null && window.top != window.self) {
		element = window.top.document.getElementById(id);
	}
    return element;
}

function DisplayInTop() {
	if (window.top != self) {
		window.top.location = location;
	}
}

var WINDOW_FEATURES = "";

function OpenExternalWindow(url, target, doForceExternal) {
	if (url.match(/\.pdf$/) != null && !IsPDFReaderInstalled()) {
		window.top.location = url;
		return;
	}
	if (!doForceExternal && !DO_OPEN_EXTERNAL_WINDOWS) {
		window.top.location = url;
		return;
	}
	if (target == "TARGET_EXTERNAL") {
		target = TARGET_EXTERNAL;
	} else if (target == "TARGET_PDF") {
		target = TARGET_PDF;
	} else if (target == "TARGET_APP") {
		target = TARGET_APP;
		if (target == null) {
			var query = window.location.search;
			if (query != null && query.length > 0) {
				var a = query.split(/[?&]/);
				for (var i = 0; i < a.length; i++) {
					var b = a[i].split("=");
					if (b[0] == "TARGET_APP") {
						target = TARGET_APP = b[1];
						break;
					}
				}
			}
		}
	}
	win = window.open(url, target, WINDOW_FEATURES, false);
	if (win == null) {
		alert(fold("Cannot open external window. Do you have a popup blocker enabled?"));
		return false;
	}
	if (window.focus) {
		try {
			win.focus();
		} catch (e) {
			// never mind (Adobe Reader 7.05 bug)
		}
	}
	return false;
}

function IsPDFReaderInstalled() {
	if (navigator.mimeTypes && navigator.mimeTypes["application/pdf"]) {
		return navigator.mimeTypes["application/pdf"].enabledPlugin != null;
	} else if (window.ActiveXObject) {
		for (x = 2; x < 10; x++) {
			try {
				oAcro = eval("new ActiveXObject('PDF.PdfCtrl." + x + "');");
				if (oAcro) {
					return true;
				}
			} catch(e) {}
		}
		try {
			oAcro4 = new ActiveXObject('PDF.PdfCtrl.1');
			if (oAcro4) {
				return true;
			}
		} catch(e) {}
		try {
			oAcro7 = new ActiveXObject('AcroPDF.PDF.1');
			if (oAcro7) {
				return true;
			}
		} catch(e) {}
	}
	return false;
}

function detectNS(ClassID, name) {
	var n = "";
	if (nse.indexOf(ClassID) != -1) if (navigator.mimeTypes[ClassID].enabledPlugin != null) n = name + ","; return n;
}

function Maximize() {
	var message = "Maximize: window.screen.availWidth = " + window.screen.availWidth + " window.screen.availHeight = " + window.screen.availHeight;
	try {
		window.moveTo(0, 0);
		// window.top.status = message;
		window.resizeTo(window.screen.availWidth, window.screen.availHeight);
	} catch (e) {
		// errorReporter.Report("Util.js", message);
	}
}

var globalResizeTimeout = null;
var globalPageWidth = 0;
var globalPageHeight = 0;
var globalScreenWidth = 0;
var globalPageWidth0 = -1;
var globalMapPanelContainerWidth0 = -1;

function Resize(event) {
    if (event == null) {
        event = window.event;
    }
	// General independent resize code
	var resizeFunctions = null;
	
	// Map-dependent resize code
	var map = getElement("mapimg_id");
	if (map != null && globalMapPanelContainer != null) {
		// Map-dependent resize code to be run on every resize event
		if (globalMapPanelContainerWidth0 == -1) {
			globalMapPanelContainerWidth0 = globalMapPanelContainerWidth;
		}
		globalMapPanelContainerWidth = globalMapPanelContainer.offsetWidth;
		if (globalMapPanelContainerWidth > 0 && globalMapPanelContainerWidth != globalMapPanelContainerWidth0) {
			InitializeMap(globalMapPanelContainerWidth - GetMapMargin());
		}
			
		// Map-dependent resize code to be run on resize mouse up
		resizeFunctions = "ChangeWidth(true);";
	} else {
		globalPageWidth0 = globalPageWidth;
		resizeFunctions = "ChangeWidth(false);";
	}
	
	// Dialog-dependent resize code
	if (Dialogs.getDialogByPropertyValue("isModal", true) != null) {
		resizeFunctions += "SetDialogBackdropWidth();";
	}
	
	if (isIE || isWebKit) {
		// on IE and WebKit browsers, repetitive resize events as long as resizing continues.
		if (globalResizeTimeout != null) {
			// replace scheduled startmap
			window.clearTimeout(globalResizeTimeout);
			globalResizeTimeout = null;
		}
		// schedule resize functions - only the last scheduled instance actually runs
		globalResizeTimeout = window.setTimeout(resizeFunctions, 500);
	} else {
		// on Mozilla, only one resize event, on mouse up.
		eval(resizeFunctions);
	}
	return Finish(event);
}

function SetScreenWidth() {
	var screenWidth = window.screen.width;
	if (globalScreenWidth != screenWidth) {
		SetWidth(null, null, screenWidth);
		StartMap(CurrentMapMode);
	}
}

function SetWidth(pageWidth, pageHeight, screenWidth) {
	if (pageWidth == null) {
		pageWidth = GetPageWidth();
	}
	if (pageHeight == null) {
		pageHeight = GetPageHeight();
	}
	if (screenWidth == null) {
		screenWidth = window.screen.width;
	}
	if (globalPageWidth != pageWidth || globalPageHeight != pageHeight || globalScreenWidth != screenWidth) {
		globalPageWidth = pageWidth;
		globalPageHeight = pageHeight;
		globalScreenWidth = screenWidth;
		var url = new Url(LOADSCRIPT_URL);
		url.Append("command", "setwidth");
		url.Append("windowwidthpx", pageWidth);
		url.Append("windowheightpx", pageHeight);
		url.Append("screenwidthpx", screenWidth);
		url.Append("doupdatetabs", "true");
		LoadScript(url.toString());
	}
}

function ChangeWidth(doStartMap) {
	if (doStartMap) {
		if (globalMapPanelContainerWidth0 != globalMapPanelContainerWidth) {
			// Startmap does what SetWidth does, as a side effect
			StartMap(CurrentMapMode);
		}
	} else {
		globalPageWidth = GetPageWidth();
		if (globalPageWidth0 != globalPageWidth) {
			SetWidth();
		}
	}
	// window.top.status = GetPageWidth();
	globalPageWidth0 = -1;
	globalMapPanelWidth0 = -1;
	globalMapPanelContainerWidth0 = -1;
}

function SetContainerWidth(id) {
	if (id == null) {
		return;
	}
	var elem = getElement(id);
	if (elem != null && elem.parentNode != null && elem.parentNode.offsetWidth != null) {
		var w = elem.parentNode.offsetWidth;
		elem.style.width = w + "px";
	}
}

function fold(s) {
	var len = 80;
	var out = "";
	var sa = s.split(/\n/);
	var i;
	var start;
	for (i = 0; i < sa.length; i++) {
		if (sa[i].length <= len) {
			out += (sa[i] + "\n");
		} else {
			start = 0;
			do {
				if (sa[i].length - start <= len) {
					out += sa[i].substring(start) + "\n";
				} else {
					out += sa[i].substring(start, start + len) + "\n";
				}
				start += len;
			} while (start < sa[i].length);
		}
	}
	return out;
}

var BUSY_BACKDROP_ID = "busybackdropid";
var BUSY_BACKDROP_IMG_ID = "busybackdropimgid";
var BUSY_BACKDROP_IFRAME_ID = "busybackdropiframeid";
var BUSY_IMG_ID = "busybackdropimgid";
var MESSAGE_CONTAINER_ID = "messagecontainerid";
var MESSAGE_H_ID = "messagehid";
var globalBusyCounter = 0;

function Busy(doBusy, message) {
	var busyBackdrop = getElement(BUSY_BACKDROP_ID);
	if (busyBackdrop == null) {
		return;
	}
	busyBackdropImg = getElement(BUSY_BACKDROP_IMG_ID);
	busyBackdropIframe = getElement(BUSY_BACKDROP_IFRAME_ID);
	if (doBusy) {
		globalBusyCounter++;
		cancelScripts.Add("Busy(false)");
		busyBackdrop.style.visibility = "visible";
		var pageWidth = GetPageWidth();
		var scrollWidth = GetScrollWidth();
		var width = Math.max(scrollWidth, pageWidth);
		busyBackdrop.style.width = width + "px";
		var scrollHeight = GetScrollHeight();
		var pageHeight = GetPageHeight();
		var height = Math.max(scrollHeight, pageHeight);
		busyBackdrop.style.height = height + "px";
		if (busyBackdropImg != null) {
			busyBackdropImg.style.width = width + "px";
			busyBackdropImg.style.height = height + "px";
		}
		if (busyBackdropIframe != null) {
			busyBackdropIframe.style.width = width + "px";
			busyBackdropIframe.style.height = height + "px";
		}
		SetBusyMessage(doBusy, message);
	} else {
		globalBusyCounter = Math.max(globalBusyCounter - 1, 0);
		if (globalBusyCounter == 0) {
			window.setTimeout("cancelScripts.RemoveAll()", 0);
			if (busyBackdropImg != null) {
				busyBackdropImg.style.width = "0px";
				busyBackdropImg.style.height = "0px";
			}
			if (busyBackdropIframe != null) {
				busyBackdropIframe.style.width = "0px";
				busyBackdropIframe.style.height = "0px";
			}
			busyBackdrop.style.width = "0px";
			busyBackdrop.style.height = "0px";
			busyBackdrop.style.visibility = "hidden";
			SetBusyMessage(doBusy, null);
		}
	}	
}

function SetBusyMessage(doBusy, message) {
	var messageContainer = getElement(MESSAGE_CONTAINER_ID);
	var messageH = getElement(MESSAGE_H_ID);
	if (messageContainer == null) {
		return;
	}
	if (!doBusy) {
		messageContainer.style.visibility = "hidden";
		messageH.innerHTML = "";
	} else if (message != null && message.length > 0) {
		messageH.innerHTML = message;
		messageContainer.style.visibility = "visible";
		var width = GetPageWidth();
		var messageWidth = messageContainer.offsetWidth;
		var height = GetPageHeight();
		var messageHeight = messageContainer.offsetHeight;
		messageContainer.style.left = Math.round((width - messageWidth) / 2) + GetScrollLeft() + "px";
		messageContainer.style.top = Math.round((height - messageHeight) / 2) + GetScrollTop() + "px";
	}
}

function GetComputedStyle(element) {
	try {
		if (element.currentStyle != null) {
			return element.currentStyle;
		} else {
			return window.getComputedStyle(element, null);
		}
	} catch (e) {
		return null;
	}
}

function GetDescendentsByTagNameAndClassName(parent, tagname, className) {
	var r = new Array();
	if (parent == null) {
		return r;
	}
	var tagChildren = parent.getElementsByTagName(tagname.toUpperCase());
	for (var i = 0; i < tagChildren.length; i++) {
		var child = tagChildren[i];
		if (ContainsStyleClass(child, className)) {
			r.push(child);
		}
	}
	return r;
}

function HasAncestor(child, ancestorId) {
	var parent = child.parentNode;
	while (parent != null) {
		if (parent.id == ancestorId) {
			return true;
		}
		parent = parent.parentNode;
	}
	return false;
}

function GetAncestorByTagName(child, tagName) {
	var parent = child.parentNode;
	while (parent != null) {
		if (parent.tagName == tagName.toUpperCase()) {
			return parent;
		}
		parent = parent.parentNode;
	}
	return null;
}

function GetAncestorByTagNameAndClassName(child, tagName, className) {
	var parent = child.parentNode;
	while (parent != null) {
		if (parent.tagName == tagName.toUpperCase() && ContainsStyleClass(parent, className)) {
			return parent;
		}
		parent = parent.parentNode;
	}
	return null;
}

function ContainsStyleClass(object, styleClass) {
	if (object.className == null) {
		return false;
	}
	var classes = object.className.split(/ +/);
	for (var i = 0; i < classes.length; i++) {
		if (styleClass == classes[i]) {
			return true;
		}
	}
	return false;
}

function AddStyleClass(id, styleClass) {
	var object = getElement(id);
	if (object != null) {
		DoAddStyleClass(object, styleClass);
	}
}

function DoAddStyleClass(object, styleClass) {
	var className = Trim(object.className);
	if (className == null || className.length == 0) {
		object.className = styleClass;
	} else if (!ContainsStyleClass(object, styleClass)) {
		var c = object.className + " " + styleClass;
		object.className = c;
	}
}

function RemoveStyleClass(id, styleClass) {
	var object = getElement(id);
	if (object != null) {
		DoRemoveStyleClass(object, styleClass);
	}
}

function DoRemoveStyleClass(object, styleClass) {
	if (object.className == null) {
		return;
	} else if (ContainsStyleClass(object, styleClass)) {
		var c = object.className;
		c = c.replace(new RegExp(styleClass, "g"), "");
		c = c.replace(/  /g, " ");
		c = c.replace(/^ */, "");
		c = c.replace(/ *$/, "");
		object.className = c;
	}
}

function SetStyleClass(id, styleClass) {
	var object = getElement(id);
	if (object != null) {
		DoSetStyleClass(object, styleClass);
	}
}

function DoSetStyleClass(object, styleClass) {
	object.className = styleClass;
}

function AttributeContainsValue(object, attribute, value) {
	var currentValue = eval("object." + attribute)
	if (currentValue == null || currentValue.length == 0) {
		return false;
	}
	var values = currentValue.split(/ +/);
	for (var i = 0; i < values.length; i++) {
		if (value == values[i]) {
			return true;
		}
	}
	return false;
}

function DoAddToAttribute(object, attribute, value) {
	var currentValue = eval("object." + attribute)
	if (currentValue == null || currentValue.length == 0) {
		eval("object." + attribute + " = '" + value + "'");
	} else if (!AttributeContainsValue(object, attribute, value)) {
		eval("object." + attribute + " = '" + currentValue + " " + value + "'");
	}
}

function DoRemoveFromAttribute(object, attribute, value) {
	var currentValue = eval("object." + attribute)
	if (currentValue == null || currentValue.length == 0) {
		return;
	} else if (AttributeContainsValue(object, attribute, value)) {
		var values = currentValue.split(/ +/);
		var newValue = "";
		for (var i = 0; i < values.length; i++) {
			if (value != values[i]) {
				if (i > 0) {
					newValue += " ";
				}
				newValue += values[i];
			}
		}
		eval("object." + attribute + " = '" + newValue + "'");
	}
}

function IsEmpty(object) {
    if (object == null) {
        return true;
    } else if (typeof(object) == "string" || object instanceof String) {
    	object = object.replace(/^\s+/, "");
    	object = object.replace(/\s+$/, "");
    	return object.length == 0;
    } else {
    	return object.length == 0;
    }
}

function HasTagChildren(id, tagname) {
	var object = getElement(id);
	return object != null && object.getElementsByTagName(tagname.toUpperCase()).length > 0;
}

var TRIM_CHARS = /^[ \t\r\n]$/;

function Trim(s) {
	if (s == null) {
		return s;
	}
	if (s.charAt == null) {
		return s;
	}
	var index1 = 0;
	var index2 = s.length;
	if (index2 == index1) {
		return s;
	}
	while (s.charAt(index1).match(TRIM_CHARS)) {
		index1++;
	}
	while (s.charAt(index2 - 1).match(TRIM_CHARS)) {
		index2--;
	}
	if (index2 <= index1) {
		return "";
	}
	return s.substring(index1, index2);
}

var currentTextSize = null;

function SetTextSize(size) {
	if (size == null) {
		errorReporter.Report("Util.js", "SetTextSize(\"" + size + "\"): size is not set.");
		return;
	}
	if (size != currentTextSize) {
		currentTextSize = size;
		if (LOADSCRIPT_URL == null) {
			errorReporter.Report("Util.js", "SetTextSize(\"" + size + "\"): LOADSCRIPT_URL is not set.");
			return;
		}
		var url = new Url(LOADSCRIPT_URL);
		url.Append("command", "changetextsize");
		url.Append("newtextsize", size);
		LoadScript(url.toString());
	}
}

function Enable(id, doEnable) {
	var elem = getElement(id);
	if (elem != null) {
	    elem.disabled = !doEnable;
	    if (doEnable) {
			DoRemoveStyleClass(elem, "disabled");
	    } else {
			DoAddStyleClass(elem, "disabled");
	    }
	}
}

function EnableRadioTable(name, doEnable) {
	var radioInputs = document.getElementsByName(unEscape(name));
	for (var i = 0; i < radioInputs.length; i++) {
		radioInputs[i].disabled = !doEnable;
	}
	var scrollabletable = GetAncestorByTagNameAndClassName(radioInputs[0], "DIV", "scrollabletable");
	if (scrollabletable != null) {
		if (doEnable) {
			DoRemoveStyleClass(scrollabletable, "disabled");
		} else {
			DoAddStyleClass(scrollabletable, "disabled");
		}
	}
}

function SetTitle(id, title) {
	var elem = getElement(id);
	if (elem != null) {
	    elem.title = title;
	}
}

function SetPageTitle(title) {
	document.title = title;
}

var menu = null;
var dynamicParameters = null;
var menuY = null;
var menuX = null;

function MenuDown(id, parameters, event) {
    if (event == null) {
        event = window.event;
    }
	if (event == null || event.type != "mousedown" || !IsRightMouseButton(event)) {
		// pass event on to be handled normally
		return true;
	}
	if (menu != null) {
		DoDisplay(menu, false);
		menu = null;
		// don't pass event on
		return Finish(event);
	}
	id = unEscape(id);
	menu = getElement(id);
	if (menu == null) {
		return;
	}
	dynamicParameters = parameters;
	menuY = event.clientY;
	menuX = event.clientX;
	document.onclick = MenuClick;
	var scrollTop = GetScrollTop(); 
	var scrollLeft = GetScrollLeft();
	var shadow = getElement(id + "_shadow");
	menu.style.top = event.clientY + scrollTop + "px";
	menu.style.left = event.clientX + scrollLeft + "px";
	DoDisplay(menu, true);
	shadow.style.height = menu.offsetHeight + "px";
	shadow.style.width = menu.offsetWidth + "px";
	// don't pass event on
	return Finish(event);
}

function MenuClick(event) {
    if (event == null) {
        event = window.event;
    }
	if (event == null || menu == null) {
		return;
	}
	document.onclick = null;
	var target = GetTarget(event);
	// perform menu function, only if:
	// (1) target is in the menu, and
	// (2) target has a command attribute.
	if (HasAncestor(target, menu.id)) {
		var command = target.getAttribute("command");
		if (command != null) {
			var staticParameters = target.getAttribute("parameters");
			var url = new Url(LOADSCRIPT_URL);
			url.Append("command", command);
			var parameter;
			for (var i = 0; staticParameters != null && i < staticParameters.length; i++) {
				parameter = staticParameters[i];
				url.Append(parameter[0], parameter[1]); 
			}
			for (var i = 0; dynamicParameters != null && i < dynamicParameters.length; i++) {
				parameter = dynamicParameters[i];
				url.Append(parameter[0], parameter[1]); 
			}
			LoadScript(url.toString());
		}
	}
	DoDisplay(menu, false);
	menu = null;
	// don't pass event on
	return Finish(event);
}

function SetPageWidth(width) {
	// window.top.status = "";
	var EPSILON = 1;
	var outerMost = getElement("outermost");
	var offWidth = outerMost.offsetWidth;
	var dWidth = Math.abs(width - offWidth);
	var ostWidth;
	if (isIE) {
		if (ieVersion < 7) {
			var correction = 0.5;
			ostWidth = outermost.style.width;
			if (ostWidth == null || ostWidth.length == 0 || dWidth >= EPSILON) {
				// window.top.status = "SetPageWidth(" + width + "); Before: offWidth = " + offWidth + ";"
				outerMost.style.width = Math.round(width * correction) + "px";
				offWidth = outerMost.offsetWidth;
				// window.top.status += " Finally: offWidth = " + offWidth;
			}
		} else {
			ostWidth = outermost.style.minWidth;
			if (ostWidth == null || ostWidth.length == 0 || dWidth >= EPSILON) {
				// window.top.status = "SetPageWidth(" + width + ")";
				outerMost.style.minWidth = width + "px";
			}
		}
	} else {
		ostWidth = outerMost.style.minWidth;
		if (ostWidth == null || ostWidth.length == 0 || dWidth >= EPSILON) {
			// window.top.status = "SetPageWidth(" + width + ")";
			outerMost.style.minWidth = width + "px";
			var mapimg = getElement("mapimg_id");
			if (mapimg != null) {
				mapimg.style.width = mapimg.offsetWidth + dWidth + "px";
				Resize();
			}
		}
	}
}

function ClearPageWidth() {
	// window.top.status = "ClearPageWidth()";
	var outerMost = getElement("outermost");
	if (isIE && ieVersion < 7) {
		outerMost.style.width = null;
	} else {
		outerMost.style.minWidth = null;
	}
	if (isMozilla) {
		var mapimg = getElement("mapimg_id");
		if (mapimg != null && IsVisibleElement(mapimg, true)) {
			Resize();
		}
	}
}

var TimerIntervals = new Object();

function StartTimer(id, buttonId) {
	id = unEscape(id)
	buttonId = unEscape(buttonId);
	var timerSpan = getElement(id);
	if (timerSpan == null) {
		return;
	}
	TimerIntervals[id] = setInterval("UpdateTimer('" + id + "', '" + buttonId + "')", 1000);
}

function UpdateTimer(id, buttonId) {
	var timerSpan = getElement(id);
	if (timerSpan == null) {
		return;
	}
	var done = false;
	var time = timerSpan.innerHTML.split(":");
	var i = Number(0);
	var hours = Number(0);
	var minutes;
	var seconds;
	var hasHours = time.length == 3;
	if (hasHours) {
		hours = Number(time[i++]);
	}
	minutes = Number(time[i++]);
	seconds = Number(time[i++]);
	seconds--;
	if (seconds < 0) {
		if (minutes == 0 && hours == 0) {
			seconds = 0;
			done = true;
		} else {
			seconds = Number(59);
			minutes--;
			if (minutes < 0) {
				if (hasHours) {
					minutes = Number(59);
					hours--;
				} else {
					minutes = Number(0);
				}
			}
		}
	}
	timerSpan.innerHTML = FormatTime(hasHours, hours, minutes, seconds);
	if (done) {
		DoAddStyleClass(timerSpan, "done");
		EndTimer(id, buttonId);
	}
}

function EndTimer(id, buttonId) {
	clearInterval(TimerIntervals[id]);
	var button = getElement(buttonId);
	if (button != null) {
		button.disabled = true;
	}
	var url = new Url(LOADSCRIPT_URL);
	url.Append("command", "timeout");
	LoadScript(url.toString());
}

function FormatTime(hasHours, hours, minutes, seconds) {
	if (hasHours) {
		return FormatTimeNumber(hours) + ":" + FormatTimeNumber(minutes) + ":" + FormatTimeNumber(seconds);
	} else {
		return FormatTimeNumber(minutes) + ":" + FormatTimeNumber(seconds);
	}
}

function FormatTimeNumber(n) {
	var s = "0" + n;
	return s.substring(s.length - 2);
}

function NavigateToPath(path, keys, searchType, onWordBoundaries) {
	var url = new Url(LOADSCRIPT_URL);
	url.Append("command", "navigatetopath");
	url.Append("path", path);
	url.Append("searchkeys", keys);
	url.Append("searchtype", searchType);
	url.Append("searchonwordboundaries", onWordBoundaries);
	var searchResultsScrollable = getElement("searchpanelresultsscrollableid");
	if (searchResultsScrollable != null) {
		var scrollTop = searchResultsScrollable.scrollTop;
		url.Append("searchresultsscrolltop", scrollTop);
	}
	LoadScript(url.toString());
}

function SetMaxHeight(id, minHeight) {
	var elem = getElement(id);
	if (elem != null)
	{
		DoSetMaxHeight(elem, minHeight);
	}
}

function DoSetMaxHeight(elem, minHeight) {
	if (minHeight == null) {
		minHeight = 0;
	}
	var height = elem.offsetHeight;
	var pageHeight = GetPageHeight();
	var scrollHeight = GetScrollHeight();
	var maxHeight = Math.max(pageHeight - (scrollHeight - height) - 10, 0);
	maxHeight = Math.max(maxHeight, minHeight);
	if (isIE && ieVersion <= 6) {
		if (elem.offsetHeight > maxHeight) {
			elem.style.height = maxHeight + "px";
		}
	} else {
		elem.style.maxHeight = maxHeight + "px";
	}
}

function CreateCookie(name, value, days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
		var expires = "; expires=" + date.toGMTString();
	} else {
		var expires = "";
	}
	document.cookie = name + "=" + value + expires + "; path=/";
}

function ReadCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for (var i = 0; i < ca.length; i++) {
		var c = ca[i];
		while (c.charAt(0) == ' ') {
			c = c.substring(1, c.length);
		}
		if (c.indexOf(nameEQ) == 0) {
			return c.substring(nameEQ.length, c.length);
		}
	}
	return null;
}

function EraseCookie(name) {
	CreateCookie(name, "", -1);
}