var vdh = new Object();
vdh.ie = false;

/*
Browser Compatible method for attaching events to objects
eg: addEvent(document.getElementById('some_form_button'), 'mousedown', submitForm);
*/
vdh.addEvent = function (obj, type, func) {
	if (obj.addEventListener) {
		obj.addEventListener(type, func, false);
	} else if (obj.attachEvent) {
		obj.attachEvent("on" + type, func);
	}
}

vdh.removeEvent = function (obj, type, func) {
	if (obj.removeEventListener) {
		obj.removeEventListener(type, func, false);
	} else if (obj.detachEvent) {
		obj.detachEvent("on" + type, func);
	}
}

/*
Browser Compatible method for getting the DOM Object that triggered the event
eg:
	function someFunction(e) {
		buttonClicked = getEventCaller(e);
	}
	someFunction();
*/
vdh.getEventCaller = function (e) {
	if (window.addEventListener) {
		return document.getElementById(e.target.id);
	} else {
		return document.getElementById(window.event.srcElement.id);
	}
}

vdh.getObject = function(ele) {
	var obj;
	if (typeof(ele) == "object") {
		obj = ele;
	} else if (typeof(ele) == "string") {
		obj = document.getElementById(ele);
	} else {
		return false;	
	}
	if (typeof(obj) != "object" || obj == null) { return false; }
	if (typeof(obj) == "object") { return obj; }
	return false;
}

vdh.findParentTag = function (ele, tagName) {

	var obj = new Object();
	if (typeof(ele) == "string") {
		obj = document.getElementById(ele);
	} else if (typeof(ele) == "object") {
		obj = ele;
	} else {
		return null;
	}

	var parentTag = obj.parentNode;

	if (typeof(tagName) != "string") {
		return parentTag;
	}

	while (parentTag.tagName != tagName.toUpperCase()) {
		if (parentTag.tagName == "BODY") {
			return parentTag;
		}
		parentTag = parentTag.parentNode;
	}
	return parentTag;

}

vdh.stopBubbling = function (e) {
	if (!e) var e = window.event;
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
}


/* Creates a guid, with optional delimiter */
vdh.guid = function(delimiterString) {

	this.randomHex = function() {
		return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
	}

	if (typeof(delimiterString) == "string") {
		this.delimiter = delimiterString;
	} else {
		this.delimiter = "";
	}
	return (
		this.randomHex() + this.randomHex()
		+ this.delimiter + this.randomHex()
		+ this.delimiter + this.randomHex()
		+ this.delimiter + this.randomHex()
		+ this.delimiter + this.randomHex()
		+ this.randomHex() + this.randomHex()
	).toUpperCase();
}


vdh.random = function() {
	var timeStamp = new Date();
	return parseInt(timeStamp.getTime() * Math.random());
}
/* toggle element visibility - NB! different to toggling display */
vdh.toggleVisibility = function (ele) {
	var domObj;
	if (typeof(ele) == 'string') {
		domObj = document.getElementById(ele);
	} else if (typeof(ele) == 'object') {
		domObj = ele;
	} else { return false; }
	domObj.style.visibility = (domObj.style.visibility == "hidden") ? "visible" : "hidden";
}

vdh.toggleDisplay = function (ele) {
	var domObj;
	if (typeof(ele) == 'string') {
		domObj = document.getElementById(ele);
	} else if (typeof(ele) == 'object') {
		domObj = ele;
	} else { return false; }
	domObj.style.display = (domObj.style.display == "none") ? "" : "none";
}


/* Formats a number to a given precision and prepends with a given symbol */
vdh.formatCurrency = function (amount, decimalPlaces, symbol) {
    floatAmount = parseFloat(amount);
    if (isNaN(floatAmount)) { floatAmount = 0; }
    if (typeof(symbol) == "string") {
   		return symbol + floatAmount.toFixed(decimalPlaces);
    } else {
    	return floatAmount.toFixed(decimalPlaces);
    }
}

/* Get the currently selected text in a form */
vdh.getSelectedText = function() {
    var txt = "";
    if (window.getSelection) {
		txt = window.getSelection();
    } else if (document.getSelection) {
		txt = document.getSelection();
    } else if (document.selection) {
		txt = document.selection.createRange().text;
    }
    return txt;
}

/* Get the value of request param by parsing the url querystring */
vdh.getURLParamValue = function (param) {
	var paramValue = "";
	var url = document.location.href.split("?")[1];
	var queryString = url.split("&");
	for (i = 0; i < queryString.length; i++) {
		temp = queryString[i].split("=");
		if (temp[0] == param) {
			paramValue = temp[1];
			break;
		}
	}
	return paramValue;
}

