// Locale
var locale = "no_NO";
var decimalSeparator = "";
var groupingSeparator = "";
var autoFocus = true;
var currentTlxSelectId = null;
var currentTlxSelectSearchId = 0;

// Modules
var ijobman = false;
var moduleElectro = false;
var moduleNrf = false;
var moduleemployee = false;
var modulecustomer = false;

function setLocale(newLocale) {
	locale = newLocale;
}

function setGroupingSeparator(newGroupingSeparator) {
	groupingSeparator = newGroupingSeparator;
}

function setDecimalSeparator(newDecimalSeparator) {
	decimalSeparator = newDecimalSeparator;
}

// String methods
String.prototype.cut = function(maxLength) {
	if(maxLength >= this.length) return this;
	return this.substr(0, maxLength) + "...";
}
String.prototype.endsWith = function(sEnd) {
	return (this.substr(this.length-sEnd.length)==sEnd);
}

String.prototype.startsWith = function(sStart) {
	return (this.substr(0,sStart.length)==sStart);
}

String.prototype.trim = function() {
	var b=0,e=this.length -1;
	while(this.substr(b,1) == " " && b <= e) b++;
	while(this.substr(e,1) == " " && e > b) e--;
	return this.substring(b,e+1);
}

String.prototype.reverse = function() {
	var a = new Array();
	for(var i=0;i<this.length;i++) a.push(this.substr(i,1));
	return a.reverse().join("");
}

String.prototype.divide = function(separator) {
	var ret = new Array();
	var last = 0;
	for(var i = this.indexOf(separator); i >= 0; i = this.indexOf(separator, i)) {
		ret[ret.length] = this.substring(last, i);
		i++;
		last = i;
	}
	if (this.length > 0) ret[ret.length] = this.substring(last);
	return ret;
}

function isString(value) {
	if(value == null) return false;
	return ((typeof value == "string") || value.constructor == String); 
}

function isInt(value) {
	if(value == null) return false;
	return typeof value == "number" && /\./.test(value) == false;
}

function isFloat(value) {
	if(value == null) return false;
	return typeof value == "number" && /\./.test(value);
}
function isNumber(value) {
	if(value == null) return false;
	return typeof value == "number";
}
function isBoolean(value) {
	if(value == null) return false;
	return typeof value == "boolean";
}

// Collection methods

function toArray(collection) {
	var length = collection.length;
	var ret = new Array(length);
	for (var i = 0; i < length; i++) {
		ret[i] = collection[i];
	}
	return ret;
}

// Array methods

function arrayClone(a) {
	toArray(a);
}

function arrayVisit(a, func) {
	var length = a.length;
	for (var i = 0; i < length; i++) {
		func(a[i]);
	}
	return a;
}

function arrayMap(a, func) {
	var length = a.length;
	var res = new Array(length);
	for (var i = 0; i < length; i++) {
		res[i] = func(a[i]);
	}
	return res;
}

function arrayRemoveIf(a, func) {
	var ret = new Array();
	var i = 0;
	arrayVisit(a, function (a) { 
		if (!func(a)) {
			ret[i] = a;
			i++;
		}
	});
	return ret;
}

function arrayFind(a, element, key) {
	for (var i = 0; i < a.length; i++) {
		var value = a[i];
		if (key) value = key(value);
		if (value == element) return element;
	}
}

function arrayReduce(a, func) {
	var l = a.length;
	if (l == 0) return func();
	if (l == 1) return a[0];
	var ret = func(a[0], a[1]);
	for (var i = 2; i < l; i++) ret = func(ret, a[i]);
	return ret;
}


function plus(a, b) {
	if (!a) return 0;
	if (!b) return a;
	return a + b;
}


// Math

function round2(num) {
	return Math.round(num*100.0)/100.0;
}


// Date methods

function addDays(date, count) {
	return new Date(date.getTime() + count*86400000);
}

function addDay(date) {
	return addDays(date, 1);
}

function getYear(date) {
	var year;
	if (date.getFullYear) {
		year = date.getFullYear();
	} else {
		year = date.getYear();
		if (year < 1000) year = year + 1900;
	}
	return year;
}

function addMonths(date, count) {
	var year = getYear(date);
	var month = date.getMonth();
	var day = date.getDate();
	var absMonth = year*12+month+count;
	date = new Date(Math.floor(absMonth/12), absMonth%12, day, 0, 0, 0);
	if (date.getDate() != day) {
		date = new Date(getYear(date), date.getMonth(), 0, 0, 0, 0);
	}
	return date;
}

function addMonth(date) {
	return addMonths(date, 1);
}


// Calendar methods

function calSetup(inputField, button) {
	if (!button) button = inputField + ".cal.img";
	Calendar.setup(
	    {
		  weekNumbers : true,
		  animation   : false,
	      inputField  : inputField,
	      ifFormat    : "%Y-%m-%d",
	      button      : button,
	      trigger     : button,
	      onSelect    : function() { this.hide(); getElement(inputField).focus(); },
	      align       : "tR",
	      firstDay    : 1
	    }
	);
}
 

// DOM methods

// Returns next element using tabIndex
function getNextElement(element) {
	var nextElement = null;

	if(element.form) {
		var nextTabIndex = element.tabIndex + 1;
		var elements = toArray(element.form.elements); // Prevents Opera from freaking out

		for (var i = 0; i < elements.length; i++) {
			var e = elements[i];
			if(!e) continue;
			if(e.disabled == undefined || e.disabled) continue;
			if(e.tabIndex == undefined || e.tabIndex == 0) continue;
			if(isElementHidden(e)) continue;
			if(e.tabIndex < nextTabIndex) continue;
			if(e.tabIndex == nextTabIndex) return e;	

			if(nextElement == null ||  e.tabIndex < nextElement.tabIndex) {
				nextElement = e;
			}
		}
	}
	
	return nextElement;
}

function isElementHidden(idOrElement) {
	var element = isString(idOrElement) ? getElement(idOrElement) : idOrElement;
	if(!element) return false;
	if(element.style && element.style.display == "none") return true;
	var parent = getParentNode(element);
	if(parent) return isElementHidden(parent);
	return false;	
}

function doesExist(theId) {
  if (!theId) return false;
  if (document.getElementById && document.getElementById(theId)) return true;
  if (document.all && document.all(theId)) return true;
  if (document.layers && document.layers[theId]) return true;
  return false;
}

function getElement(theId, doc) {
  if (!theId) return null;
  var d;
  if(doc) d = doc;
  else d = document;
  if (d.getElementById) return d.getElementById(theId);
  if (d.all) return d.all(theId);
  if (d.layers) return d.layers[theId];
  return null;
}

function getElementObject(idOrElement) {
	var element = isString(idOrElement) ? getElement(idOrElement) : idOrElement;
	if(!element) return null;
	return fromJSON(element.getAttribute("tlxObject"));
}

function fromJSON(json) {
	var obj;
	try {
		eval("obj = " + json);
	} catch( e ) {
		throw "error parsing JSON representation";
	}
	return obj;
}

function jsonDate(date) {
	if(date) return { javaClass: "java.util.Date", time: date.valueOf() };
	return null;
}

function getElementValue(idOrElement, defaultValue) {
	var element = isString(idOrElement) ? getElement(idOrElement) : idOrElement;
	if (!element) {
		return defaultValue;
	} else if (element.tagName.toUpperCase() == "INPUT" || element.tagName.toUpperCase() == "TEXTAREA") {
		if (element.type.toUpperCase() == "CHECKBOX") {
			return element.checked;
		} else {
			return element.value;
		}
	} else if (element.tagName.toUpperCase() == "SELECT") {
		if(element.options.length == 0) {
			return null;
		}
		
		return element.options[element.selectedIndex].value;
	} else {
		if (element.innerText) {
			return element.innerText; // IE
		} else if (element.textContent) {
			return element.textContent; // FF
		} else {
			return element.innerHTML; // Emergency
		}
	}
}

function getElementInt(idOrElement, defaultValue) {
	var ret = getElementValue(idOrElement);
	return (ret == undefined) ? defaultValue : parseInt(ret);
}

function getElementFloat(idOrElement, defaultValue) {
	var ret = getElementValue(idOrElement);
	return (ret == undefined) ? defaultValue : parseFloat2(ret);
}

function getElementDate(idOrElement, defaultValue) {
	var ret = getElementValue(idOrElement);
	return (ret == undefined) ? defaultValue : parseDate(ret);
}

function setElementValue(idOrElement, value) {
	value = isString(value) ? value : "" + value;
	var element = isString(idOrElement) ? getElement(idOrElement) : idOrElement;	
	if(!element || !element.tagName) return;
	
	if (element.tagName.toUpperCase() == "INPUT" || element.tagName.toUpperCase() == "TEXTAREA") {
		if (element.type.toUpperCase() == "CHECKBOX") {
			element.checked = (value == "true" || value == true);
		} else if (element.type.toUpperCase() == "HIDDEN") {
			element.value = value;						

			if(element.getAttribute("tlxSelectType")) {				
				tlxSelectSetElementDisplayName(element.id, value);		
			}
		} else {
			element.value = value;
		}
	} else if (element.tagName.toUpperCase() == "SELECT") {
		var options = element.options;
		for(var i = 0; i < options.length; i++) {
			if(options[i].value == value) {
				element.selectedIndex = i;
				break;
			}
		}
	} else {
		element.innerHTML = value;
	}
}

function getParentForm(node) {
	return getParentNode(node, "FORM");
}

function getParentTable(node) {
	var candidate = getParentNode(node, "TBODY");
	return candidate ? candidate : getParentNode(node, "TABLE");
}

function getParentNode(node, type) {
	var parent = node.parentNode;
	if (!parent) return null;
	if (!type || parent.nodeName == type.toUpperCase()) return parent;
	return getParentNode(parent, type);
}

var visitTreeId = 0;

function visitTree(root, visitor) {
	var doit = function (root, visitor, beenThere) {
		if(!root.tagName) return;
		var cyclicDom = isSafari2();

		if(cyclicDom) {
			var rootVisitTreeId = root.getAttribute("visitTreeId");
			
			if(!rootVisitTreeId) {
				visitTreeId++;
				root.setAttribute("visitTreeId", "" + visitTreeId);
				rootVisitTreeId = root.getAttribute("visitTreeId"); // If only strings are supported
			}

			beenThere[rootVisitTreeId] = "yes";
		}
		
		var stop = visitor(root);
		var children = toArray(root.childNodes);
		var length = children.length;
		
		if (!stop) {
			for (var i = 0; i < length; i++) {
				var child = children[i];
				if(!child.tagName) continue;
				
				if(cyclicDom) {
					// The Safari DOM may be cyclic -> must check if we have been there before
					// ME: Is this true anymore?
					var childVisitTreeId = child.getAttribute("visitTreeId");

					if (childVisitTreeId && beenThere[childVisitTreeId]) {
						continue;
					} 
				}

				doit(children[i], visitor, beenThere);
			}
		}
	}

	doit(root, visitor, {});
}

function collectIf(dom, func, recurse) {
	var ret = new Array();
	var i = 0;
	visitTree(dom, function (node) {
		if (func(node)) { 
			ret[i] = node;
			i++;
			if (!recurse) return true;
		}
	});
	return ret;
}

function removeIf(dom, func) {
	visitTree(dom, function (node) {
		if (func(node)) { 
			removeNode(node);
			return true;
		}
	});
}

function removeNode(node) {
	node.parentNode.removeChild(node);
}

function removeChildren(node) {
	while(node.lastChild) node.removeChild(node.lastChild);
}

function getTags(dom, tagName, recurse) {
	return collectIf(dom, function (node) { return (node.nodeName && node.nodeName == tagName); }, recurse);
}

function removeTags(dom, tagName) {
	removeIf(dom, function (node) { return (node.nodeName && node.nodeName == tagName);	});
}

function getByClass(dom, className, recurse) {
	return collectIf(dom, function (node) {
		var nodeClass = node.className;
		return (nodeClass && arrayFind(nodeClass.divide(" "), className));
	}, recurse);
}

function removeByClass(dom, className) {
	removeIf(dom, function (node) {
		var nodeClass = node.className;
		return (nodeClass && arrayFind(nodeClass.divide(" "), className));
	});
}

function removeByStyle(dom, style, value) {
	removeIf(dom, function (node) {
		return (node && node.style && node.style[style] == value);
	});
}

function replaceNodeWithChild(node) {
	if (node.firstChild) {
		var child = node.removeChild(node.firstChild);
		node.parentNode.replaceChild(child, node);
	} else {
		removeNode(node);
	}
}

function replaceChildren(node, newChild) {
	removeChildren(node);
	node.appendChild(newChild);
}

function replaceChildrenWithText(node, text) {
	replaceChildren(node, document.createTextNode(text));
}

function getRows(table, from, to) {
	return getTags(table, "TR").slice(from, to);
}

function removeRows(table, from, to) {
	arrayVisit(getRows(table, from, to), removeNode);
}

function removeLinks(dom) {
	visitTree(dom, function (node) {
		if (node.nodeName == "A") replaceNodeWithChild(node);
	});
}

function removeInputs(dom) {
	visitTree(dom, function (node) {
		var name = node.nodeName;
		if (name == "INPUT") {
			var type = node.type.toUpperCase();
			if (type == "HIDDEN" || type == "BUTTON" || type == "FILE" || type == "IMAGE" || type == "PASSWORD" || type == "RESET" || type == "SUBMIT") {
				removeNode(node);
			} else if (type == "CHECKBOX") {
				var text = document.createTextNode(node.checked ? "X" : "");
				node.parentNode.replaceChild(text, node);
			} else if (type == "RADIO") {
				if (node.checked) {
					var text = document.createTextNode(node.value);
					node.parentNode.replaceChild(text, node);
				} else {
					removeNode(node);
				}
			} else {
				var text = document.createTextNode(node.value);
				node.parentNode.replaceChild(text, node);
			}
		} else if (name == "TEXTAREA") {
			//replaceNodeWithChild(node);
			if (node.firstChild) {
				var child = node.removeChild(node.firstChild);
				var content = child.nodeValue;
				var span = document.createElement("span");
				span.innerHTML = content.replace(/\n/g, "<br>");
				node.parentNode.replaceChild(span, node);
			} else {
				removeNode(node);
			}
		} else if (name == "SELECT") {
			var option = null;
			
			if(node.options.length > 0) {
				option = node.options[node.selectedIndex];
			}
		
			if (option && option.firstChild) {
				var text = option.removeChild(option.firstChild);
				node.parentNode.replaceChild(text, node);
			} else {
				removeNode(node);
			}
		}
	});
}

function removeScripts(dom) {
	visitTree(dom, function (node) {
		var name = node.nodeName;
		if (name == "SCRIPT") {
			removeNode(node);
		}
	});
}

function replaceRowSpan(table, from, to) {
	visitTree(table, function (node) {
		if (node.nodeName == "TD") {
			if (node.rowSpan && node.rowSpan == from) {
				node.rowSpan = to;
			}
			return true;
		}
	});
}

// Tripletex

function isScriptXOk() {
  if (!doesExist("ScriptX")) return false;
  var ok = false;
  try {
	var ScriptX = getElement("ScriptX");
  	ok = ((typeof ScriptX == 'object') && ScriptX.printing && (typeof ScriptX.printing == 'object'));
  }
  catch (err) {}
  return ok;
}