vdh.emptyDom = function() {
	return '';
}

vdh.xslTransform = function (xmlDom, styleSheet, callBack) {
	var req;
	if (vdh.ie == true) {
        req = new ActiveXObject("Microsoft.XMLHTTP");
	} else {
        req = new XMLHttpRequest();
    }
    var dom = new Object();
	req.onreadystatechange = function () {
		if (req.readyState == 4) {
			if(req.status == 200) {
				if (vdh.ie) {
					var xslDom = new ActiveXObject("MSXML2.DOMDocument");
					xslDom.loadXML(req.responseText);
					dom = xmlDom.transformNode(xslDom);
				} else {
					xslDom = req.responseXML;
					var processor = new XSLTProcessor();
					processor.importStylesheet(xslDom);
					dom = processor.transformToFragment(xmlDom, document);
				}
				if (typeof(callBack) == "function") {
					callBack(xmlDom, styleSheet, dom);
				}
			} else {
  				alert("There was a problem retrieving the response:\n" + styleSheet + '\n' + req.status + ": " + req.statusText);
			}
		}
	};
    req.open("GET", styleSheet, true);
	req.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
    req.send("");
}

vdh.httpRequest = function (url, postData, callBack) {
    var req;
	if (vdh.ie == true) {
        req = new ActiveXObject("Microsoft.XMLHTTP");
    } else {
        req = new XMLHttpRequest();
    }
	req.onreadystatechange = function() {
		if (req.readyState == 4) {
			var response = "";
			if(req.status == 200) {
				if (vdh.ie) {
					if (req.responseText != null) {
						response = req.responseText;
					} else {
						response = "Unrecognised response: " + req;
					}					
				} else {
					if (req.responseXML != null) {
						response = req.responseXML;
					} else if (req.responseText != null) {
						response = req.responseText;
					} else {
						response = "Unrecognised response: " + req;
					}
				}
			} else {
  				response = "There was a problem retrieving the response from:\n" + url + '\n' + req.statusText;
			}
			if (typeof(callBack) == "string") {
				if (typeof(eval("window." + callBack)) == "function") {
					eval(callBack + "(url, postData, response)");
				} else if (typeof(response) == "string") {
					alert(response);
				}
			} else if (typeof(callBack) == "function"){
				callBack(url, postData, response);
			} else {
				alert(response);
			}
		} else if (req.readyState == 2) {
			//TODO: Add streaming support;
//			document.body.innerHTML += req.responseText;
		}
	};

    req.open("POST", url, true);
	req.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
    req.send(postData);

}

/* Creates an empty XML Document. Used for loading XSLT without doing any transformation */
vdh.createXMLDoc = function (xmlData) {

	var doc;
	if (typeof(xmlData) == "string") {
		var xmlString = xmlData;
		xmlString = xmlString.replace(/&/gi, "&amp;");

	    if (document.implementation.createDocument) {
	        var parser = new DOMParser();
	        doc = parser.parseFromString(xmlString, "text/xml");
	    } else if (window.ActiveXObject) {
	        doc = new ActiveXObject("Microsoft.XMLDOM");
	        doc.async="false";
	        doc.loadXML(xmlString);
	    }
	} else if (typeof(xmlData) == "object"){
		/* Parse array to xml String*/
	} else {
		if (document.implementation && document.implementation.createDocument) {
		    doc = document.implementation.createDocument("", "", null);
		} else {
			doc = new ActiveXObject("MSXML2.DOMDocument");
		}
	}
	return doc;
}


vdh.submit = function (submittedForm, customCallBack) {
	var url = submittedForm.action;
	var postData = "form=" + submittedForm.name;
	var submission = document.forms[submittedForm.name];



	var files = 0;
	
	var loading = document.createElement("DIV");
	var loadingGuid = vdh.guid();
	loading.id = "loading" + loadingGuid;
	loading.className = "loading";

	var loadingPos = false;
		
	
	function cleanUp(url, postData, response) {
		document.getElementById("loading" + loadingGuid).parentNode.removeChild(document.getElementById("loading" + loadingGuid));
		for (var i = 0; i < submission.length; i++) {
			submission[i].disabled = false;
		}
		if (typeof(customCallBack) == "string") {
			if (typeof(eval("window." + customCallBack)) == "function") {
				eval(customCallBack + "(submittedForm, response)");
			}
		}
	}
	
	for (var i = submission.length-1; i >= 0; i--) {
		if (submission[i].tagName == "INPUT") {
			if (submission[i].type == "submit") {
				submission[i].parentNode.insertBefore(loading, submission[i].nextSibling);
				loadingPos = true;
				break;
			}
		}
	}
		
	if (!loadingPos) {
		submission.appendChild(loading);
	}
	for (var i = 0; i < submission.length; i++) {
		if (submission[i].tagName == "INPUT") {
			if (submission[i].type.toUpperCase() == "RADIO") {
				if (submission[i].checked) {
					if (postData.length > 0) { postData += "&"; }
					postData += submission[i].name + "=";
					postData += escape(submission[i].value);
				}
			} else if (submission[i].type.toUpperCase() == "CHECKBOX") {
				if (submission[i].checked) {
					if (postData.length > 0) { postData += "&"; }
					postData += submission[i].name + "=";
					postData += escape(submission[i].value);
				}
			} else if (submission[i].type.toUpperCase() == "FILE") {
				
				if (submission[i].value != "") {
					files++;
					
					if (postData.length > 0) { postData += "&"; }
					postData += submission[i].name + "=";
					postData += escape(submission[i].value);

					var guid = vdh.guid();
		
					var fileHolder				= document.createElement("DIV");
					fileHolder.id				= "fileHolder" + guid;
					fileHolder.style.display	= "none";	
	
					var fileFrame				= document.createElement("IFRAME");
					fileFrame.name				= "fileFrame" + guid;
					fileFrame.id				= "fileFrame" + guid;
					
					var fileForm				= document.createElement("FORM");
					fileForm.name				= "fileForm" + guid;
					fileForm.action				= submittedForm.action;
					fileForm.target				= "fileFrame" + guid;
					fileForm.method				= "post";
					fileForm.enctype			= "multipart/form-data";
					
					var fileField				= document.createElement("INPUT");
					fileField.name				= "file" + guid;
					fileField.value				= escape(submission[i].value);
					
					fileForm.appendChild(fileField);
					fileHolder.appendChild(fileFrame);
					fileHolder.appendChild(fileForm);
		
					var fileUploadId = vdh.random();
		
					vdh.vars[fileUploadId] = new Object();
		
					vdh.vars[fileUploadId].checkStatus = function() {
						if (window.frames["fileFrame" + this.guid].document.body.hasChildNodes()) {
							document.body.removeChild(document.getElementById("fileHolder" + this.guid));
							files--;
							if (files == 0) { request(); }
							clearInterval(this.intervalId);	
							//delete vdh.vars[fileUploadId];
						}
					}
		
					vdh.vars[fileUploadId].guid = guid;
					vdh.vars[fileUploadId].fileHolder = fileHolder;
					vdh.vars[fileUploadId].fileFrame = fileFrame;			
		
					document.body.appendChild(vdh.vars[fileUploadId].fileHolder);
					
					document.forms["fileForm" + guid].submit();
		
					vdh.vars[fileUploadId].intervalId = setInterval("vdh.vars[" + fileUploadId + "].checkStatus()", 50);
				}			
			} else {
				if (postData.length > 0) { postData += "&"; }
				postData += submission[i].name + "=";
				postData += escape(submission[i].value);
			}

		} else if (submission[i].tagName == "TEXTAREA") {
			if (postData.length > 0) { postData += "&"; }
			postData += submission[i].name + "=";
			postData += escape(submission[i].value);
		} else if (submission[i].tagName == "SELECT") {
			for (var j = 0; j < submission[i].options.length; j++) {
				if (submission[i].options[j].selected) {
					if (postData.length > 0) { postData += "&"; }
					postData += submission[i].name + "=";
					postData += escape(submission[i].options[j].value);
				}
			}
		}
		submission[i].disabled = true;
	}

	function request() {
		vdh.httpRequest(url, postData, cleanUp);	
	}
		
	if (files == 0) {
		request();	
	}

	return false;
}

vdh.createDomFragment = function (dom) {

	if (typeof(dom) == "string") {

		var tmpDiv = document.createElement("DIV");
		tmpDiv.id = "appendedNode" + vdh.guid();
		tmpDiv.innerHTML = dom;
		if (vdh.ie) {
			var myDom = document.createElement("DIV");
			myDom.appendChild(tmpDiv);
			
			return myDom;
		} else {			
			var myDom = document.createDocumentFragment();
			myDom.appendChild(tmpDiv);
			return myDom;
		}
	} else if (typeof(dom) == "object") {
		return dom;
	} else {
		return false;
	}
}