function getTitle() { return ""; }
function getCompanyName() { return ""; }
function getHeader() { return getCompanyName() + " &b " + getTitle() + " &b &d &t"; }
function getFooter() { return "Utskrift fra tripletex.no &b&b Side &p av &P"; }
function getOrientation() { return "portrait"; }
function getTopMargin() { return -1; }
function getBottomMargin() { return -1; }
function getLeftMargin() { return -1; }
function getRightMargin() { return -1; }

function pageSetup() {
  if (isScriptXOk()) {
  	try {
	    ScriptX.printing.header = getHeader ? getHeader() : getCompanyName() + " &b " + getTitle() + " &b &d &t";
	    ScriptX.printing.footer = getFooter ? getFooter() : "Utskrift fra tripletex.no &b&b Side &p av &P";
	    ScriptX.printing.portrait = (getOrientation() == "portrait");
	    if (getTopMargin() >= 0)    ScriptX.printing.topMargin = getTopMargin();
	    if (getBottomMargin() >= 0) ScriptX.printing.bottomMargin = getBottomMargin();
	    if (getLeftMargin() >= 0)   ScriptX.printing.leftMargin = getLeftMargin();
	    if (getRightMargin() >= 0)  ScriptX.printing.rightMargin = getRightMargin();
	}
	catch (err) {}
  }
}

window.onerror = function () {
/*
	if (window == getContentFrame()) {
		submit(getContentFrame(), "/execute/jsError", "post", {
			"userAgent": navigator.userAgent,
			"location": document.location,
		});
	}
*/
}

function initialize() {
	if (window == getContentFrame() && window.loginCompanyId && loginCompanyId != getTopFrame().loginCompanyId) {
		//alert(messageErrorMultipleWindows);
		//window.open("/index.jsp", "_top");
	} else {
		if (window == getContentFrame()) {
			if (getBottomFrame() && getBottomFrame().setChanged) getBottomFrame().setChanged(false);
			showContent();
		}
		requestlog(); // Defined in header.jsp
		pageSetup();
		setFocus();
		if (window.init) init();
		if (window == getContentFrame()) {
			fillSelectAsync.perform();
			if (window.showPopups) showPopups();
			if (window.showDownloads) showDownloads();
		}
		
		document.onkeydown = documentOnkeydown;
		document.onclick = documentOnclick;
	}
}

function finalize() {
	if (window == getContentFrame()) {
		hideContent();
	}
}

function setFocus() {
	if(!autoFocus) return;
	if (document.forms && document.forms[0] && document.forms[0].elements) {
		var elements = document.forms[0].elements;
		
		for (var i = 0; i < elements.length; i++) {
			try {
				if (elements[i] && elements[i].type.toUpperCase() != "HIDDEN") {
					elements[i].focus();
					elements[i].blur(); // IE 7 fix
					elements[i].focus();
					break;
				}
			}
			catch (e) { }
		}
	}
}

function showPopups() {
	var popupForm = getElement('PopupForm0');
	var i = 1;
	while (popupForm) {
		popupForm.submit();
		popupForm = getElement('PopupForm' + i);
		i++;
	}
}

if (window == getContentFrame()) {
	if (isIE()) {
		document.onkeypress = onchange;
	} else {
		document.onchange = onchange;
	}
	document.onclick = onchange;
}


function printPageOld() {
  if (window.print)
    window.print();
  else
    alert(messageOperationNotSupportedPrint);
}

function printPageImpl() {
	if (isScriptXOk()) {
		try {
			ScriptX.printing.Print(true);
		}
		catch (err) {
			alert(messageDefaultPrinterMissing);
		}
	} else if (window.print) {
		window.print();
	} else {
		alert(messageOperationNotSupportedPrint);
	}
}
function printPage() {
	printPageImpl();
}

function printPreview() {
	if (isScriptXOk()) {
		try {
			ScriptX.printing.Preview();
		}
		catch (err) {
			alert(messageDefaultPrinterMissing);
		}
	} else {
		alert(messageOperationNotSupportedPreview);
	}
}

function openPrintWindow(url) {
	var w = window.open(url,"tripletex_print","toolbar=0,location=0,directories=0,status=1,menubar=1,scrollbars=1,resizable=1,width=800,height=600,top=10,left=10");
	w.focus();
}

function func(url, target) {
	navigate(url, target);
}

function link(url, target) {
	navigate(url, target);
}

function popup(url) {
	navigate(url, "_blank");
}

function download(url) {
	getContentFrame().document.location = url;
	//window.open(url);
}

function submenu(url) {
	navigate(url);
}

function navigate(url, target) {
	if (target) {
		//window.open(url, target);
		// Workaround for IE/Vista/Adobe problem
		var newWindow = window.open("", target);
		newWindow.document.location = url;
	} else {
		if (changeTest()) {
			var content = getContentFrame();
			if (content.hideContent) content.hideContent();
			content.document.location = url;
		}
	}
}

function logout(chTest) {
	var ok = chTest ? changeTest() : true;
	if (ok) top.document.location = "/execute/logout";
}

function hideContent() {
	collapseExtra();
	hideClass('.bodyContent');
	showClass('.bodyWait');
}

function showContent() {
	collapseExtra();
	hideClass('.bodyWait');
	showClass('.bodyContent');
}

function submitHideContent(form) {
	if (changeTest(form)) {
		hideAndSubmit(form);
	}
}

function onSubmit(form, bookmark) {
	if (window.validate && !validate(form)) {
		return false;
	}
	form.action = form.action + "#" + bookmark;
	hideContent();
	checkboxFix(form);
	return true;
}

function onSubmitWithWarning(form) {
	if (window.validate && !validate(form)) {
		return false;
	}
	if(!doWarning()) return false; 
	hideContent();
	checkboxFix(form);
	return true;
}

function hideAndSubmit(form) {
	hideContent();
	checkboxFix(form);
	form.submit();
}
function submitNoHide(button) {
	if (!button.form) throw new Error("Unable to find form based on given object: " + button);
	checkboxFix(button.form);
	addFormActionParameter(button);	
	button.form.submit();
}
function submitWithWarningBookmark(form, bookmark) { 
	if(!doWarning()) return; 
	submitWithoutWarningBookmark(form, bookmark);
}
function submitWithoutWarningBookmark(form, bookmark) {
	form.action = form.action + "#" + bookmark;
	submitHideContent(form);
}
function submitWithoutWarning() {
	var args = submitWithoutWarning.arguments;
	if (args.length == 1) {
		submitWithoutWarning1(args[0]);
	} else if (args.length == 2) {
		submitWithoutWarning2(args[0], args[1]);
	} else if (args.length == 3) {
		submitWithoutWarning3(args[0], args[1], args[2]);
	} else {
		throw new Error("submitWithoutWarning does not support " + args.length + " arguments");
	}
}

function submitWithoutWarning1(button) {
	if (!button.form) throw new Error("Unable to find form based on given object: " + button);
	var form = button.form;
	
	if (changeTest(form)) {
		createFormActionElement(button);
		hideAndSubmit(form);
	}
}

function createFormActionElement(button) {
	var form = button.form;
	var action = button.name;
	
	if (action && action.indexOf(".") > 0) {
		var separatorIndex = action.indexOf(".");
		var name = action.substring(0, separatorIndex);
		var value = action.substring(separatorIndex + 1, action.length);
		addHiddenInput(button.form, name, value);
		//if (form.action.indexOf("?") < 0) form.action += "?";
		//form.action += action + "=";
	}
}

function addFormActionParameter(button) {
	var form = button.form;
	var action = button.name;
	
	if (action && action.indexOf(".") > 0) {
		if (form.action.indexOf("?") < 0) form.action += "?";
		form.action += action + "=";
	}
}

function submitWithoutWarning2(form, action) {
	if (!form) throw new Error("No form argument given");
	if (changeTest(form)) {
		if (!form.action) {
			if (form.form) {
				form = form.form;
			} else {
				throw new Error("Unable to find form based on given object: " + form);
			}
		}
		createFormActionElement(button);
		hideAndSubmit(form);
	}
}

function submitWithoutWarning3(button, param, value) {
	if (!button.form) throw new Error("Unable to find form based on given object: " + button);
	var form = button.form;
	if (changeTest(form)) {
		var action = button.name;

		if (param) {
			if (form.action.indexOf("?") < 0) {
				form.action += "?";
			} else if (form.action.substring(form.action.length-1) != "&") {
				form.action += "&";
			}
			form.action += param + "=" + value;
		}

		createFormActionElement(button);
		hideAndSubmit(form);
	}
}

function submitWithWarning() {
	var args = submitWithWarning.arguments;
	if (args.length == 1) {
		submitWithWarning1(args[0]);
	} else if (args.length == 2) {
		submitWithWarning2(args[0], args[1]);
	} else if (args.length == 3) {
		submitWithWarning3(args[0], args[1], args[2]);
	} else {
		throw new Error("submitWithWarning does not support " + args.length + " arguments");
	}
}

function submitWithWarning1(button) {
	if (!doWarning()) {
		return false;
	}
	submitWithoutWarning1(button);
}

function submitWithWarning2(form, action) {
	if(!doWarning()) {
		return false;
	}
	submitWithoutWarning2(form, action);
}

function submitWithWarning3(button, param, value) {
	if (!doWarning()) {
		return false;
	}
	submitWithoutWarning3(button, param, value);
}

function addUrlParameter(url, name, value) {
	if (url.indexOf("?") < 0) {
		url += "?";
	} else if (url.substring(url.length-1) != "&") {
		url += "&";
	}
	url += name;
	url += "=";
	url += encodeURIComponent(value);
	return url;
}

function _getRootOpener(win) {
	try {
		if (!win.opener) return win;
		if (win.opener == win) return win;
		return _getRootOpener(win.opener);
	}
	catch (e) {
		// Permission denied
		return win;
	}
}

function _getRootFrame(win) {
	try {
		if (!win.parent) return win;
		if (win.parent == win) return win;
		return _getRootFrame(win.parent);
	}
	catch (e) {
		// Permission denied
		return win;
	}
}

function getMainWindow() {
	try {
		if (window) {
			var main = _getRootOpener(window);
			main = _getRootFrame(main);
			if (main && main.content) {
				// Last test to make absolutely sure this is the real main window
				return main;
			}
		}
	}
	catch (e) { }
	return null;
}

function getTopFrame() {
	var main = getMainWindow();
	if (main && main.topframe && main.topframe.location) {
		return main.topframe;
	} else {
		return null;
	}
}

function getContentFrame() {
	var main = getMainWindow();
	if (main && main.content && main.content.location) {
		return main.content;
	} else {
		return null;
	}
}

function getBottomFrame() {
	var main = getMainWindow();
	if (main && main.bottomframe && main.bottomframe.location) {
		return main.bottomframe;
	} else {
		return null;
	}
}

function parseFloat2(s) {
	if(s == null) return 0;
	s = s.trim();
	
	var decimalSeparatorCode = decimalSeparator == "" ? 44 : decimalSeparator.charCodeAt(0);
	var groupingSeparatorCode = groupingSeparator.charCodeAt(0);
	var temp = "0";
	if(s.length > 0 && s.charCodeAt(0) == 45) temp = "-0";  // 45 = '-'
	
	for (var i = 0; i < s.length; i++) {
		var charCode = s.charCodeAt(i);
		if (charCode == groupingSeparatorCode) {
		} else if (decimalSeparatorCode > 0 && (charCode == decimalSeparatorCode || charCode == 44 || charCode == 46)) { // 44 = ','  46 = '.'
			temp += ".";
			decimalSeparatorCode = -1;
		} else if (charCode >= 48 && charCode < 58) {
			temp += s.charAt(i);
		}
	}
	
	return parseFloat(temp);
}

function decimalPoints(a, b) {
    a *= Math.pow(10, b);
    a = Math.round(a);
    a /=  Math.pow(10, b);
    return a;
}

function decimalPointsBlank(a, b) {
    a = decimalPoints(a, b)
    
    if(a == 0) {
    	return "";
    }
    
    return a;
}

function getDecimalSeparator() {
	if(locale == "no_NO") {
		return ",";
	}
	
	return ".";
}
	
function formatHours0(d, blank) {
	return formatDecimal0(d, blank);
}

function formatHours2(d, blank) {
	return formatDecimal2(d, blank);
}

function formatHours(d, blank) {
	d = decimalPoints(d, 2);

    if(blank == true && d == 0) {
    	return "";
    }

	var s = String(d);

	if(decimalSeparator != '.') {
		s = s.replace(/\./g, decimalSeparator);
	}
	
	var separatorIndex = s.indexOf(decimalSeparator);
	
	if(separatorIndex < 0) {
		return s + decimalSeparator + "0";
	}

	if(separatorIndex == s.length - 1) {
		return s + "0";
	}

	return s;
}

function formatSeconds(hours) {
	var h = Math.floor(hours);
	var minutes = (hours - h) * 60;
	var m = Math.floor(minutes);
	var seconds = (minutes - m) * 60;
	var s = Math.floor(seconds);
	return formatInt2(h) + ":" + formatInt2(m) + ":" + formatInt2(s);
}

function formatInt2(integer) {
	if (integer == 0) {
		return "00";
	} else if (integer < 10) {
		return "0"+integer;
	} else {
		return String(integer);
	}
}

function formatAmount0(d, blank) {
	return formatDecimal0(d, blank);
}

function formatAmount(d, blank) {
	d = decimalPoints(d, 2);

    if(blank == true && d == 0) {
    	return "";
    }

	var s = String(d);

	if(decimalSeparator != '.') {
		s = s.replace(/\./g, decimalSeparator);
	}
	
	var separatorIndex = s.indexOf(decimalSeparator);
	
	if(separatorIndex < 0) {
		return s + decimalSeparator + "00";
	}

	if(separatorIndex == s.length - 2) {
		return s + "0";
	}

	if(separatorIndex == s.length - 1) {
		return s + "00";
	}

	return s;
}

function formatCurrencyAmount(d, blank) {
	d = decimalPoints(d, 10);

    if(blank == true && d == 0) {
    	return "";
    }
    
	var s = String(d);

	if(decimalSeparator != '.') {
		s = s.replace(/\./g, decimalSeparator);
	}
	
	return s;
}

function formatDecimal(d, precision, blank) {
	d = decimalPoints(d, precision);

    if(blank == true && d == 0) {
    	return "";
    }

	var s = String(d);
	if (precision > 0) {
		var separatorIndex = s.indexOf(".");
		if (separatorIndex < 0) separatorIndex = s.length;
		var fraction = s.substring(separatorIndex+1);
		s = s.substring(0, separatorIndex) + decimalSeparator;
		s += fraction;
		for (var i = fraction.length; i < precision; i++) {
			s += "0";
		}
	}
	
	return s;
}

function formatDecimal0(d, blank) {
	return formatDecimal(d, 0, blank);
}

function formatDecimal2(d, blank) {
	return formatDecimal(d, 2, blank);
}

function formatQuantity(d, blank) {
	var temp = formatDecimal(d, 10, blank);
	for (var i = temp.length; i > 0; i--) {
		var char = temp.substring(i-1, i);
		if (char == "." || char == ",") return temp.substring(0,i-1);
		if (char != "0") return temp.substring(0,i);
	}
}