vdh.appendNode = function (parentNode, dom, mode) {
	var domObj = vdh.getObject(parentNode);
	if (domObj === false) { return false; }
	
	var myDom = vdh.createDomFragment(dom);
	if (typeof(myDom) != "object") { return false; }

	switch (mode) {
		case -1: // Prepend to existing contents
			domObj.insertBefore(myDom, domObj.firstChild);
		break;
		case 1: // Append to existing contents
			domObj.appendChild(myDom);
		break;
		case 2: // Replace node
			domObj.parentNode.replaceChild(myDom, domObj);
		break;
		default: // Replace node contents
			if (vdh.ie) {
				domObj.innerHTML = myDom.outerHTML;
			} else {
				domObj.innerHTML = "";
				domObj.appendChild(myDom);	
			}
		break;
	}
}

/* Pseudo sleep function */
vdh.sleep = function (sleepTime) {
	var sleeping = true;
	var now = new Date();
	var alarm;
	var startingMSeconds = now.getTime();
	
	while(sleeping){
	   alarm = new Date();
	   alarmMSeconds = alarm.getTime();
	   if(alarmMSeconds - startingMSeconds > sleepTime){ sleeping = false; }
	}
}

vdh.clickableRows = {
	rows: new Array(),
	aTags: new Array(),
	initialise: function() {
		vdh.clickableRows.aTags = document.getElementsByTagName("A");
		var aTags = vdh.clickableRows.aTags;
		for (var i = 0; i < aTags.length; i++) {
			if (aTags[i].className.indexOf("rowClickable") >= 0) {
			var clickableRow = vdh.findParentTag(aTags[i], "TR");

				clickableRow.onmouseover = function() {

					 this.className = "vdhClickableRow";
				}
	
				clickableRow.onmouseout = function() {
					this.className = vdh.clickableRows.findOriginalClass(this);
				}
				clickableRow.onclick = function() {
					var alink = vdh.clickableRows.findAction(this);
					if (alink !== false) {
						if (alink.indexOf("javascript:") >= 0) {
							var jsAction = alink.replace("javascript:", "");
							eval(jsAction);
						} else {
							document.location.href = alink;
						}
					}
				}
				vdh.clickableRows.rows[vdh.clickableRows.rows.length] = {
					row: clickableRow, 
					alink: aTags[i].href,
					originalClass: clickableRow.className
				};				
			}
		}
		var inputBoxes = document.getElementsByTagName("INPUT");
		for (i = 0; i < inputBoxes.length; i++) {
			if (inputBoxes[i].type == "checkbox") {
				var inputTd = vdh.findParentTag(inputBoxes[i], "TD");
				if (inputTd !== false) {
					inputTd.onclick = vdh.stopBubbling;
				}
				inputBoxes[i].onclick = vdh.stopBubbling;
			}
		}
		var selectBoxes = document.getElementsByTagName("SELECT");
		for (i = 0; i < selectBoxes.length; i++) {
			selectBoxes[i].onclick = vdh.stopBubbling;
		}
		var aTags = document.getElementsByTagName("A");
		for (i = 0; i < aTags.length; i++) {
			aTags[i].onclick = vdh.stopBubbling;
		}

	},

	findOriginalClass: function(ele) {
		for (var i = 0; i < vdh.clickableRows.rows.length; i++) {
			if (vdh.clickableRows.rows[i].row === ele) {			
				return vdh.clickableRows.rows[i].originalClass;
			}
		}
		return "";
	},
	
	findAction: function(ele) {	
		for (var i = 0; i < vdh.clickableRows.rows.length; i++) {
			if (vdh.clickableRows.rows[i].row === ele) {
				return vdh.clickableRows.rows[i].alink;
			}
		}
		return false;
	}
}