function formatUnitPrice(d, blank) {
	var temp = formatDecimal(d, 10, blank);
	var ret = blank ? "" : "0.00";
	for (var i = temp.length; i > 0; i--) {
		var char = temp.substring(i-1, i);
		if (char == "." || char == ",") return temp.substring(0,i-1);
		if (char != "0") {
			ret = temp.substring(0,i);
			break;
		}
	}
	var ret2 = formatAmount(d, blank);
	if (ret2.length > ret.length) {
		return ret2;
	} else {
		return ret;
	}
}

function deleteRow(button, index, name, elementName) {
	if (!elementName) elementName = name;
	button.form[name+'['+index+'].deleted'].value = true;
	hideElement(elementName + index);
	changed();
}

function getTableRowCount(groupName) {
	var row = getElement(groupName+"[0]");
	if (row) {
		var table = getParentTable(row);
		var count = table.getAttribute(groupName + ".getTableRowCount.count");
		if (count != undefined && count != null) {
			return count;
		} else {
			for (count = table.childNodes.length; count > 0; count--) {
				row = getElement(groupName+"["+(count-1)+"]");
				if (row) {
					table.setAttribute(groupName + ".getTableRowCount.count", count);
					return count;
				}
			}
		}
	} else {
		return 0;
	}
}

function deleteRow2(groupName, index, cancel) {
	if (!cancel) {
		var rowName = groupName+"["+index+"]";
		var deleted = getElement(rowName+".deleted");
		deleted.setAttribute("deleteRow.dirty", true); 
		deleted.value = "true";
		hideElement(rowName);
		changed();
		if (window.refreshTable) refreshTable(groupName);
	}
}

function addRow(groupName, cancel) {
	if (!cancel) {
		var last = null;
		var deleted = null;
		var size = getTableRowCount(groupName);
		do {
			size--;
			last = deleted;
			deleted = getElement(groupName+"["+size+"].deleted");
		} while (deleted && deleted.value == "true" && !deleted.getAttribute("deleteRow.dirty"))
		if (last) {
			last.value = "false";
			if (window.fillRow) fillRow(size+1, groupName);
			var groupNameStr = groupName+"["+(size+1)+"]";  
			showElement(groupNameStr);
			changed();
		}
	}
}

function showNextRow(groupName, i, cancel) {
	if (!cancel) {
		var last = null;
		var lastJ = -1;
		var deleted = null;
		for (var j = getTableRowCount(groupName)-1; j > i; j--) {
			deleted = getElement(groupName+"["+j+"].deleted");
			if (deleted.value == "false") {
				return;
			} else if (!deleted.getAttribute("deleteRow.dirty")){
				last = deleted;
				lastJ = j;
			}
		}
		if (last) {
			last.value = "false";
			if (window.fillRow) fillRow(lastJ, groupName); 
			showElement(groupName+"["+lastJ+"]");
			changed();
		}
	}
}

function applyRows(name, lambda) {
	var i = 0;
	do {
		var deletedInput = getElement(name+"["+i+"].deleted");
		if (deletedInput && deletedInput.value == "false") {
			lambda(name+"["+i+"]");
		}
		i++;
	} while (deletedInput)
}

function sumRows(name, property) {
	var sum = 0.0;
	var i = 0;
	do {
		var deletedInput = getElement(name+"["+i+"].deleted");
		if (deletedInput && deletedInput.value == "false") {
			sum = round2(sum + parseFloat2(getElementValue(name+"["+i+"]."+property)));
		}
		i++;
	} while (deletedInput)
	return sum;
}

function sumRowsInto(name, property, formatFunction, blank, id) {
	var sum = sumRows(name, property);
	if (!formatFunction) formatFunction = formatDecimal2;
	if (!id) id = name+".sum."+property;
	setElementValue(id, formatFunction(sum, blank));
	return sum;
}

function subtractRowsInto(name, property, formatFunction, blank, id) {
	var sum = -sumRows(name, property);
	if (!formatFunction) formatFunction = formatDecimal2;
	if (!id) id = name+".sum."+property;
	setElementValue(id, formatFunction(sum, blank));
	return sum;
}

// DOM inspection/manipulation

function debug(text) {
	document.body.appendChild(document.createTextNode(text));
	document.body.appendChild(document.createElement("BR"));
}

function setSelectedOption(list, value) {
	list.selectedIndex = 0;
	var options = list.options;
	
	for(var i = 0; i < options.length; i++) {
		if(options[i].value == value) {
			list.selectedIndex = i;
			break;
		}
	}
	
}

function getSelectedObject(list) {
	if(list.options.length == 0) return null;
	return getElementObject(list.options[list.selectedIndex]);
}

function getSelectedOption(list) {
	if(list.options.length == 0) return null;
	return list.options[list.selectedIndex];
}

function getSelectedValue(select) {
	return select.options[select.selectedIndex].value;
}

function clearSelect(select, exceptThisIndex) {
	for (var i = select.options.length-1; i >= 0; i--) {
		if (exceptThisIndex == undefined || i != exceptThisIndex) {
			select.remove(i);
		}
	}
}

function clearSelectAfterIndex(select, afterThisIndex) {
	for (var i = select.options.length-1; i >= 0; i--) {
		if (afterThisIndex == undefined || i > afterThisIndex) {
			select.remove(i);
		}
	}
}

function clearListFromIntValue(select, intValue) {
	for (var i = select.options.length-1; i >= 0; i--) {
		if (intValue == undefined || parseInt(select.options[i].value) >= intValue) {
			select.remove(i);
		}
	}
}

function copyOptions(fromSelect, toSelect) {
	for (var i = 0; i < fromSelect.options.length; i++) {
		var option = fromSelect.options[i];		
		addOption(toSelect, option.text, option.value, option.getAttribute("tlxObject"));
	}
}

function fillListSelectsRecursive(idOrElement, sync) {
	var element = isString(idOrElement) ? getElement(idOrElement) : idOrElement;    
    if(element == null) return;
    
	visitTree(element, function (node) {
		if (node.tagName && node.tagName.toUpperCase() == "SELECT") fillListSelect(node, sync);
		return false;
	});

}
function fillListSelect(idOrElement, sync) {
	var element = isString(idOrElement) ? getElement(idOrElement) : idOrElement;    
    if(element == null) return;

    var listFunctionArgs = element.getAttribute("listFunctionArgs");
    if(!listFunctionArgs) return;

    if(element.getAttribute("isFilled")) return;

	var ev = window.event;
	
	if(ev) {
		var keyCode = ev.keyCode;			

		if(keyCode == 9 || keyCode == 16) {
		 	// Tab or shift
			return;
		}	
	}

        
    if(element.selectedIndex >= 0 && parseInt(element.options[element.selectedIndex].value) > 0) {
    	element.remove(element.selectedIndex);
    }
    
    if(sync) {
	    eval("fillSelectSync(" + listFunctionArgs + ");");
	    if(element.style.display = "") element.focus();
    } else {
	    eval("fillSelectAsync(" + listFunctionArgs + ");");
    }
    
    element.setAttribute("isFilled", "true");
    return true;
}


function fillSelect(select, objects, property, labelProperty, prefix, value) {
	if (!prefix) prefix = "";
	//var options = new Array(objects.length + 1);
	//options[0] = select.innerHTML;
	for (var i = 0; i < objects.length; i++) {
		var optValue = property ? objects[i][property] : '' + objects[i];
		var label = labelProperty ? objects[i][labelProperty] : '' + objects[i];
		addOption(select, prefix + label, optValue, optValue == value, null, objects[i]);
	}
	/*
	select.innerHTML = "";
	var html = select.outerHTML;
	var splitPoint = html.toUpperCase().indexOf("</SELECT>");
	select.outerHTML = html.substring(0, splitPoint) + options.join("") + html.substring(splitPoint);
	*/
}

// Changes the cursor to an hourglass
function cursor_wait() {
	document.body.style.cursor = 'wait';
}

// Returns the cursor to the default pointer
function cursor_clear() {
	document.body.style.cursor = 'default';
}

function cursor_pointer() {
	document.body.style.cursor = 'pointer';
}

function addOption(select, label, value, selected, defaultSelected, tlxObject) {
	//var opt = new Option(label, value, selected ? true : false);
	var opt = new Option(label, value);
	var index = select.options.length;
	select[index] = opt;
	if (selected) {
		opt.selected = true;
		select.selectedIndex = index;
	}
	
	opt.defaultSelected = defaultSelected ? true : false;	

	if(tlxObject && getTopFrame()) {		
		opt.setAttribute("tlxObject", getTopFrame().toJSON(tlxObject));
	}

	return opt;
}

function isElementVisible(idOrElement) {
	return !isElementHidden(isOrElement);
}

function showHideElement(idOrElement) {
	var element = isString(idOrElement) ? getElement(idOrElement) : idOrElement;
    if(!element) return;

    if(element.style.display == 'none') {
		if (isSafari2()) {
			element.style.display = undefined; // Safari 2
		} else if (isOpera()) {
			element.style.display = "table-row"; // Opera
		} else {
			element.style.display = ""; // // IE / Firefox / Safari 3
		}
	} else {
		element.style.display = 'none';
	}	
}

function showElement(idOrElement) {
	var element = isString(idOrElement) ? getElement(idOrElement) : idOrElement;
    if(!element) return;
    if(isTlxSelectElement(element)) element = tlxSelectGetSelectDivElement(element.id);

    if (isSafari2()) {
	    element.style.display = undefined; // Safari 2
	} else if (isOpera()) {
	    element.style.display = "table-row"; // Opera
	} else {
	    element.style.display = ""; // // IE / Firefox / Safari 3
	}
}

function hideElement(idOrElement) {
	var element = isString(idOrElement) ? getElement(idOrElement) : idOrElement;
    if(!element) return;
    if(isTlxSelectElement(element)) element = tlxSelectGetSelectDivElement(element.id);
    element.style.display = "none";
}

function getOs() {
	if(!navigator.userAgent) return "Unknown";
	var ua = navigator.userAgent.toLowerCase();

	if (agent.indexOf("windows") >= 0) {
	    return "Windows";
	}
	if (agent.indexOf("linux") >= 0) {
	    return "Linux";
	}
	if (agent.indexOf("freebsd") >= 0) {
	    return "FreeBSD";
	}
	if (agent.indexOf("sunos") >= 0) {
	    return "Solaris";
	}
	if (agent.indexOf("mac") >= 0) {
	    return "Mac";
	}
	
	return "Unknown";
}

function isMac() {
	return getOs().equals("Mac");
}

function isPdfObjectCompatible() {
	if(isMac() && isOpera()) return false;
	return true;
}

function isFirefox() {
	if (!document.layers){
		return navigator.userAgent.indexOf('Firefox') != -1;
	}
	
	return false;
}

function isChrome() {
	if (!document.layers){
		return navigator.userAgent.indexOf('Chrome') != -1;
	}
	
	return false;
}

function isSafari() {
	if (!document.layers){
		return navigator.userAgent.indexOf('Safari') != -1 && !isChrome();
	}
	
	return false;
}

function isSafari2() {
	return isSafari() && !isSafari3plus();
}

function isSafari3plus() {
	return isSafari() && 
			(navigator.userAgent.indexOf('Version/3.') >= 0 ||
			 navigator.userAgent.indexOf('Version/4.') >= 0 || 
			 navigator.userAgent.indexOf('Version/5.') >= 0 || 
			 navigator.userAgent.indexOf('Version/6.') >= 0 ||
			 navigator.userAgent.indexOf('Version/7.') >= 0);
}

function isOpera() {
	if (!document.layers){
		return navigator.userAgent.indexOf('Opera') != -1;
	}
	return false;
}

function isKonqueror() {
	if (!document.layers){
		return navigator.userAgent.indexOf('Konqueror') != -1;
	}
	return false;
}

function isMozilla() {
	if (!document.layers){
		return navigator.userAgent.indexOf('Gecko') != -1 && !isSafari() && !isKonqueror() && !isChrome();
	}
	return false;
}

function isIE() {
	return !isSafari() && !isOpera() && !isKonqueror() && !isMozilla() && !isChrome();
}

function isIE6() {
	return navigator.userAgent.indexOf("MSIE 6.") != -1 && isIE();
}

function styleSheetChanger(cssClassName, toChange, changeTo){ 
	var ds = document.styleSheets; 
	
	if (ds == undefined) {
		// Opera
		styleSheetChangerVisitTree(cssClassName, toChange, changeTo);
		return;
	}
	
	cssClassName = cssClassName.toLowerCase(); // Safari
	for (var i = 0; ds.length > i; i++) { 
		dsi = ds[i]; 
		dsir = (dsi.rules != undefined) ? dsi.rules : dsi.cssRules; // IE : Mozilla
		for (j = 0; dsir.length > j; j++) {
			if (dsir[j].selectorText && dsir[j].selectorText.toLowerCase() == cssClassName) {
				dsir[j].style[toChange] = changeTo; 
				return;
			}
		}
	} 
}

function styleSheetChangerVisitTree(cssClassName, toChange, changeTo) {
	visitTree(document.body, function (root) {
		var clsn = root.className;
		if (clsn != undefined) {
			var classes = clsn.divide(" ");
			for (var i = 0; i < classes.length; i++) {
				if ("."+classes[i] == cssClassName) {
					root.style[toChange] = changeTo;
					break;
				}
			}
		}
	});
}

function addClass(idOrElement, className) {
	var element = isString(idOrElement) ? getElement(idOrElement) : idOrElement;
	if(!element) return;
	var oldClasses = element.className.divide(" ");
	for (var i = 0; i < oldClasses.length; i++) {
		var cl = oldClasses[i];
		if (cl == className) return;
	}
	element.className = element.className + " " + className;
}

function removeClass(idOrElement, className) {
	var element = isString(idOrElement) ? getElement(idOrElement) : idOrElement;
	if(!element) return;
	var newClass = "";
	var oldClasses = element.className.divide(" ");
	for (var i = 0; i < oldClasses.length; i++) {
		var cl = oldClasses[i];
		if (cl != className) newClass += (cl + " ");
	}
	element.className = newClass;
}

function replaceClass(element, oldClass, newClass) {
	if(element == null) {
		return null;
	}
	
	var newClasses = "";
	var changed = false;
	var oldClasses = element.className.divide(" ");
	for (var i = 0; i < oldClasses.length; i++) {
		var cl = oldClasses[i];
		if (cl == oldClass) {
			newClasses += (newClass + " ");
			changed = true;
		} else {
			newClasses += (cl + " ");
		}
	}
	if (changed) element.className = newClasses;
	return changed;
}

function hideClass(className) {
	styleSheetChanger(className, "display", "none");
}

function showClass(className) {
	if (isSafari2()) {
		styleSheetChanger(className, "display", undefined); // Safari 2
	} else if (isOpera()) {
		styleSheetChanger(className, "display", "table-row"); // Opera
	} else {
		styleSheetChanger(className, "display", ""); // IE / Firefox / Safari 3 /Chrome
	}
}

function calculateVatAmount(amountIncVat, vat) {
	return decimalPoints(-(amountIncVat / (100.0 + vat) * 100.0) + amountIncVat, 2);
}

function resetSelect(select) {
	for (var i = 0; i < select.options.length; i++) {
		option = select.options[i];
		if (option.defaultSelected) {
			option.selected = true;
			option.blur();
			return;
		}
	}
}