vdh.fade = function (ele, interval, direction, customCallBack) {

	this.cleanUp = function() {
		clearInterval(this.intervalId);
		delete this.obj.fading;				
		delete vdh.domNodes[this.domNodeId];
	}

	this.callBack = function () {
		this.cleanUp();	
	}
	
	this.interval = 50;
	if (!isNaN(interval)) {
		if (interval > this.interval) {
			this.interval = interval;
		}
	}; 
	
	this.fadeOutNode = function() {
		if (vdh.ie) {
			var filterValue  = parseInt(this.obj.style.filter.replace('alpha (', '').replace(')', ''));
			if (filterValue >= 40) {
				filterValue -= 5;
				this.obj.style.filter = 'alpha (' +  filterValue + ')';
			} else {
				this.obj.style.filter = 'alpha (0)';			
				this.obj.parentNode.style.backgroundColor = this.parentBgColor;						
				this.callBack();
			}
		} else {
			if (this.obj.style.opacity >= 40) {
				this.obj.style.opacity = parseFloat(this.obj.style.opacity) - 0.05;
			} else {
				this.obj.style.opacity = 0;			
				this.obj.parentNode.style.backgroundColor = this.parentBgColor;						
				this.callBack();
			}
		}		
	}	

	this.fadeInNode = function() {
		if (vdh.ie) {
			var filterValue  = parseInt(this.obj.style.filter.replace('alpha (', '').replace(')', ''));
			if (filterValue < 100) {
				filterValue += 5;
				this.obj.style.filter = 'alpha (' +  filterValue + ')';
			} else {
				this.obj.parentNode.style.backgroundColor = this.parentBgColor;						
				this.callBack();
			}
		} else {
			if (this.obj.style.opacity < 1) {
				this.obj.style.opacity = parseFloat(this.obj.style.opacity) + 0.05;
			} else {
				this.obj.parentNode.style.backgroundColor = this.parentBgColor;						
				this.callBack();
			}
		}		
	}	

	
	this.obj = vdh.getObject(ele);
	if (this.obj === false) { return false; }
	if (typeof(this.obj.fading) != "undefined") { return false; }	
	
	if (typeof(customCallBack) == "function") {
		this.callBack = customCallBack;	
	}

	this.intervalId = 0;
	this.domNodeId = "";
	this.parentBgColor = "";
	
		if (this.obj.style.display != "none") {
			this.obj.fading = true;
			this.domNodeId = vdh.random();
			vdh.domNodes[this.domNodeId] = this;
			this.parentBgColor = this.obj.parentNode.style.backgroundColor; 				
			this.obj.parentNode.style.backgroundColor = '#ffffff';
			
			if (typeof(direction) == "string") {
				if (vdh.ie) {
					this.obj.style.filter = 'alpha (0)';
				} else {
					this.obj.style.opacity = 0;
				}
				this.intervalId = setInterval('vdh.domNodes['+ this.domNodeId + '].fadeInNode()', this.interval);
			} else {
				if (vdh.ie) {
					this.obj.style.filter = 'alpha (100)';
				} else {
					this.obj.style.opacity = 1;
				}
				this.intervalId = setInterval('vdh.domNodes['+ this.domNodeId + '].fadeOutNode()', this.interval);
			}
		}
}

vdh.fadeAway = function(ele) {

	this.callBack = function () {
		vdh.toggleDisplay(this.obj);
		if (vdh.ie) {
			this.obj.style.filter = 'alpha (100)';
			this.obj.parentNode.style.backgroundColor = this.parentBgColor;
		} else {
			this.obj.style.opacity = 1;
			this.obj.parentNode.style.backgroundColor = this.parentBgColor;
		}
		this.cleanUp();
	}
	vdh.fade(ele, false, false, this.callBack);
}

vdh.removeFromDom = function(ele) {

	this.callBack = function () {
		if (typeof(this.obj) == "object") {
			this.obj.parentNode.removeChild(this.obj);
			this.cleanUp();
		}	
	}
	vdh.fade(ele, false, false, this.callBack);
}

vdh.message = function (messageInfo, messageDuration) {
	
	this.guid = vdh.guid();
	this.duration = 0;
	
	this.message = messageInfo;
	this.obj = document.createElement("DIV");
	if (!isNaN(messageDuration)) { this.duration = messageDuration; }

	this.create = function()  {
		this.obj.id = "vdhMessage" + this.guid;
		this.obj.zIndex = 50000;
		this.obj.className = "vdhMessage";
		this.obj.onclick = this.destroy;
		this.obj.innerHTML = this.message;
		document.body.appendChild(this.obj);	
		if (!isNaN(this.duration)) {
			if (this.duration > 0) {
				setTimeout("vdh.removeFromDom('" + this.obj.id + "')", this.duration);
			}
		}
	}
	
	this.destroy = function (e) {
		vdh.removeFromDom(vdh.getEventCaller(e));
	}
	this.create();
}


vdh.widget = function() {
	this.widgetId		= vdh.random();
	this.widgetTitle	= "";
	this.widgetContent	= "";
	this.widgetClass	= "";
	this.parentNode		= document.body;
	this.widgetDiv		= new Object();
	this.create = function() {

		this.widgetDiv = document.createElement("DIV");
		this.widgetDiv.id = "widget" + this.widgetId;
		this.widgetDiv.className = this.widgetClass;
		if (vdh.ie) {
			this.widgetDiv.style.filter = "alpha (0)";
		} else {
			this.widgetDiv.style.opacity = 0;
		}
		var widgetTitle = document.createElement("H1");
		widgetTitle.id = "widgetTitle" + this.widgetId;
		widgetTitle.appendChild(document.createTextNode(this.widgetTitle));
		this.widgetDiv.appendChild(widgetTitle);

		var widgetContent = document.createElement("DIV");
		widgetContent.id = "widgetContent" + this.widgetId;
		this.widgetDiv.appendChild(widgetContent);
		vdh.appendNode(widgetContent, this.widgetContent, 0);
				


		var parentNode = vdh.getObject(this.parentNode);
		parentNode.appendChild(this.widgetDiv);
		vdh.fade("widget" + this.widgetId, false, "in");
	}
	
	this.updateContent = function(content) {
		this.widgetContent = content;
		vdh.appendNode("widgetContent" + this.widgetId, this.widgetContent, 0);		
	}	
};