function findPos(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		curleft = obj.offsetLeft
		curtop = obj.offsetTop
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft
			curtop += obj.offsetTop
		}
	}
	return [curleft,curtop];
}

function onchange(e) {
	var targ;
	if (!e) e = window.event;
	
	if (e.target) targ = e.target;
	else if (e.srcElement) targ = e.srcElement;
	
	if (targ.nodeType == 3) // defeat Safari bug
		targ = targ.parentNode;
		
	if (e.type == "change" || e.type == "keypress" || targ.type == "checkbox" || targ.type == "radio") {
		if (targ.form && targ.form.method.toLowerCase() == "post") {
			changed(targ.id, getElementValue(targ));
		}
	}
}

function getScrollXY(frame) {
	var win = frame.window;
	var doc = frame.document;
	var scrOfX = 0, scrOfY = 0;

	if( typeof( win.pageYOffset ) == 'number' ) {
		scrOfY = win.pageYOffset; scrOfX = win.pageXOffset;
	} else if( doc.body && ( doc.body.scrollLeft || doc.body.scrollTop ) ) {
		scrOfY = doc.body.scrollTop; scrOfX = doc.body.scrollLeft;
	} else if( doc.documentElement && ( doc.documentElement.scrollLeft || doc.documentElement.scrollTop ) ) {
		scrOfY = doc.documentElement.scrollTop; scrOfX = doc.documentElement.scrollLeft;
	}
	return [ scrOfX, scrOfY ];
}



/*
function onchange(input) {
	if (input.form && input.form.method.toLowerCase() == "post") {
		changed();
	}
}
*/

function changeTest(form) {
	if(form && form.method.toLowerCase() == "post") {
		return true;
	}
	
	if (getBottomFrame().isChanged()) {
		return confirm(messageContentChanged);
	}
	
	return true;
}

function changed(el, oldValue) {
	var bottom = getBottomFrame();
	if (bottom) {
		if (el) {
			bottom.setChanged(el, oldValue);
		} else {
			bottom.setChanged(true);
		}
	}
}

function isChanged(idOrElement) {
	var bottom = getBottomFrame();
	if (bottom) {
		var id = idOrElement ? (isString(idOrElement) ? idOrElement : idOrElement.id) : undefined;
		return bottom.isChanged(id);
	} else {
		return false;
	}
}

function getOldValue(idOrElement) {
	var bottom = getBottomFrame();
	if (bottom) {
		var id = idOrElement ? (isString(idOrElement) ? idOrElement : idOrElement.id) : undefined;
		return bottom.getOldValue(id);
	} else {
		return undefined;
	}
}

function onSubmenu()  {
//	hideContent();
}
function onLink()  {
//	hideContent();
}
function onFunction()  {
//	hideContent();
}
function onDownload()  {
}


// Events

function stopEvent(e) {
	if(!e) e = window.event;
	if(!e) return;
	if (e.preventDefault) { e.preventDefault(); } else { e.returnValue = false; }
	if (e.stopPropagation) { e.stopPropagation(); } else { e.cancelBubble = true; }
}


// XLS

function cleanDom(dom) {
	removeLinks(dom);
	removeInputs(dom);
	removeByClass(dom, "hideFromPrint");
	removeByClass(dom, "xlsHide");
}

function getDefaultTable() {
	var candidates = toArray(document.getElementsByTagName("TABLE"));
	var tables = arrayRemoveIf(candidates, function (table) {
		return !table.className || !arrayFind(table.className.divide(" "), "xls");
	});
	if (tables.length > 0) return tables[0];
	tables = arrayRemoveIf(candidates, function (table) {
		return !table.className || !arrayFind(table.className.divide(" "), "contentTable");
	});
	return tables[0];
}

function submit(target, action, method, values) {
	var form = document.createElement("form");
	form.style.display="none";
	form.method=method.toLowerCase();
	form.action=action;
	if (target) form.target=target;
	for (var name in values) {
		var input = document.createElement("textarea");
		input.name = name;
		input.value = values[name];
		form.appendChild(input);
	}
	var body = document.getElementsByTagName("BODY")[0];
	body.appendChild(form);
	form.submit();
	body.removeChild(form);
}

function html2xls(table, title) {
	var action = "/html2xls";
	if (title) {
		action += "/"+title+".xls";
	}
	var tableTag = "<table width=\"100%\">"+table.innerHTML+"</table>";
	var target = window.name;
	if (isIE()) {
		target = "_blank";
	}
	submit(target, action, "post", {
		"table": tableTag,
		"title": title
	});
}

function noXlsExportAlert() {
	alert(messageNoExcelExport);
}

function defaultXlsPage(table, title) {
	if (!title && getTitle) title = getTitle();
	if (!table) table = getDefaultTable();
	if (!table) {
		noXlsExportAlert();
		return;
	}
	table = table.cloneNode(true);
	cleanDom(table);
	html2xls(table, title);
}

function sessionTimeout() {
	alert(messageTimeout);
	logout(false);
}

function checkboxFix(form) {
	var elements = toArray(form.elements); // Prevents Opera from freaking out

	for (var i = 0; i < elements.length; i++) {
		var e = elements[i];	
		if (e.type && e.type.toUpperCase() == "CHECKBOX") {
			if (!e.checked) {
				addHiddenInput(form, e.name, "false");
				e.name = "";
			} else if (e.disabled) {
				addHiddenInput(form, e.name, "true");
				e.name = "";
			}
		} else if (e.disabled) {
			if (e.tagName && e.tagName.toUpperCase() == "SELECT" && e.selectedIndex >= 0) {
				addHiddenInput(form, e.name, e.options[e.selectedIndex].value);
				e.name = "";
			} else if (e.type && e.type.toUpperCase() == "TEXT") {
				addHiddenInput(form, e.name, e.value);
				e.name = "";
			}
		}
	}
}

function addHiddenInput(form, name, value) {
	var input = document.createElement("input");
	input.type = "hidden";
	input.name = name;
	input.value = value;
	form.appendChild(input);
}

function setCheckboxHiddenValue(chk, hiddenName) {
	var hidden = getElement(hiddenName);
	
	if(chk == null || hidden == null) {
		return;
	}
	
	if(chk.checked == true) {
		hidden.value = 'true';
	} 
	else {
		hidden.value = 'false';
	}
}

function getFormElementSet(form, namePattern) {
	var index = namePattern.indexOf("[]");
	var ret = [];
	if (index < 0) {
		var element = form.elements[namePattern];
		if (element) ret.push(element);
	} else {
		var pre = namePattern.substring(0, index+1);
		var post = namePattern.substring(index+1);
		var i = 0;
		do {
			var r = form.elements[pre + i + post];
			if (r) ret.push(r);
			i++;
		} while (r);
	}
	return ret;
}

function radioSetSelect(radioSet, radio) {
	if (radio.checked) {
		for (var i = 0; i < radioSet.length; i++) {
			var r = radioSet[i];
			if (r != radio) r.checked = false;
		}
	}
}


// JSON-RPC

function getJsonrpc() {
	return (getTopFrame() && getTopFrame().jsonrpc);
}

function makeIdMap(objects) {
	var map = {};
	for (var i = 0; i < objects.length; i++) {
		var object = objects[i];
		map[object.id] = object;
	}
	return map;
}

function displayJsonRpcError() {
	alert(messageUnexcpectedError);
}

function makeSafeCallback(callback) {
	var token = getContentFrame().token;
	return function (result, exception) {
		if (getContentFrame() && getContentFrame().token == token) {
			if (exception && exception.name == "no.tripletex.common.exception.NotLoggedInException") {
				alert(messageNotLoggedInError);
			} else if (exception) {
				displayJsonRpcError();
			} else {
				callback(result);
			}
		}
	}
}


function fillSelectSync(selectId, value, labelProperty, property, clazz, method) {
	document.body.style.cursor = "wait";
	var select = isString(selectId) ? getElement(selectId) : selectId;
	var disabled = select.disabled;
	select.disabled = true;
	var selectedIndex = select.selectedIndex;
	addOption(select, messageLoading, value, true);
	var toBeRemoved = select.selectedIndex;
	var args = [getTopFrame().marshallSpec(property, labelProperty)];
	for (var i=6;i<arguments.length;i++) args.push(arguments[i]);
	var c = getTopFrame().jsonrpc[clazz];
	var result = c[method].apply(c, args);
	fillSelect(select, result, property, labelProperty, false, value);
	if (select.selectedIndex == toBeRemoved && typeof(selectedIndex) == "number" && selectedIndex >= 0) {
		select.options[selectedIndex].selected = true;
	}
	select.remove(toBeRemoved);
	select.disabled = disabled;
	document.body.style.cursor = "default";
}

function fillSelectAsync(selectId, value, labelProperty, property, clazz, method) {
	var disabled = fillSelectAsync.prepareSelect(selectId, value);
	if (fillSelectAsync.calls) {
		var key = []; 
		for (var i=2;i<arguments.length;i++) key.push(arguments[i]);
		key = getTopFrame().toJSON(key);
		var callArgs = fillSelectAsync.calls[key];
		if (!callArgs) {
			callArgs = [];
			callArgs.push([]); callArgs.push([]); callArgs.push([]);
			for (var i=2;i<arguments.length;i++) callArgs.push(arguments[i]);
			fillSelectAsync.calls[key] = callArgs;
		}
		callArgs[0].push(selectId);
		callArgs[1].push(value);
		callArgs[2].push(disabled);
	} else {
		var args = [];
		args.push(selectId);
		args.push(value);
		args.push(disabled);
		for (var i=2;i<arguments.length;i++) args.push(arguments[i]);
		fillSelectAsync.perform1.apply(this, args);
	}
}

fillSelectAsync.calls = {};

fillSelectAsync.perform = function () {
	for (var key in fillSelectAsync.calls) {
		//alert(key);
		fillSelectAsync.perform1.apply(this, fillSelectAsync.calls[key]);
	}
	fillSelectAsync.calls = undefined;
};

fillSelectAsync.prepareSelect = function (selectId, value) {
    var select = getElement(selectId);

    if(select == null) {
    	return;
    }
    
    select.setAttribute("fillSelectAsync.selectedIndex", select.selectedIndex);

	var ret = select.disabled;
	select.disabled = true;
	addOption(select, messageLoading, value, true);
	return ret;
};

fillSelectAsync.perform1 = function (selectIds, values, disableds, labelProperty, property, clazz, method) {
	var args = [getTopFrame().makeSelectFillerCallback(selectIds, values, disableds, labelProperty, property), getTopFrame().marshallSpec(property, labelProperty)];
	for (var i=7;i<arguments.length;i++) args.push(arguments[i]);
	/*
	if (selectIds.constructor != Array) selectIds = [selectIds];
	if (values.constructor != Array) {
		var val = values;
		values = new Array();
		for (var i = 0; i < selectIds.length; i++) values[i] = val;
	}
	*/
	var c = getTopFrame().jsonrpc[clazz];
	c[method].apply(c, args);
};


// Messages / help

function getMessage(key) {
	var message = getMessage.cache[key];
	if (!message) {
		//	alert(key);
		message = getTopFrame().jsonrpc.MessageUtil.getMessage(key);
		getMessage.cache[key] = message;
	}
	return message;
}
getMessage.cache = {};

function showMessage(key) {
	if (showMessage.timeout && showMessage.timeout > 0) {
		enabletip = true;
		showMessage.timeoutId = setTimeout("showMessage.delayFunc('"+key+"')", showMessage.timeout);
	} else {
		ddrivetip(getMessage(key));
		tipobj().style.visibility="visible";
	}
}
showMessage.delayFunc = function(key) {
	ddrivetip(getMessage(key));
	tipobj().style.visibility="visible";
};
showMessage.timeout = 500;

function hideMessage(key) {
	if (showMessage.timeoutId) { 
		clearTimeout(showMessage.timeoutId);
		showMessage.timeoutId = undefined;
	}
	hideddrivetip();
}


// findOption

function isCharacterKeyCode(keyCode) {
	return (keyCode >= 48 && keyCode <= 57) || (keyCode >= 65 && keyCode <= 90) || (keyCode >= 96 && keyCode <= 111) || keyCode >= 186;
}

function findOption(select, ev) {
	var keyCode = ev.keyCode;

	if (isCharacterKeyCode(keyCode)) {
		findOption.select = select;
		findOption.selectedIndex = select.selectedIndex;
		var div = findOption.div = document.createElement("div");
		div.style.position = "absolute";
		div.style.zIndex = 1000000;
		div.style.width=select.offsetWidth+"px";
		div.style.border="0";
		div.style.padding="0";
	
		var input = findOption.input = document.createElement("input");
		input.type = "text";
		input.onkeydown = findOption.keyDown;
		input.onkeypress = findOption.keyPress;
		input.onblur = findOption.hide;
		input.style.border="1px solid black";
		input.style.width=select.offsetWidth+"px";
		input.style.height=select.offsetHeight+"px";
		div.appendChild(input);
		document.body.appendChild(div);

		var pos = findPos(select);
		div.style.left = pos[0]+"px";
		var height = input.offsetHeight;
		if (isSafari()) height += 2;
		if (pos[1] < height) {
			div.style.top = (pos[1]+height)+"px";
		} else {
			div.style.top = (pos[1]-height)+"px";
		}
		input.focus();
	}
}

findOption.keyDown = function(ev) {
	if (!ev) ev = window.event;
	var keyCode = ev.keyCode;
	var select = findOption.select;
	
	if (keyCode == 9) { // Tab
		findOption.hide();
	} else if (keyCode == 13) { // Enter
		findOption.hide();
	} else if (keyCode == 27) { // Esc
		select.selectedIndex = findOption.selectedIndex;
		findOption.hide();
		stopEvent(ev);
	} else if (keyCode == 37 || keyCode == 39) { // Left, Right
		stopEvent(ev);
	} else if (keyCode == 38) { // Up
		stopEvent(ev);
		findOption.findPreviousOption(findOption.input.value, true);
	} else if (keyCode == 40) { // Down
		stopEvent(ev);
		findOption.findNextOption(findOption.input.value, true);
	}
}

findOption.keyPress = function(ev) {
	if (!ev) ev = window.event;
	var keyCode = ev.keyCode ? ev.keyCode : ev.charCode;
	if (keyCode == 13) { // Enter
		stopEvent(ev);
		return;
	} else if (findOption.input) {
		var character = String.fromCharCode(keyCode);
		var searchPhrase = findOption.input.value+character;
		searchPhrase = searchPhrase.toUpperCase();
		findOption.findNextOption(searchPhrase);
	}
}

findOption.findNextOption = function(searchPhrase, next) {
	searchPhrase = searchPhrase.toUpperCase();
	var options = findOption.select.options;
	var current = findOption.select.selectedIndex;
	var length = options.length;
	
	for (var n = (next ? 1 : 0); n < length; n++) {
		var i = (current + n) % length;
		if (options[i].text.toUpperCase().indexOf(searchPhrase) >= 0) {
			findOption.selectOption(i);
			break;
		}
	}
}

findOption.findPreviousOption = function(searchPhrase, previous) {
	searchPhrase = searchPhrase.toUpperCase();
	var options = findOption.select.options;
	var current = findOption.select.selectedIndex;
	var length = options.length;
	
	for (var n = (previous ? 1 : 0); n < length; n++) {
		var i = (current - n);
		if(i < 0) i += length;
		
		if (options[i].text.toUpperCase().indexOf(searchPhrase) >= 0) {
			findOption.selectOption(i);
			break;
		}
	}
}