vdh.autoCompleteTextBox = function () {
	this.timeOut		= -1; // Autocomplete Timeout in ms (-1: autocomplete never time out)
	this.limit			= -1;    // Number of elements autocomplete can show (-1: no limit)
	this.firstText		= false; // should the auto complete be limited to the beginning of keyword?
	this.classNormal	= "autoComplete";
	this.classHighlight	= "autoCompleteHighlight";
	this.classTable		= "autoCompleteTable";
	this.classText		= "autoCompleteText";
	this.classDisabled	= "autoCompleteDisabled";
	this.classDiv 		= "autoCompleteDiv";

	this.lookUp;
	this.keywords		= new Array();
	this.display		= false;
	this.position		= 0;
	this.total			= 0;
	this.current		= null;
	this.siblingObj		= null;
	this.siblingId		= 0;		
	this.rangeUp		= 0;
	this.rangeDown		= 0;
	this.bool			= new Array();
	this.previous		= 0;
	this.timeOutId;
	this.create			= false;
	this.currentKey		=	"";

	
	this.initialise = function(inputBox, inputBoxDesc, siblingObj, siblingId, evt, arr) {
		this.lookUp = inputBoxDesc;
		this.siblingObj = vdh.getObject(siblingObj);
		this.siblingId = siblingId;
		vdh.addEvent(inputBox, "blur", vdh.autoComplete.removeDisplay);
		if (this.display) {
			return this.checkKey(inputBox, evt, arr);
		} else {
			this.complete(inputBox,evt,arr);
		}
	}

	this.mouseClick = function(e){
		obj = vdh.getEventCaller(e);
		vdh.autoComplete.position = obj.id.replace("tat_td", "");
		vdh.autoComplete.enterPressed();
	}
	
	this.parse = function(n){
		var searchString = this.current.value;
		if (this.currentKey === false) {
			searchString = searchString.substr(0, searchString.length-1);
		} else {
			searchString += this.currentKey;
		}
		
		if (this.firstText) {
			var re = new RegExp("^" + searchString, "i");
		} else {
			var re = new RegExp(searchString, "i");
		}
		
		var position = n.search(re);
		str = n.substr(0, position);
		str += "<strong>";
		str += n.substr(position, searchString.length);
		str += "</strong>";
		str += n.substr(position + searchString.length, n.length - position - searchString.length);

		return str;
	}
	
	this.generate = function() {
	    if (document.getElementById("tat_div")) document.body.removeChild(document.getElementById("tat_div"));
		autoDiv = document.createElement("DIV");
		autoDiv.id = "tat_div";
		autoDiv.className = this.classDiv;
	    autoDiv.style.top = eval(this.currentTop() + this.current.offsetHeight + 2) + "px";
	    autoDiv.style.left = this.currentLeft() + "px";
		

	    a = document.createElement("TABLE");
		a.className = this.classTable;
	
	    a.id = "tat_table";
		autoDiv.appendChild(a);
	    document.body.appendChild(autoDiv);
	    var i;
	    var first = true;
	    var j = 1;
	
	    var counter = 0;
	    for (i=0; i<this.keywords.length; i++){
	        if (this.bool[i]){
	            counter++;
	            r = a.insertRow(-1);
           		vdh.addEvent(r, "mousedown", vdh.autoComplete.mouseClick);
	            if (first && !this.create){
	                r.className = this.classHighlight;
	                first = false;
	                this.position = counter;
	            }else if(this.previous == i){
	                r.className = this.classHighlight;
	                first = false;
	                this.position = counter;
	            }else{
	                r.className = this.classNormal;
	            }
	            r.id = "tat_tr"+(j);
	            c = r.insertCell(-1);
	            if (typeof(this.keywords[i]["disabled"]) == "string") {
					c.className = this.classDisabled;
	            } else {
	            	c.className = this.classText;	            
	            }

	            c.innerHTML = this.parse(this.keywords[i][this.lookUp]);
	            c.id = "tat_td"+(j);
	            j++;
	        }
	        if (j - 1 == this.limit && j < this.total){
	            r = a.insertRow(-1);
           		vdh.addEvent(r, "mousedown", vdh.autoComplete.mouseClick);
	            r.className = this.classNormal;
	            c = r.insertCell(-1);
	            c.className = this.classText;
	            c.align="center";
	            c.innerHTML = "\\/";
	            break;
	        }
	    }
	    this.rangeUp = 1;
	    this.rangeDown = j-1;
	    this.display = true;
	    if (this.position <= 0) { this.position = 1; }
	}
	
	this.currentTop = function() {
	    var toReturn = 0;
	    var obj = this.current;
	    while(obj){
	        toReturn += obj.offsetTop;
	        obj = obj.offsetParent;
	    }
	    return toReturn;
	}

	this.currentLeft = function() {
	    var toReturn = 0;
	    var obj = this.current;
	    while(obj){
	        toReturn += obj.offsetLeft;
	        obj = obj.offsetParent;
	    }
	    return toReturn;
	}
	

	this.remake = function(){
	    document.body.removeChild(document.getElementById("tat_div"));
		autoDiv = document.createElement("DIV");
		autoDiv.id = "tat_div";
		autoDiv.className = this.classDiv;
	    autoDiv.style.top = eval(this.currentTop() + this.current.offsetHeight) + "px";
	    autoDiv.style.left = this.currentLeft() + "px";

	    a = document.createElement("TABLE");
		a.className = this.classTable;
	    a.id = "tat_table";
		autoDiv.appendChild(a);
		
	    document.body.appendChild(autoDiv);
	    var i;
	    var first = true;
	    var j = 1;
	    if (this.rangeUp > 1){
	        r = a.insertRow(-1);
          	vdh.addEvent(r, "mousedown", vdh.autoComplete.mouseClick);
	        r.className = this.classNormal;
	        c = r.insertCell(-1);
			c.className = this.classNormal;
	        c.align='center';
	        c.innerHTML = '/\\';
	    }
	    for (i=0;i<this.keywords.length;i++){
	        if (this.bool[i]){
	            if (j >= this.rangeUp && j <= this.rangeDown){
	                r = a.insertRow(-1);
	                r.className = this.classNormal;
	                r.id = "tat_tr"+(j);
	                c = r.insertCell(-1);
		            if (typeof(this.keywords[i]["disabled"]) == "string") {
						c.className = this.classDisabled;
		            } else {
		            	c.className = this.classText;	            
		            }

	                c.innerHTML = this.parse(this.keywords[i][this.lookUp]);
	                c.id = "tat_td"+(j);
	                j++;
	            }else{
	                j++;
	            }
	        }
	        if (j > this.rangeDown) break;
	    }
	    if (j-1 < this.total){
	        r = a.insertRow(-1);
           	vdh.addEvent(r, "mousedown", vdh.autoComplete.mouseClick);	        
			r.className = this.classNormal;
	        c = r.insertCell(-1);
			c.className = this.classNormal;
	        c.align='center';
	        c.innerHTML = '\\/';
	    }
	}
	
	this.goUp = function() {
	    if (!this.display) return;
	    if (this.position == 1) return;
	    document.getElementById('tat_tr'+this.position).className = this.classNormal;
	    this.position--;
	    if (this.position < this.rangeUp) this.moveUp();
	    document.getElementById('tat_tr'+this.position).className = this.classHighlight;
	    if (this.timeOutId) { clearTimeout(this.timeOutId); }
	    if (this.timeOut > 0) { this.timeOutId = setTimeout("vdh.autoComplete.removeDisplay()",this.timeOut); }
	}
	
	this.goDown = function() {
	    //if (!actb_display) return;
	    if (this.position == this.total) return;
	    document.getElementById("tat_tr"+this.position).className = this.classNormal;
	    this.position++;
	    if (this.position > this.rangeDown) this.moveDown();
	    document.getElementById("tat_tr"+this.position).className = this.classHighlight;
	    if (this.timeOutId) { clearTimeout(this.timeOutId); }
	    if (this.timeOut > 0) { this.timeOutId = setTimeout("vdh.autoComplete.removeDisplay()",this.timeOut); }
	}
	
	this. moveUp = function(){
	    this.rangeUp++;
	    this.rangeDown++;
	    this.remake();
	}
	this.moveDown = function(){
	    this.rangeUp--;
	    this.rangeDown--;
	    this.remake();
	}	

	this.enterPressed = function(){
	    if (!this.display) return;
	    this.display = 0;
	    var word = "";
	    var id = "";
	    var disabled = 0;
	    var c = 0;
	    for (var i=0;i<=this.keywords.length;i++){
	        if (this.bool[i]) c++;
	        if (c == this.position){
	        	if (typeof(this.keywords[i]["disabled"]) == "string") {
	        		disabled = 1;	        	
	        	}
	            word = this.keywords[i][this.lookUp];
	            id = this.keywords[i][this.siblingId];
	            break;
	        }
	    }
	    if (disabled == 1) { return; }
	    //a = word;//actb_keywords[actb_pos-1];//document.getElementById('tat_td'+actb_pos).;
	    a = word.replace(/&nbsp;&nbsp;/g, "");
	    this.current.value = a;
	    this.siblingObj.value = id;
	    this.removeDisplay();
		return false;

	}
	
	this.removeDisplay = function(){
	    this.display = 0;
	    if (document.getElementById("tat_div")) document.body.removeChild(document.getElementById("tat_div"));
	    if (this.timeOutId) { clearTimeout(this.timeOutId); }
	}

	this.checkKey = function(sndr, evt, arr){
	    a = evt.keyCode;
	    if (a == 38){ // up key
	        this.goUp();
	    }else if(a == 40){ // down key
	        this.goDown();
	    }else if(a == 13 || a == 9){
	        return this.enterPressed();
	    } else if (a == 27) {
	    	this.removeDisplay();
	    } else {
			this.complete(sndr, evt, arr);	    
	    }
	}
	
	this.complete = function (sndr,evt,arr){
	    if (arr) this.keywords = arr;
	    if (evt.keyCode == 38 || (evt.keyCode == 40 && this.display != false) || evt.keyCode == 13 || evt.keyCode == 27) return;
	    var i;
	    if (this.display){
	        var word = 0;
	        var c = 0;
	        for (var i=0;i<=this.keywords.length;i++){
	            if (this.bool[i]) c++;
	            if (c == this.position){
	                word = i;
	                break;
	            }
	        }
	        this.previous = word;//actb_pos;
	    }else{ this.previous = -1};
	
	    if (!sndr) var sndr = evt.srcElement;
	    this.current = sndr;
	/*
	    if (sndr.value == ''){
	        actb_removedisp();
	        return;
	    }
	*/	

	    var t = sndr.value; 
    	this.currentKey = String.fromCharCode(evt.which);
	    if (evt.which == 8) {
	    	this.currentKey = false;
	    	if (t.length > 0) {
				t = t.substr(0, t.length -1);
			}
	    } else {
	    	t += this.currentKey;
	    }
	    
	    if (this.firstText){
	        var re = new RegExp("^" + t, "i");
	    }else{
	        var re = new RegExp(t, "i");
	    }
	
	    this.total = 0;
	    this.create = false;	    
	    for (i=0;i<this.keywords.length;i++){
	        this.bool[i] = false;
	        if (re.test(this.keywords[i][this.lookUp])){
	            this.total++;
	            this.bool[i] = true;
	            if (this.previous == i) this.create = true;
	        }
	    }
	    if (this.timeOutId) { clearTimeout(this.timeOutId); }
	    if (this.timeOut > 0) { this.timeOutId = setTimeout("vdh.autoComplete.removeDisplay()",this.timeOut); }
	    this.generate(this.bool);
		
	}
}

/* Initialise some required variables and objects */
vdh.initialise = function () {
	vdh.loading = false;
	vdh.domNodes = new Array();
	vdh.vars = new Array();
	if (document.layers) { document.captureEvents(Event.KEYPRESS); }
	
//	vdh.clickableRows.initialise();
//	vdh.autoComplete = new vdh.autoCompleteTextBox();
}
if (window.addEventListener) {
	window.addEventListener("load", vdh.initialise, false);
} else if (window.attachEvent) {
	vdh.ie = true;
	window.attachEvent("onload", vdh.initialise);
}