findOption.selectOption = function(index) {
	findOption.select.options[findOption.select.selectedIndex].selected = false;
	findOption.select.options[index].selected = true;
	if (isSafari3plus()) {
		var onblur = findOption.input.onblur;
		findOption.input.onblur = undefined;
		findOption.select.focus();
		findOption.input.focus();
		findOption.input.onblur = onblur;
	}
	//if (findOption.select.onchange) findOption.select.onchange();
}

findOption.hide = function() {
	findOption.div.parentNode.removeChild(findOption.div);
	findOption.select.focus();
	findOption.select.blur(); // IE fix
	findOption.select.focus(); // IE fix
	if (findOption.select.selectedIndex != findOption.selectedIndex && findOption.select.onchange) findOption.select.onchange();
	findOption.select = null;
	findOption.input = null;
	findOption.div = null;
}


// Date input

function dateOnChange(input, event) {
	if (input.value.trim() == "") return true;
	var date = parseDate(input.value, true);
	if (date) {
		input.value = formatDate(date, "yyyy-MM-dd");
		return true;
	} else {
		alert(messageInvalidDate);
		input.value = "";
		if (!isIE()) setTimeout(function () { input.focus(); }, 1);
		stopEvent(event);
		return false;
	}
}

function dateOnKeyDown(input, event) {
	var keyCode = event.keyCode;
	var date = parseDate(input.value, true);
	if (event.ctrlKey || event.altKey || event.shiftKey) {
		return true;
	} else {
		if (keyCode == 84) { // t
			date = new Date();
		} else if (keyCode == 67) { // c
			var inpId = input.id;
			var inpValue = input.value;
			var imgId = inpId + ".cal.img";
			setTimeout(function () {
				var inp = getElement(inpId);
				var img = getElement(imgId);
				if (inp && img && img.onclick) {
					inp.value = date ? inpValue : ""; // Opera
					inp.blur();
					img.onclick();
				} else if (inp && img) {
					//calSetup(inpId, imgId).redraw();
				}
			}, 1);
			stopEvent(event);
			return false;
		} else if (date) {
			if (keyCode == 38) { // Up
				date = addDays(date, -1);
			} else if (keyCode == 40) { // Down
				date = addDay(date);
			} else if (keyCode == 33) { // Page Up
				date = addMonths(date, -1);
			} else if (keyCode == 34) { // Page Down
				date = addMonth(date);
			} else {
				date = null;
			}
		} else {
			date = null;
		}
	}
	
	if (date) {
		if (isOpera()) {
			setTimeout(function () { input.value = formatDate(date, "yyyy-MM-dd"); }, 1);
			return false;
		} else {
			input.value = formatDate(date, "yyyy-MM-dd");
			stopEvent(event);
			return false;
		}
	} else {
		return true;
	}
}


// Extra frame

function viewerDocument(id) {
	var url = "/execute/viewer?act=viewerDocument&KeepFCache=&id="+id;
	var frame = getMainWindow().extraFrame.expand();
	frame.document.location = url;
}

function viewerPdf(pdfUrl) {
	var url = "/execute/viewer?act=viewerPdf&KeepFCache=&url="+escape(pdfUrl);
	var frame = getMainWindow().extraFrame.expand();
	frame.document.location = url;
}

function viewerVoucher(id, noPostings) {
	var url = "/execute/viewer?act=viewerVoucher&KeepFCache=&id="+id;
	var frame = getMainWindow().extraFrame.expand();
	if (noPostings) url += "&noPostings=";
	frame.document.location = url;
}

function collapseExtra() {
	var main = getMainWindow();
	if(main && main.extraFrame) main.extraFrame.collapse();
}

function encodeHTML(html) {
	html = html.replace(/&/,"&amp;");
	html = html.replace(/</,"&lt;");
	html = html.replace(/>/,"&gt;");
	html = html.replace(/'/,"&quot;");
	html = html.replace(/\r\n/,"<br/>");
	html = html.replace(/\n/,"<br/>");
	html = html.replace(/\r/,"<br/>");
	return html;
} 

function documentOnkeydown(event) {
	if(!event) event = window.event;
	var keyCode = event.keyCode ? event.keyCode : event.charCode;

	if((event.ctrlKey || event.metaKey) && keyCode == 83) {
		// CTRL-S
		//var targ;		
		//if (event.target) targ = event.target;
		//else if (event.srcElement) targ = event.srcElement;

		//if(targ) {
			//alert("srcElement: " + srcElement.value);
			//targ.blur();
		//}
		
		var saveButton = getElement("SaveButton");
		
		if(saveButton && !saveButton.disabled) {
			saveButton.focus();
			
			setTimeout( function () {
				submitWithoutWarning1(saveButton);			
			}, 1);
			
			stopEvent(event);
			return false;
		}
	}
	
	return true;
}
function documentOnclick(event) {
	if(currentTlxSelectId) {
		tlxSelectCloseOuterDiv(currentTlxSelectId);
	}
}
// StringBuffer
function StringBuffer() { 
	this.buffer = []; 
} 

StringBuffer.prototype.append = function append(string) { 
	this.buffer.push(string); 
	return this; 
}; 

StringBuffer.prototype.toString = function toString() { 
	return this.buffer.join(""); 
}; 



// TLXSELECT
var tlxSelectMaxRows = 1000;
var tlxSelectIgnoreMouseover = false;

function isTlxSelectElement(element) {
	return element.tagName && element.tagName.toUpperCase() == "INPUT" && element.type && element.type.toUpperCase() == "HIDDEN" && element.getAttribute("tlxSelectType");
}

function tlxSelectOnclickOuterDiv(event) {
	if(!event) event = window.event;
	stopEvent(event);
	return false;
}

function tlxSelectOnclickCloseImg(event, propertyId) {
	tlxSelectCollapse(propertyId);
	stopEvent(event);
	return false;
}

function tlxSelectOnclickArrow(event, propertyId) {
	tlxSelectExpandCollapse(propertyId);
	stopEvent(event);
	return false;
}
function tlxSelectOnclickInput(event, propertyId) {
	tlxSelectExpandCollapse(propertyId);
	stopEvent(event);
	return false;
}
function tlxSelectOnkeydown(event, propertyId) {
	if(tlxSelectGetDisabled(propertyId)) return;
	if(tlxSelectGetReadonly(propertyId)) return true;
	var keyCode = event.keyCode ? event.keyCode : event.charCode;

	if (keyCode == 40 || isCharacterKeyCode(keyCode)) {
		tlxSelectExpand(propertyId);
	}
	
	return true;
}
function tlxSelectOnkeydownSearch(event, propertyId) {
	var keyCode = event.keyCode ? event.keyCode : event.charCode;
	var searchElement = tlxSelectGetSearchElement(propertyId);
	var propertyElement = getElement(propertyId);
	//alert("Keycode: " + keyCode);
	
	if(keyCode == 13) {
		// Enter
		var selectedIndex = searchElement.getAttribute("tlxSelectSelectedIndex");
		
		if(selectedIndex) {
			tlxSelectSetSelectedValue(propertyId);
			tlxSelectCollapse(propertyId);
		} else {
			tlxSelectSearch(propertyId);
			//var oldSearchString = searchElement.getAttribute("tlxSelectSearchOldValue");
			//var searchString = getElementValue(searchElement);
			
			//if(oldSearchString == undefined || oldSearchString != searchString) {
			//}
		}

		stopEvent(event);
		return false;
	} else if(keyCode == 27) {
		// ESC
		tlxSelectCollapse(propertyId);
	} else if (keyCode == 38) { // Up
		tlxSelectIgnoreMouseover = true;
		var selectedIndex = searchElement.getAttribute("tlxSelectSelectedIndex");
		
		if(selectedIndex) {
			var selectedIndexValue = parseInt(selectedIndex);
			if(selectedIndexValue > 0) tlxSelectSelectRow(propertyId, selectedIndexValue - 1, true);		
		}
		
	} else if (keyCode == 40) { // Down
		tlxSelectIgnoreMouseover = true;
		var selectedIndex = searchElement.getAttribute("tlxSelectSelectedIndex");

		if(!selectedIndex) {
			tlxSelectSelectRow(propertyId, 0, true);							
		} else {
			var selectedIndexValue = parseInt(selectedIndex);
			tlxSelectSelectRow(propertyId, selectedIndexValue + 1, true);
		}
	} else if(isCharacterKeyCode(keyCode)) {
		tlxSelectUnselectRow(propertyId);	
	}
	
	return true;
}
function tlxSelectOnclickSearchButton(propertyId) {
	tlxSelectSearch(propertyId);
}
function txlSelectCreateOuterDiv(propertyId) {
	var propertyElement = getElement(propertyId);
	var selectElement = tlxSelectGetSelectElement(propertyId);
	var selectElementParent = selectElement.parentNode;
	var selectElementPos = findPos(selectElement);
	var height = tlxSelectGetHeight(propertyId);
	
	var outerDiv = document.createElement("div");
	outerDiv.id = propertyId + "OuterDiv";
	outerDiv.onclick = tlxSelectOnclickOuterDiv;
	outerDiv.className = "tlxSelectOuterDiv";
	if(height) outerDiv.style.height = height;
	outerDiv.style.left = selectElementPos[0] + "px";
	
	var selectElementHeight = selectElement.offsetHeight;
	outerDiv.style.top = (selectElementPos[1] + selectElementHeight)+"px";
	var buffer = new StringBuffer();
	buffer.append("<input type=\"text\" id=\"");
	buffer.append(propertyId);
	buffer.append("Search\" name=\"");
	buffer.append(propertyId);
	buffer.append("Search\" class=\"tlxSelectSearchInput\" value=\"\" onkeydown=\"var event = arguments[0] || window.event;return tlxSelectOnkeydownSearch(event, '");
	buffer.append(propertyId);
	buffer.append("');\"/>");
	buffer.append("<input type=\"button\" name=\"SearchButton\" value=\"");
	buffer.append(messageSearch);
	buffer.append("\" class=\"tlxSelectSearchButton\" onclick=\"tlxSelectOnclickSearchButton('");
	buffer.append(propertyId);
	buffer.append("');\"/>");
	buffer.append("<img src=\"/resources/images/tlxselect-close.jpg\" class=\"tlxSelectCloseImg\" onclick=\"var event = arguments[0] || window.event;tlxSelectOnclickCloseImg(event, '");
	buffer.append(propertyId);
	buffer.append("');\" border=\"0\" alt=\"\" title=\"\"/>");
	buffer.append("<div id=\"");
	buffer.append(propertyId);
	buffer.append("ListDiv\" class=\"tlxSelectListDiv\"");
	//if(isIE()) buffer.append(" style=\"padding-right: 15px;\"");
	buffer.append("></div>");
	outerDiv.innerHTML = buffer.toString();
	selectElementParent.appendChild(outerDiv);
	return outerDiv;	
}

function tlxSelectFireOnchange(propertyId) {
	var propertyElement = getElement(propertyId);
	var type = tlxSelectGetType(propertyId);	
	
	// Dependencies
	if(type == "Department") {
		tlxSelectFireOnchangeDepartment(propertyId);
	} else if(type == "Project") {
		tlxSelectFireOnchangeProject(propertyId);
	} else if(type == "ProjectCategory") {
		tlxSelectFireOnchangeProjectCategory(propertyId);
	} else if(type == "EmployeeCategory") {
		tlxSelectFireOnchangeEmployeeCategory(propertyId);
	} else if(type == "Customer") {
		tlxSelectFireOnchangeCustomer(propertyId);
	} else if(type == "Employee") {
		tlxSelectFireOnchangeEmployee(propertyId);
	} else if(type == "CustomerCategory") {
		tlxSelectFireOnchangeCustomerCategory(propertyId);
	}
		
	var onchange = propertyElement.getAttribute("tlxSelectOnchange");
	
	if(onchange != undefined) {
		//alert("onchange: " + onchange);
		eval(onchange);
	}
}
function tlxSelectFireOnchangeDepartment(propertyId) {
	var propertyElement = getElement(propertyId);
	var departmentId = getElementInt(propertyElement);
	
	if(departmentId > 0) {
		var employeeElementIds = tlxSelectGetAttributeStringValue(propertyId, "tlxSelectEmployeeElementId");

		if(employeeElementIds) {
			var ids = employeeElementIds.split(",");
			
			for(var i = 0; i < ids.length; i++) {
				var employeeElementId = ids[i];
				var employeeId = getElementInt(employeeElementId, 0);
				
				if(employeeId > 0) {
					var employee = getTopFrame().jsonrpc.Employee.get(tlxSelectGetEmployeeMarshallSpec(propertyId), employeeId);
					
					if(employee.departmentId != departmentId) {
						var defaultOptions = tlxSelectGetDefaultOptions(employeeElementId);				
						if(defaultOptions.length > 0) setElementValue(employeeElementId, defaultOptions[0][0]);
					}					
				}
			}
		}
		
		var projectElementId = tlxSelectGetAttributeStringValue(propertyId, "tlxSelectProjectElementId");

		if(projectElementId) {
			var projectId = getElementInt(projectElementId, 0);
			
			if(projectId > 0) {
				var project = getTopFrame().jsonrpc.Project.get(tlxSelectGetProjectMarshallSpec(propertyId), projectId);
				
				if(project.departmentId != departmentId) {
					var defaultOptions = tlxSelectGetDefaultOptions(projectElementId);				

					if(defaultOptions.length > 0) {
						setElementValue(projectElementId, defaultOptions[0][0]);
						tlxSelectFireOnchangeProject(projectElementId);
					}
				}					
			}			
		}
	}
}
function tlxSelectFireOnchangeProject(propertyId) {
	var activityElementId = tlxSelectGetAttributeStringValue(propertyId, "tlxSelectActivityElementId");

	if(activityElementId) {
		var defaultOptions = tlxSelectGetDefaultOptions(activityElementId);				
		if(defaultOptions.length > 0) setElementValue(activityElementId, defaultOptions[0][0]);
	}
	/*
	var projectId = getElementInt(propertyElement);
	
	if(projectId > 0) {
	}
	*/
}
function tlxSelectFireOnchangeCustomer(propertyId) {
	var propertyElement = getElement(propertyId);
	var customerId = getElementInt(propertyElement);
	
	if(customerId > 0) {
		var employeeElementIds = tlxSelectGetAttributeStringValue(propertyId, "tlxSelectEmployeeElementId");
		
		if(employeeElementIds) {
			var ids = employeeElementIds.split(",");
			
			for(var i = 0; i < ids.length; i++) {
				var employeeElementId = ids[i];
				var employeeId = getElementInt(employeeElementId, 0);
				
				if(employeeId > 0) {
					var employee = getTopFrame().jsonrpc.Employee.get(tlxSelectGetEmployeeMarshallSpec(propertyId), employeeId);
					
					if(employee.customerId != customerId) {
						var defaultOptions = tlxSelectGetDefaultOptions(employeeElementId);				

						if(defaultOptions.length > 0) {
							setElementValue(employeeElementId, defaultOptions[0][0]);
						}
					}					
				}			
			}
		}

		var projectElementId = tlxSelectGetAttributeStringValue(propertyId, "tlxSelectProjectElementId");

		if(projectElementId) {
			var projectId = getElementInt(projectElementId, 0);
			
			if(projectId > 0) {
				var project = getTopFrame().jsonrpc.Project.get(tlxSelectGetProjectMarshallSpec(propertyId), projectId);
				
				if(project.customerId != customerId) {
					var defaultOptions = tlxSelectGetDefaultOptions(projectElementId);				

					if(defaultOptions.length > 0) {
						setElementValue(projectElementId, defaultOptions[0][0]);
					}
				}					
			}			
		}
	}
}
function tlxSelectFireOnchangeProjectCategory(propertyId) {
	var propertyElement = getElement(propertyId);
	var projectCategoryId = getElementInt(propertyElement);
	
	if(projectCategoryId > 0) {
		var projectElementId = tlxSelectGetAttributeStringValue(propertyId, "tlxSelectProjectElementId");

		if(projectElementId) {
			var projectId = getElementInt(projectElementId, 0);
			
			if(projectId > 0) {
				var project = getTopFrame().jsonrpc.Project.get(tlxSelectGetProjectMarshallSpec(propertyId), projectId);
				
				if(project.projectCategoryId != projectCategoryId) {
					var defaultOptions = tlxSelectGetDefaultOptions(projectElementId);				

					if(defaultOptions.length > 0) {
						setElementValue(projectElementId, defaultOptions[0][0]);
						tlxSelectFireOnchangeProject(projectElementId);
					}
				}					
			}			
		}
	}
}
function tlxSelectFireOnchangeCustomerCategory(propertyId) {
	var propertyElement = getElement(propertyId);
	var customerCategoryId = getElementInt(propertyElement);
	
	if(customerCategoryId > 0) {
		var customerElementId = tlxSelectGetAttributeStringValue(propertyId, "tlxSelectCustomerElementId");
		var categoryType = tlxSelectGetAttributeIntValue(propertyId, "tlxSelectArg0", -1);

		if(customerElementId && categoryType > 0) {
			var customerId = getElementInt(customerElementId, 0);
			
			if(customerId > 0 && categoryType > 0) {
				var customer = getTopFrame().jsonrpc.Company.get(tlxSelectGetCustomerMarshallSpec(propertyId), customerId);
				
				if((categoryType == 1 && customer.customerCategoryId1 != customerCategoryId) || 
						(categoryType == 2 && customer.customerCategoryId2 != customerCategoryId) ||
						(categoryType == 3 && customer.customerCategoryId3 != customerCategoryId)) {
					var defaultOptions = tlxSelectGetDefaultOptions(customerElementId);				

					if(defaultOptions.length > 0) {
						setElementValue(customerElementId, defaultOptions[0][0]);
						tlxSelectFireOnchangeCustomer(customerElementId);
					}
				}					
			}			
		}
	}
}
function tlxSelectFireOnchangeEmployee(propertyId) {
	var propertyElement = getElement(propertyId);
	var employeeId = getElementInt(propertyElement);
	
	if(employeeId > 0) {
		var projectElementId = tlxSelectGetAttributeStringValue(propertyId, "tlxSelectProjectElementId");

		if(projectElementId) {
			var projectId = getElementInt(projectElementId, 0);
			
			if(projectId > 0) {
				var project = getTopFrame().jsonrpc.Project.get(tlxSelectGetProjectMarshallSpec(propertyId), projectId);
				
				if(project.employeeId != employeeId) {
					var defaultOptions = tlxSelectGetDefaultOptions(projectElementId);				

					if(defaultOptions.length > 0) {
						setElementValue(projectElementId, defaultOptions[0][0]);
						tlxSelectFireOnchangeProject(projectElementId);
					}
				}					
			}			
		}
	}
}
function tlxSelectFireOnchangeEmployeeCategory(propertyId) {
	var propertyElement = getElement(propertyId);
	var employeeCategoryId = getElementInt(propertyElement);
	
	if(employeeCategoryId > 0) {
		var employeeElementIds = tlxSelectGetAttributeStringValue(propertyId, "tlxSelectEmployeeElementId");

		if(employeeElementIds) {
			var ids = employeeElementIds.split(",");
			
			for(var i = 0; i < ids.length; i++) {
				var employeeElementId = ids[i];
				var employeeId = getElementInt(employeeElementId, 0);
				
				if(employeeId > 0) {
					var employee = getTopFrame().jsonrpc.Employee.get(tlxSelectGetEmployeeMarshallSpec(propertyId), employeeId);
					
					if(employee.employeecategoryid != employeeCategoryId) {
						var defaultOptions = tlxSelectGetDefaultOptions(employeeElementId);				

						if(defaultOptions.length > 0) {
							setElementValue(employeeElementId, defaultOptions[0][0]);
						}
					}					
				}			
			}
		}
	}
}
function tlxSelectSearch(propertyId) {
	// Search
	var searchElement = tlxSelectGetSearchElement(propertyId);
	var searchString = getElementValue(searchElement);
	//var oldSearchString = searchElement.getAttribute("tlxSelectSearchOldValue");
	//if(oldSearchString && oldSearchString == searchString) return;
	if(currentTlxSelectSearchId == -1) return; // In tlxSelectSearchFunctionCallback
	currentTlxSelectSearchId++;
	var searchId = currentTlxSelectSearchId;
	
	var listDivElement = getElement(propertyId + "ListDiv");
	
	if(listDivElement) {
		listDivElement.innerHTML = "<img src='/resources/images/ajax-loader.gif' width='16' height='16' border='0' alt='Loading' />";
	}
	
	var searchFunction = tlxSelectGetSearchFunction(searchId, propertyId, searchString);
	if(searchFunction) eval(searchFunction);
}
function tlxSelectSearchFunctionCallback(searchId, propertyId) {
	return function(objects) {
		if(searchId != currentTlxSelectSearchId) return; // New search started
		currentTlxSelectSearchId = -1; // Lock
		var propertyElement = getElement(propertyId);
		
		if(!propertyElement) {
			currentTlxSelectSearchId = 0;
			return;
		}
		
		if(window.tlxSelectSearchFilter) {
			objects = window.tlxSelectSearchFilter(propertyId, objects);
		}		

		var currentValueAsString = getElementValue(propertyElement);
		var searchElement = tlxSelectGetSearchElement(propertyId);
		var searchString = getElementValue(searchElement).toLowerCase();

		searchElement.removeAttribute("tlxSelectSelectedIndex");
		//searchElement.setAttribute("tlxSelectSearchOldValue", searchString);
				
		// Create div
		var buffer = new StringBuffer();
	
		if(objects.length == tlxSelectMaxRows) {
			buffer.append("<div class=\"tlxSelectMaxRows\">");
			buffer.append(textShowing);
			buffer.append(" 1 - ");
			buffer.append(objects.length);
			buffer.append("</div>");
		}
		 	
		// Create table
		buffer.append("<table cellspacing=\"4\" class='tlxSelectListTable'><tr>");
		
		// Heading	
		var props = tlxSelectGetProperties(propertyId);
		
		if(props) {
			for(var i = 0; i < props.length; i++) {
				var prop = props[i];
				buffer.append("<th");
				
				if(prop.width) {
					buffer.append(" width='");
					buffer.append(prop.width);
					buffer.append("'");
				}
				
				buffer.append(">");
				if(prop.heading) buffer.append(encodeHTML(prop.heading));
				buffer.append("</th>");
			}
		}
	
		buffer.append("</tr>");
		
		// Default options
		var colspan = props ? props.length : 1;
		var defaultOptions = tlxSelectGetDefaultOptions(propertyId);
		var row = 0;
		var autoSelectRow = -1;
		
		if(defaultOptions) {
			for(; row < defaultOptions.length; row++) {
				var option = defaultOptions[row];
				var value = option[0];		
				var text1 = encodeHTML(option[1]);
				var text2 = encodeHTML(option[2]);
				if(text2.toLowerCase() == searchString) autoSelectRow = row;
				buffer.append("<tr id='");
				buffer.append(propertyId);
				buffer.append("ListRow");
				buffer.append(row);
				buffer.append("' onmouseover=\"tlxSelectOnmouseoverRow('");
				buffer.append(propertyId);
				buffer.append("', ");
				buffer.append(row);
				buffer.append(");\" onclick=\"tlxSelectOnclickRow('");
				buffer.append(propertyId);
				buffer.append("', ");
				buffer.append(row);
				buffer.append(");\"><td colspan='");
				buffer.append(colspan);
				buffer.append("' class='nowrap'>");
				
				buffer.append("<span");
				buffer.append(" id='");
				buffer.append(propertyId);
				buffer.append("OptionText");
				buffer.append(row);
				buffer.append("' style='display:none;'>");
				buffer.append(text1);
				buffer.append("</span>");
			
				buffer.append("<span");
				buffer.append(" id='");
				buffer.append(propertyId);
				buffer.append("OptionValue");
				buffer.append(row);
				buffer.append("' style='display:none;'>");
				buffer.append(value);
				buffer.append("</span>");

				buffer.append(text2);
				buffer.append("</td></tr>");	
			}
		}
	
		var selectedRow = -1;
		
		if(objects.length > 0) {
			var idProperty = tlxSelectGetObjectValueProperty(propertyId);
			var displayNameProperty = tlxSelectGetDisplayNameProperty(propertyId);
	
			for (var i = 0; i < objects.length; i++) {
				var object = objects[i];
				var id = eval("object." + idProperty);
				var idAsString = isString(id) ? id : "" + id;
				var isSelected = idAsString == currentValueAsString;
				var styleClass = isSelected ? "tableContentSelected" : "tableContent";
	
				if(isSelected) {
					searchElement.setAttribute("tlxSelectSelectedIndex", String(row));
					selectedRow = row;
				}
	
				var displayName = encodeHTML(eval("object." + displayNameProperty));			
				
				buffer.append("<tr id='");
				buffer.append(propertyId);
				buffer.append("ListRow");
				buffer.append(row);
				buffer.append("' class='");
				buffer.append(styleClass);
				buffer.append("' onmouseover=\"tlxSelectOnmouseoverRow('");
				buffer.append(propertyId);
				buffer.append("', ");
				buffer.append(row);
				buffer.append(");\" onclick=\"tlxSelectOnclickRow('");
				buffer.append(propertyId);
				buffer.append("', ");
				buffer.append(row);
				buffer.append(");\">");
	
				for(var j = 0; j < props.length; j++) {
					var prop = props[j];
					
					buffer.append("<td");

					if(prop.align) {
						buffer.append(" align='");
						buffer.append(prop.align);
						buffer.append("'");
					}

					buffer.append(" class='nowrap'>");
					
					if(j == 0) {
						buffer.append("<span");
						buffer.append(" id='");
						buffer.append(propertyId);
						buffer.append("OptionText");
						buffer.append(row);
						buffer.append("' style='display:none;'>");
						buffer.append(displayName);
						buffer.append("</span>");
					
						buffer.append("<span");
						buffer.append(" id='");
						buffer.append(propertyId);
						buffer.append("OptionValue");
						buffer.append(row);
						buffer.append("' style='display:none;'>");
						buffer.append(id);
						buffer.append("</span>");
					}
					
					var propValue = eval("object." + prop.prop);
					
					if(isString(propValue)) {
						if(prop.maxLength) {
							buffer.append(encodeHTML(propValue.cut(prop.maxLength)));
						} else {
							buffer.append(encodeHTML(propValue));
						}
					} else if(isBoolean(propValue)) {
						if(propValue) buffer.append("<span class='checkboxOn'>&times;</span>");
						//else buffer.append("<span class='checkboxOff'>&nbsp;</span>");
					} else if(prop.type && prop.type == "amount") {
						buffer.append(formatAmount(propValue));				
					} else {
						buffer.append(propValue);				
					}
					
					buffer.append("</td>");
				}
				
				buffer.append("</tr>");
				row++;
			}	
		}
		
		buffer.append("</table>");
		var listDivElement = getElement(propertyId + "ListDiv");
		
		if(listDivElement) {
			if(!isElementHidden(propertyId + "OuterDiv")) {
				listDivElement.innerHTML = buffer.toString();
				
				if(autoSelectRow == -1 && searchString != '' && objects.length == 1) {
					var object = objects[0];
					
					if(object.number) {
						var numberAsString = isString(object.number) ? object.number : "" + object.number;
						if(numberAsString.toLowerCase() == searchString) autoSelectRow = row - 1;
					}
					
					if(object.customerAccountNumber) {
						var customerAccountNumberAsString = "" + object.customerAccountNumber;
						if(customerAccountNumberAsString == searchString) autoSelectRow = row - 1;
					}

					if(object.vendorAccountNumber) {
						var vendorAccountNumberAsString = "" + object.vendorAccountNumber;
						if(vendorAccountNumberAsString == searchString) autoSelectRow = row - 1;
					}

					if(autoSelectRow == -1 && object.name && object.name.toLowerCase() == searchString) autoSelectRow = row - 1;
					if(autoSelectRow == -1 && object.fullName && object.fullName.toLowerCase() == searchString) autoSelectRow = row - 1;
					if(autoSelectRow == -1 && object.elNumber && object.elNumber.toLowerCase() == searchString) autoSelectRow = row - 1;
					if(autoSelectRow == -1 && object.nrfNumber && object.nrfNumber.toLowerCase() == searchString) autoSelectRow = row - 1;
				}
				
				if(autoSelectRow != -1) {
					tlxSelectOnclickRow(propertyId, autoSelectRow);
				} else {
					tlxSelectScrollToSelectedElement(propertyId);					
				}
			}
		}

		currentTlxSelectSearchId = 0;
	}
}

function tlxSelectScrollToSelectedElement(propertyId) {
	var searchElement = tlxSelectGetSearchElement(propertyId);
	var selectedIndex = searchElement.getAttribute("tlxSelectSelectedIndex");
	
	if(selectedIndex) {
		var selectedIndexIntValue = parseInt(selectedIndex);
		var selectedRowElement = getElement(propertyId + "ListRow" + selectedIndex);
		var listDivElement = getElement(propertyId + "ListDiv");	
		listDivElement.scrollTop = selectedRowElement.offsetTop;		
	}	
}

function tlxSelectExpand(propertyId) {
	if(currentTlxSelectId && currentTlxSelectId != propertyId) {
		// Delete current
		tlxSelectCloseOuterDiv(currentTlxSelectId);
	}

	var outerDivElement = getElement(propertyId + "OuterDiv");
	if(!outerDivElement) outerDivElement = txlSelectCreateOuterDiv(propertyId);
	else showElement(outerDivElement);
	
	var searchElement = tlxSelectGetSearchElement(propertyId);
	searchElement.focus();
	
	scrollToElement(outerDivElement);
	
	//var bodyHeight =  document.getElementsByTagName('body')[0].clientHeight;
	//var windowScrollXY = getScrollXY(getContentFrame());	
	//var windowBottomY = bodyHeight - windowScrollXY[1];	
	//var outerDivBottomY = outerDivElement.offsetTop + outerDivElement.offsetHeight;
	//var scrollY = outerDivBottomY - windowBottomY;
	//if(scrollY > 0) window.scrollTo(0, scrollY);
	//var diffY = outerDivElement.offsetTop - windowScrollXY[1];
	//if(diffY > 200) window.scrollTo(0, outerDivElement.offsetTop - 200);
	
	//var tlxSelectAutoFill = tlxSelectGetAutoFill(propertyId);	
	//if(tlxSelectAutoFill) tlxSelectSearch(propertyId);
	var type = tlxSelectGetType(propertyId);	
	if(!ijobman || type != "Product") tlxSelectSearch(propertyId);
	currentTlxSelectId = propertyId;
}
function scrollToElement(idOrElement) {
	var element = isString(idOrElement) ? getElement(idOrElement) : idOrElement;
	if(!element) return;
	var windowScrollXY = getScrollXY(getContentFrame());	
	var elementXY = findPos(element);
	
	var diffY = elementXY[1] - windowScrollXY[1];
	//alert("elementXY[1]: " + elementXY[1]);
	//alert("windowScrollXY[1]: " + windowScrollXY[1]);
	//alert("diffY: " + diffY);
	if(diffY > 200) window.scrollTo(0, elementXY[1] - 200);	
}

function tlxSelectCollapse(propertyId) {
	var selectElement = tlxSelectGetSelectElement(propertyId); 

	if(selectElement) {
		try {
			selectElement.focus();
		} catch(err) {} // In case of submit
	}

	tlxSelectCloseOuterDiv(propertyId);
}
function tlxSelectCloseOuterDiv(propertyId) {
	var outerDiv = getElement(propertyId + "OuterDiv");
	if(!outerDiv) return;
	hideElement(outerDiv);
	
	var listDivElement = getElement(propertyId + "ListDiv");	
	if(listDivElement) listDivElement.innerHTML = '';

	var searchElement = tlxSelectGetSearchElement(propertyId);
	setElementValue(searchElement, '');

	if(propertyId == currentTlxSelectId) currentTlxSelectId = null;
}
function tlxSelectExpandCollapse(propertyId) {
	if(tlxSelectGetDisabled(propertyId)) return;
	if(tlxSelectGetReadonly(propertyId)) return;
	var outerDivElement = getElement(propertyId + "OuterDiv");
	
	if(!outerDivElement || isElementHidden(outerDivElement)) {
		tlxSelectExpand(propertyId);
	} else {
		tlxSelectCollapse(propertyId);
	}
}
function tlxSelectSelectRow(propertyId, row, scroll) {
	var propertyElement = getElement(propertyId);
	var searchElement = tlxSelectGetSearchElement(propertyId);
	var rowElement = getElement(propertyId + "ListRow" + row);

	if(rowElement) {
		tlxSelectUnselectRow(propertyId);	
		addClass(rowElement, "tableContentSelected");
		searchElement.setAttribute("tlxSelectSelectedIndex", String(row));
		if(scroll) tlxSelectScrollToSelectedElement(propertyId);
	}
}
function tlxSelectOnmouseoverRow(propertyId, row) {
	if(tlxSelectIgnoreMouseover) tlxSelectIgnoreMouseover = false;
	else tlxSelectSelectRow(propertyId, row, false);
}
function tlxSelectUnselectRow(propertyId) {
	var propertyElement = getElement(propertyId);
	var searchElement = tlxSelectGetSearchElement(propertyId);
	var selectedIndex = searchElement.getAttribute("tlxSelectSelectedIndex");
	
	if(selectedIndex != undefined) {
		var rowElement = getElement(propertyId + "ListRow" + selectedIndex);
	
		if(rowElement) {
			removeClass(rowElement, "tableContentSelected");	
		}
	}

	searchElement.removeAttribute("tlxSelectSelectedIndex");
}
function tlxSelectOnclickRow(propertyId, row) {
	tlxSelectSelectRow(propertyId, row, false);
	tlxSelectSetSelectedValue(propertyId);
	tlxSelectCollapse(propertyId);
}

function tlxSelectSetSelectedValue(propertyId) {
	var propertyElement = getElement(propertyId);
	var searchElement = tlxSelectGetSearchElement(propertyId);
	var selectedIndex = searchElement.getAttribute("tlxSelectSelectedIndex");
	
	if(selectedIndex) {
		var row = parseInt(selectedIndex);	
		var optionValue = getElement(propertyId + "OptionValue" + row);

		if(optionValue) {
			// Set value
			var oldValue = getElementValue(propertyId);
			var newValue = getElementValue(optionValue);
	
			if(oldValue != newValue) {
				setElementValue(propertyId, newValue);
				var displayNameValue = getElementValue(propertyId + "OptionText" + row);
				var selectElement = tlxSelectGetSelectElement(propertyId);
				setElementValue(selectElement, displayNameValue);
				tlxSelectFireOnchange(propertyId);
			}
		}
	}		
}

function tlxSelectGetSelectElement(propertyId) {
	return getElement(propertyId + "Select");
}
function tlxSelectGetSelectDivElement(propertyId) {
	return getElement(propertyId + "SelectDiv");
}
function tlxSelectGetSearchElement(propertyId) {
	return getElement(propertyId + "Search");
}
function tlxSelectGetReadonly(propertyId) {
	var propertyElement = getElement(propertyId);
	var isReadonly = propertyElement.getAttribute("tlxSelectReadonly"); 
	return isReadonly != undefined;	
}
function tlxSelectSetReadonly(propertyId, readonly) {
	var propertyElement = getElement(propertyId);
	if(readonly) {
		propertyElement.setAttribute("tlxSelectReadonly", "true");
	} else {
		propertyElement.removeAttribute("tlxSelectReadonly");
	}
}
function tlxSelectGetHeight(propertyId) {
	var propertyElement = getElement(propertyId);
	return propertyElement.getAttribute("tlxSelectHeight");
}
function tlxSelectGetDisabled(propertyId) {
	var propertyElement = getElement(propertyId);
	var isDisabled = propertyElement.getAttribute("tlxSelectDisabled"); 
	return isDisabled != undefined;	
}
function tlxSelectSetDisabled(propertyId, disabled) {
	var propertyElement = getElement(propertyId);
	var selectElement = tlxSelectGetSelectElement(propertyId);

	if(disabled) {
		propertyElement.setAttribute("tlxSelectDisabled", "true");
	} else {
		propertyElement.removeAttribute("tlxSelectDisabled");
	}

	selectElement.disabled = disabled;
}

function tlxSelectGetType(propertyId) {
	var propertyElement = getElement(propertyId);
	return propertyElement.getAttribute("tlxSelectType");
}
function tlxSelectGetAutoFill(propertyId) {
	var propertyElement = getElement(propertyId);
	return propertyElement.getAttribute("tlxSelectAutoFill");
}
function tlxSelectGetDefaultOptions(propertyId) {
	var propertyElement = getElement(propertyId);
	var defaultOptions = propertyElement.getAttribute("tlxSelectDefaultOptions");
	
	if(defaultOptions) {
		return eval(defaultOptions);
	}
	
	return [];	
}
function tlxSelectGetAttributeIntValue(propertyId, attrId, defaultValue) {
	var propertyElement = getElement(propertyId);
	var value = propertyElement.getAttribute(attrId);
	if(value == null) return defaultValue;
	return parseInt(value);
}
function tlxSelectGetAttributeStringValue(propertyId, attrId, defaultValue) {
	var propertyElement = getElement(propertyId);
	var value = propertyElement.getAttribute(attrId);
	if(value == null) return defaultValue;
	return value;
}
function tlxSelectGetAttributeBooleanValue(propertyId, attrId, defaultValue) {
	var propertyElement = getElement(propertyId);
	var value = propertyElement.getAttribute(attrId);
	if(value == null) return defaultValue;
	return value == "true";
}
function tlxSelectGetAttributeElementIntValue(propertyId, attrId, defaultValue) {
	var elementId = tlxSelectGetAttributeStringValue(propertyId, attrId);	
	if(elementId) return getElementInt(elementId, defaultValue);
	return defaultValue;
}

// Display name
function tlxSelectSetElementDisplayName(propertyId, value) {
	value = isString(value) ? value : "" + value;
	var selectElement = tlxSelectGetSelectElement(propertyId);
	var defaultOptions = tlxSelectGetDefaultOptions(propertyId);
	
	if(defaultOptions) {
		for(var row = 0; row < defaultOptions.length; row++) {
			var option = defaultOptions[row];
			var optionValue = isString(option[0]) ? option[0] : "" + option[0];			
	
			if(optionValue == value) {				
				
				if(selectElement) {
					setElementValue(selectElement, encodeHTML(option[1]));
					return;
				}				
			}
		}
	}
	
	var objectId = parseInt(value);
	
	if(objectId > 0) {
		var type = tlxSelectGetType(propertyId);	
		var jsonType = tlxSelectGetJSONType(propertyId);	
		var displayNameProperty = tlxSelectGetDisplayNameProperty(propertyId);
		var object = eval("getTopFrame().jsonrpc." + jsonType + ".get(tlxSelectGet" + type + "MarshallSpec(propertyId), objectId)");
		var displayName = encodeHTML(eval("object." + displayNameProperty));
		setElementValue(selectElement, displayName);
	}
}
function tlxSelectGetJSONType(propertyId) {
	var type = tlxSelectGetType(propertyId);	
	if(type == "Customer") return "Company";
	return type;
}
function tlxSelectGetSelectElementText(propertyId) {
	return tlxSelectGetSelectElement(propertyId).text;
}
// Properties
function tlxSelectGetProperties(propertyId) {
	var type = tlxSelectGetType(propertyId);	
	return eval("tlxSelectProperties" + type + "(propertyId)");
}
function tlxSelectPropertiesAccount(propertyId) {
	return [{prop: "number", align: "left", heading: textNumber, width: "10%"}, {prop: "name", heading: textName}];
}
function tlxSelectPropertiesProduct(propertyId) {
	var array = new Array();

	if(moduleNrf || moduleElectro) {
		if(moduleNrf) array.push({prop: "nrfNumber", align: "left", heading: textNrfNumber, width: "10%"});
		if(moduleElectro) array.push({prop: "elNumber", align: "left", heading: textElNumber, width: "10%"});
	} else {
		array.push({prop: "number", align: "left", heading: textNumber, width: "10%"});
	}

	array.push({prop: "name", heading: textName});

	if(moduleNrf || moduleElectro) {
		array.push({prop: "merchantName", align: "left", heading: textMerchant});
	}

	array.push({prop: "priceCurrencyIsVatOn", heading: textGrossPrice, align: "right", type: "amount", width: "10%"});
	
	if(moduleNrf || moduleElectro) {
		array.push({prop: "guiNetPriceCurrency", heading: textNetPrice, align: "right", type: "amount", width: "10%"});
	}
	
	return array;
}
function tlxSelectPropertiesCustomer(propertyId) {
	var customerType = tlxSelectGetAttributeIntValue(propertyId, "tlxSelectCustomerType", 0);
	
	if(customerType == 1) {
		return [{prop: "customerNameAndNumber", heading: textName}, {prop: "address", maxLength: 50, heading: textAddress}];
	} else if(customerType == 2) {
		return [{prop: "vendorNameAndNumber", heading: textName}, {prop: "address", maxLength: 50, heading: textAddress}];
	}

	return [{prop: "nameAndNumber", heading: textName}, {prop: "address", maxLength: 50, heading: textAddress}];
}
function tlxSelectPropertiesWageCode(propertyId) {
	return [{prop: "nameAndNumber", heading: textName}, {prop: "payStatementCodeCode", heading: textLT, width: "10%"}];
}
function tlxSelectPropertiesProjectControlSchemaType(propertyId) {
	return [{prop: "name", heading: textName}];
}
function tlxSelectPropertiesEmployee(propertyId) {
	var isExternal = tlxSelectGetAttributeIntValue(propertyId, "tlxSelectIsExternal", -1);

	if(isExternal == -1) {
		return [{prop: "nameAndNumber", heading: textName}, {prop: "isExternal", heading: textContact, width: "10%", align: "center"}];
	}
	
	return [{prop: "nameAndNumber", heading: textName}];
}
function tlxSelectPropertiesDepartment(propertyId) {
	return [{prop: "nameAndNumber", heading: textName}];
}
function tlxSelectPropertiesProjectCategory(propertyId) {
	return [{prop: "nameAndNumber", heading: textName}];
}
function tlxSelectPropertiesEmployeeCategory(propertyId) {
	return [{prop: "nameAndNumber", heading: textName}];
}
function tlxSelectPropertiesActivity(propertyId) {
	return [{prop: "nameAndNumber", heading: textName}];
}
function tlxSelectPropertiesProject(propertyId) {
	var array = new Array();
	array.push({prop: "hierarchyNameAndNumber", heading: textProject});
	
	if(modulecustomer) {
		array.push({prop: "customerName", heading: textCustomer, maxLength: "30", align: "left"});
	}	

	array.push({prop: "projectManagerNameAndNumber", heading: textProjectManager, align: "left"});
	return array;
}
function tlxSelectPropertiesMunicipality(propertyId) {
	return [{prop: "nameAndNumber", heading: textName}];
}
function tlxSelectPropertiesCustomerCategory(propertyId) {
	return [{prop: "nameAndNumber", heading: textName}];
}
function tlxSelectGetObjectValueProperty(propertyId) {
	//var type = tlxSelectGetType(propertyId);	
	return "id";	
}
function tlxSelectGetDisplayNameProperty(propertyId) {
	var type = tlxSelectGetType(propertyId);	
	
	if(type == "Project" || type == "Product" || type == "Activity" || type == "Account" || type == "Employee" || type == "Department" || 
			type == "WageCode" || type == "ProjectCategory" || type == "EmployeeCategory" || type == "Municipality" || type == "CustomerCategory") {
		return "nameAndNumber";
	} else if(type == "Customer") {
		var customerType = tlxSelectGetAttributeIntValue(propertyId, "tlxSelectCustomerType", 0);
		
		if(customerType == 1) {
			return "customerNameAndNumber";	
		} else if(customerType == 2) {
			return "vendorNameAndNumber";	
		}
			
		return "nameAndNumber";	
	} else if(type == "ProjectControlSchemaType") {
		return "name";	
	}
	
	return "";	
}

// Search functions
function tlxSelectGetSearchFunction(searchId, propertyId, searchString) {
	var propertyElement = getElement(propertyId);
	var searchFunction = propertyElement.getAttribute("tlxSelectSearchFunction");
	if(searchFunction) return searchFunction;	
	var type = tlxSelectGetType(propertyId);	
	return eval("tlxSelectSearch" + type + "(searchId, propertyId, searchString)");
}
function tlxSelectSearchProduct(searchId, propertyId, searchString) {
	var vendorId = tlxSelectGetAttributeElementIntValue(propertyId, "tlxSelectVendorElementId", -1);
	var projectId = tlxSelectGetAttributeElementIntValue(propertyId, "tlxSelectProjectElementId", -1);
	return getTopFrame().jsonrpc.Product.searchForCompanyAndMerchantProducts(makeSafeCallback(tlxSelectSearchFunctionCallback(searchId, propertyId)), tlxSelectGetProductMarshallSpec(propertyId), loginCompanyId, 1, vendorId, projectId, searchString, tlxSelectMaxRows, 0);
}
function tlxSelectSearchProductMerchant(searchId, propertyId, searchString) {
	var vendorId = tlxSelectGetAttributeElementIntValue(propertyId, "tlxSelectVendorElementId", -1);
	var projectId = tlxSelectGetAttributeElementIntValue(propertyId, "tlxSelectProjectElementId", -1);
	return getTopFrame().jsonrpc.Product.searchForMerchantProducts(makeSafeCallback(tlxSelectSearchFunctionCallback(searchId, propertyId)), tlxSelectGetProductMarshallSpec(propertyId), loginCompanyId, 1, vendorId, projectId, searchString, tlxSelectMaxRows, 0);
}
function tlxSelectSearchAccount(searchId, propertyId, searchString) {
	return getTopFrame().jsonrpc.Account.searchForAccounts(makeSafeCallback(tlxSelectSearchFunctionCallback(searchId, propertyId)), tlxSelectGetAccountMarshallSpec(propertyId), loginCompanyId, searchString, tlxSelectMaxRows, 0);
}        
function tlxSelectSearchAccountIncomingInvoice(searchId, propertyId, searchString) {
	return getTopFrame().jsonrpc.Account.searchForIncomingInvoiceAccounts(makeSafeCallback(tlxSelectSearchFunctionCallback(searchId, propertyId)), tlxSelectGetAccountMarshallSpec(propertyId), loginCompanyId, searchString, tlxSelectMaxRows, 0);
}
function tlxSelectSearchAccountProducts(searchId, propertyId, searchString) {
	return getTopFrame().jsonrpc.Account.searchForProductAccounts(makeSafeCallback(tlxSelectSearchFunctionCallback(searchId, propertyId)), tlxSelectGetAccountMarshallSpec(propertyId), loginCompanyId, true, false, searchString, -1, 0);
}
function tlxSelectSearchAccountStartBalance(searchId, propertyId, searchString) {
	return getTopFrame().jsonrpc.Account.searchForStartBalanceAccounts(makeSafeCallback(tlxSelectSearchFunctionCallback(searchId, propertyId)), tlxSelectGetAccountMarshallSpec(propertyId), loginCompanyId, searchString, tlxSelectMaxRows, 0);
}
function tlxSelectSearchCustomer(searchId, propertyId, searchString) {
	var isActive = tlxSelectGetAttributeIntValue(propertyId, "tlxSelectIsActive", 1);
	var customerType = tlxSelectGetAttributeIntValue(propertyId, "tlxSelectCustomerType", 0);
	var customerCategoryId1 = tlxSelectGetAttributeElementIntValue(propertyId, "tlxSelectCustomerCategoryId1ElementId", -1);
	var customerCategoryId2 = tlxSelectGetAttributeElementIntValue(propertyId, "tlxSelectCustomerCategoryId2ElementId", -1);
	var customerCategoryId3 = tlxSelectGetAttributeElementIntValue(propertyId, "tlxSelectCustomerCategoryId3ElementId", -1);
	return getTopFrame().jsonrpc.Company.searchForCustomersAndVendors(makeSafeCallback(tlxSelectSearchFunctionCallback(searchId, propertyId)), tlxSelectGetCustomerMarshallSpec(propertyId), loginCompanyId, customerType, customerCategoryId1, customerCategoryId2, customerCategoryId3, isActive, searchString, tlxSelectMaxRows, 0);
}
function tlxSelectSearchWageCode(searchId, propertyId, searchString) {
	return getTopFrame().jsonrpc.WageCode.searchForWageCodes(makeSafeCallback(tlxSelectSearchFunctionCallback(searchId, propertyId)), tlxSelectGetWageCodeMarshallSpec(propertyId), loginCompanyId, searchString, tlxSelectMaxRows, 0);
}
function tlxSelectSearchProjectControlSchemaType(searchId, propertyId, searchString) {
	return getTopFrame().jsonrpc.ProjectControlSchemaType.search(makeSafeCallback(tlxSelectSearchFunctionCallback(searchId, propertyId)), tlxSelectGetProjectControlSchemaTypeMarshallSpec(propertyId), 1, -1, -1, searchString, tlxSelectMaxRows, 0);
}
function tlxSelectSearchEmployee(searchId, propertyId, searchString) {
	var employeeCategoryId = tlxSelectGetAttributeElementIntValue(propertyId, "tlxSelectEmployeeCategoryElementId", -1);
	var isActive = tlxSelectGetAttributeIntValue(propertyId, "tlxSelectIsActive", 1);
	var isExternal = tlxSelectGetAttributeIntValue(propertyId, "tlxSelectIsExternal", -1);
	var customerId = tlxSelectGetAttributeElementIntValue(propertyId, "tlxSelectCustomerElementId", -1);
	var departmentId = tlxSelectGetAttributeElementIntValue(propertyId, "tlxSelectDepartmentElementId", -1);
	var dateObject = tlxSelectGetPeriodFormDateObject();
	var ignorePeriodForm = tlxSelectGetAttributeBooleanValue(propertyId, "tlxSelectIgnorePeriodForm", false);
	var startDate = !ignorePeriodForm && dateObject && dateObject.startDate ? dateObject.startDate : null;
	var endDate = !ignorePeriodForm && dateObject && dateObject.endDate ? dateObject.endDate : null;
	return getTopFrame().jsonrpc.Employee.searchForEmployees(makeSafeCallback(tlxSelectSearchFunctionCallback(searchId, propertyId)), tlxSelectGetEmployeeMarshallSpec(propertyId), loginCompanyId, departmentId, customerId, employeeCategoryId, isActive, isExternal, jsonDate(startDate), jsonDate(endDate), searchString, tlxSelectMaxRows, 0);
}
function tlxSelectSearchDepartment(searchId, propertyId, searchString) {
	return getTopFrame().jsonrpc.Department.searchForDepartments(makeSafeCallback(tlxSelectSearchFunctionCallback(searchId, propertyId)), tlxSelectGetDepartmentMarshallSpec(propertyId), loginCompanyId, searchString, tlxSelectMaxRows, 0);
}
function tlxSelectSearchProjectCategory(searchId, propertyId, searchString) {
	return getTopFrame().jsonrpc.ProjectCategory.searchForProjectCategories(makeSafeCallback(tlxSelectSearchFunctionCallback(searchId, propertyId)), tlxSelectGetProjectCategoryMarshallSpec(propertyId), loginCompanyId, searchString, tlxSelectMaxRows, 0);
}
function tlxSelectSearchEmployeeCategory(searchId, propertyId, searchString) {
	return getTopFrame().jsonrpc.EmployeeCategory.searchForEmployeeCategories(makeSafeCallback(tlxSelectSearchFunctionCallback(searchId, propertyId)), tlxSelectGetEmployeeCategoryMarshallSpec(propertyId), loginCompanyId, searchString, tlxSelectMaxRows, 0);
}
function tlxSelectSearchProject(searchId, propertyId, searchString) {
	var projectCategoryId = tlxSelectGetAttributeElementIntValue(propertyId, "tlxSelectProjectCategoryElementId", -1);
	var employeeId = tlxSelectGetAttributeElementIntValue(propertyId, "tlxSelectEmployeeElementId", -1);
	var departmentId = tlxSelectGetAttributeElementIntValue(propertyId, "tlxSelectDepartmentElementId", -1);
	var customerId = tlxSelectGetAttributeElementIntValue(propertyId, "tlxSelectCustomerElementId", -1);
	var projectParticipantId = tlxSelectGetAttributeIntValue(propertyId, "tlxSelectProjectParticipantId", -1);
	var withManagerPrivilegesOnly = tlxSelectGetAttributeBooleanValue(propertyId, "tlxSelectWithManagerPrivilegesOnly", false);
	var isClosed = tlxSelectGetAttributeIntValue(propertyId, "tlxSelectIsClosed", -1);
	var includeAllOpenProjects = tlxSelectGetAttributeBooleanValue(propertyId, "tlxSelectIncludeAllOpenProjects", false);
	var dateObject = tlxSelectGetPeriodFormDateObject();
	var ignorePeriodForm = tlxSelectGetAttributeBooleanValue(propertyId, "tlxSelectIgnorePeriodForm", false);
	var startDate = !ignorePeriodForm && dateObject && dateObject.startDate ? dateObject.startDate : null;
	var endDate = !ignorePeriodForm && dateObject && dateObject.endDate ? dateObject.endDate : null;
	return getTopFrame().jsonrpc.Project.searchForProjects(makeSafeCallback(tlxSelectSearchFunctionCallback(searchId, propertyId)), tlxSelectGetProjectMarshallSpec(propertyId), loginCompanyId, projectCategoryId, employeeId, departmentId, customerId, projectParticipantId, isClosed, withManagerPrivilegesOnly, includeAllOpenProjects, jsonDate(startDate), jsonDate(endDate), searchString);
}
function tlxSelectSearchActivity(searchId, propertyId, searchString) {
	var projectId = tlxSelectGetAttributeElementIntValue(propertyId, "tlxSelectProjectElementId", 0); // 0: Gen. act, -1: All project act.
	var dateObject = tlxSelectGetPeriodFormDateObject();
	var ignorePeriodForm = tlxSelectGetAttributeBooleanValue(propertyId, "tlxSelectIgnorePeriodForm", false);
	var startDate = !ignorePeriodForm && dateObject && dateObject.startDate ? dateObject.startDate : null;
	var endDate = !ignorePeriodForm && dateObject && dateObject.endDate ? dateObject.endDate : null;
	return getTopFrame().jsonrpc.Activity.searchForActivities(makeSafeCallback(tlxSelectSearchFunctionCallback(searchId, propertyId)), tlxSelectGetActivityMarshallSpec(propertyId), loginCompanyId, projectId, true, jsonDate(startDate), jsonDate(endDate), searchString);	
}
function tlxSelectSearchMunicipality(searchId, propertyId, searchString) {
	return getTopFrame().jsonrpc.Municipality.searchForMunicipalities(makeSafeCallback(tlxSelectSearchFunctionCallback(searchId, propertyId)), tlxSelectGetMunicipalityMarshallSpec(propertyId), searchString);
}
function tlxSelectSearchCustomerCategory(searchId, propertyId, searchString) {
	var categoryType = tlxSelectGetAttributeIntValue(propertyId, "tlxSelectArg0", -1);
	return getTopFrame().jsonrpc.CustomerCategory.searchForCustomerCategories(makeSafeCallback(tlxSelectSearchFunctionCallback(searchId, propertyId)), tlxSelectGetCustomerCategoryMarshallSpec(propertyId), loginCompanyId, categoryType, searchString);
}

// Marshall specs
function tlxSelectGetProductMarshallSpec(propertyId) {
	return getTopFrame().marshallSpec("id", "number", "nrfNumber", "elNumber", "name", "nameAndNumber", "merchantName", "priceCurrencyIsVatOn", "guiNetPriceCurrency");
}
function tlxSelectGetAccountMarshallSpec(propertyId) {
	return getTopFrame().marshallSpec("id", "number", "name", "nameAndNumber");
}
function tlxSelectGetCustomerMarshallSpec(propertyId) {
	var customerType = tlxSelectGetAttributeIntValue(propertyId, "tlxSelectCustomerType", 0);
	
	if(customerType == 1) {
		return getTopFrame().marshallSpec("id", "customerAccountNumber", "name", "customerNameAndNumber", "address", "customerCategoryId1", "customerCategoryId2", "customerCategoryId3");
	} else if(customerType == 2) {
		return getTopFrame().marshallSpec("id", "vendorAccountNumber", "name", "vendorNameAndNumber", "address", "customerCategoryId1", "customerCategoryId2", "customerCategoryId3");
	}

	return getTopFrame().marshallSpec("id", "customerAccountNumber", "vendorAccountNumber", "name", "nameAndNumber", "address", "customerCategoryId1", "customerCategoryId2", "customerCategoryId3");
}
function tlxSelectGetWageCodeMarshallSpec(propertyId) {
	return getTopFrame().marshallSpec("id", "number", "name", "nameAndNumber", "payStatementCodeCode");
}
function tlxSelectGetProjectControlSchemaTypeMarshallSpec(propertyId) {
	return getTopFrame().marshallSpec("id", "name");
}
function tlxSelectGetEmployeeMarshallSpec(propertyId) {
	var isExternal = tlxSelectGetAttributeIntValue(propertyId, "tlxSelectIsExternal", -1);

	if(isExternal == -1) {
		return getTopFrame().marshallSpec("id", "number", "fullName", "nameAndNumber", "isExternal", "departmentId");
	}

	return getTopFrame().marshallSpec("id", "number", "fullName", "nameAndNumber", "departmentId");
}
function tlxSelectGetDepartmentMarshallSpec(propertyId) {
	return getTopFrame().marshallSpec("id", "number", "name", "nameAndNumber");
}
function tlxSelectGetProjectCategoryMarshallSpec(propertyId) {
	return getTopFrame().marshallSpec("id", "number", "name", "nameAndNumber");
}
function tlxSelectGetEmployeeCategoryMarshallSpec(propertyId) {
	return getTopFrame().marshallSpec("id", "number", "name", "nameAndNumber");
}
function tlxSelectGetProjectMarshallSpec(propertyId) {
	return getTopFrame().marshallSpec("id", "number", "fullName", "nameAndNumber", "hierarchyNameAndNumber", "projectManagerNameAndNumber", "departmentId", "projectCategoryId", "customerName");
}
function tlxSelectGetActivityMarshallSpec(propertyId) {
	return getTopFrame().marshallSpec("id", "number", "name", "nameAndNumber");
}
function tlxSelectGetMunicipalityMarshallSpec(propertyId) {
	return getTopFrame().marshallSpec("id", "number", "name", "nameAndNumber");
}
function tlxSelectGetCustomerCategoryMarshallSpec(propertyId) {
	return getTopFrame().marshallSpec("id", "number", "name", "nameAndNumber");
}

function tlxSelectGetPeriodFormDateObject() {
	var dateObject = null;	
	var period = getElementInt("period", -1);
	var year = getElement("year");		
	var month = getElement("month");
	var week = getElement("week");
	var vatTerm = getElement("vatTerm");

	if(period == 0 || (period == -1 && month)) {
		if(getSelectedValue(year) == "-1") return null;

		if(getSelectedValue(month) != "-1") {
			var obj = getSelectedObject(month);
			if(obj && obj.startDate && obj.endDate) return {"startDate" : new Date(obj.startDate.time), "endDate": new Date(obj.endDate.time)};
			return null;
		}

		var obj = getSelectedObject(year);
		if(obj && obj.startDate && obj.endDate) return {"startDate" : new Date(obj.startDate.time), "endDate": new Date(obj.endDate.time)};
		return null;
	} else if(period == 1 || (period == -1 && week)) {
		if(getSelectedValue(year) == "-1") return null;		

		if(getSelectedValue(week) != "-1") {
			var obj = getSelectedObject(week);
			if(obj && obj.startDate && obj.endDate) return {"startDate" : new Date(obj.startDate.time), "endDate": new Date(obj.endDate.time)};
			return null;
		}

		var obj = getSelectedObject(year);
		if(obj && obj.startDate && obj.endDate) return {"startDate" : new Date(obj.startDate.time), "endDate": new Date(obj.endDate.time)};
		return null;
	} else if(period == 2 || (period == -1 && getElement("periodStartDate") != null)) {
		var d1 = getElementDate("periodStartDate");
		var d2 = getElementDate("lastDayInPeriod");
		return {"startDate" : d1, "endDate": addDay(d2)};		
	} else if(period == 3 || (period == -1 && vatTerm)) {
		var obj = getSelectedObject(vatTerm);
		if(obj && obj.startDate && obj.endDate) return {"startDate" : new Date(obj.startDate.time), "endDate": new Date(obj.endDate.time)};
		return null;
	}
	
	return null;
}
