function getDimensions( elm ) {
	var box = { x:0, y:0, w:0, h:0 };
	if(document.getBoxObjectFor) {
		var boxRef = document.getBoxObjectFor(elm);
		box.x = boxRef.x;
		box.y = boxRef.y;
		box.w = boxRef.width;
		box.h = boxRef.height;
	}
	else if(elm.getBoundingClientRect) {
		var rxIE50 = /MSIE 5\.0/g;
		var boxRef = elm.getBoundingClientRect();
		box.x = boxRef.left;
		box.y = boxRef.top;
		box.w = (boxRef.right - boxRef.left);
		box.h = (boxRef.bottom - boxRef.top);
		if(document.compatMode && document.compatMode != 'BackCompat') {
			// IE6/compliance mode
			box.x += document.documentElement.scrollLeft - 2;
			box.y += document.documentElement.scrollTop - 2;
		}
		else if(!gClientIsIE5) {
			// IE5.5
			box.x += document.body.scrollLeft - 2;
			box.y += document.body.scrollTop - 2;
		}
	}
	else {
		// No known box information available, walking
		// manually through offsetParents to calculate x/y coordinates
		box.w = elm.offsetWidth;
		box.h = elm.offsetHeight;
		while(elm) {
			box.x += elm.offsetLeft;
			box.y += elm.offsetTop;
			if(elm.offsetParent) // Required for Safari 1.3
				elm = elm.offsetParent;
			else
				break;
		}
	}
	var cc;
	if(cc = document.getElementById('bodyconstraint'))
		box.x -= cc.offsetLeft;
	return box;
}


var DOM = {
	isParentOf: function( parentElm, contextElm) {
		while(contextElm && (contextElm != parentElm))
			contextElm = contextElm.parentNode;
		return (contextElm == parentElm);
	},
	getParentOrSelf: function( contextElm, nodeName ) {
		nodeName = nodeName.toLowerCase();
		while(contextElm.nodeName.toLowerCase() != nodeName && contextElm.parentNode)
			contextElm = contextElm.parentNode;
		return contextElm;
	},
	addClass: function( elm, className ) {
		elm.className += ' '+className;
	},
	removeClass: function( elm, className) {
		var classMatch = new RegExp('\\b'+className+'\\b', 'g');
		if(classMatch.test(elm.className))
			elm.className = elm.className.replace(classMatch, ' ');
	}	
};

var gClientIsGecko = (window.controllers) ? true : false;
var gClientIsOpera = (window.opera) ? true : false;
var gClientIsIE    = (document.all && !gClientIsOpera) ? true : false;
var gClientIsIE5   = (gClientIsIE && /MSIE 5\.0/.test(navigator.appVersion)) ? true : false;
var gClientIsMac   = (/Mac/.test(navigator.appVersion)) ? true : false;


function SloppyRegExp( matchOn, mods ) {
	var cm, matched, upper, i, realMatch = '', sub = combo.Suggest.sub;
	for(var c = 0; c < matchOn.length; c++) {
		matched = false;
		upper = isUpperCase(matchOn.charAt(c));
		cm = matchOn.charAt(c).toLowerCase();
		for(i in sub) {
			if(sub[i].indexOf(cm) != -1) {
				cm = '[' + sub[i] + ']';
				matched = true;
				break;
			}
		}
		if(upper)
			cm = cm.toUpperCase();
		realMatch += cm + ' ?'; // add optional whitespace
	}
	return new RegExp('(' + realMatch + ')', mods);
}

function isUpperCase( text ) {
	return (text == text.toUpperCase());
}


function highlightSloppy( text, matchOn ) {
	var sloppyMatch = SloppyRegExp(matchOn, 'i');
	if(sloppyMatch.test(text)) {
		var hlss = sloppyMatch.exec(text)[1];
		return text.replace(sloppyMatch, '<strong>'+hlss+'</strong>');
	}
	else
		return text;
}




if(!combo)
	var combo = {};

combo.Suggest = {
	BS_TIMEOUT: 100,
	BS_INITIALIZED: false,
	sub: [
		'aàáâãäåæaaa',
		'iìíîïiii',
		'eèéêëeeeee',
		'oòóôõöooo',
		'uyùúûüýuuuuu',
		' ?'
	],
	request: null,
	timeout: false,
	element: null,
	popup: null,
	append: null,
	popupActive: false,
	lastValue: '',
	locationID: -1,
	init: function( elm ) {
		if(!combo.Suggest.popup) {
			var contentBody = document.getElementById('bodyconstraint') || document.body;
			var markup = '<table cellspacing="0" cellpadding="0"><tr><td></td></tr></table>';
			if(document.all && !window.opera)
				markup = '<iframe style="position:absolute;width:1000px;height:1000px;" frameborder="0"></iframe>' + markup;
			combo.Suggest.popup = document.createElement('div');
			combo.Suggest.popup.setAttribute('id', 'suggest_popup');
			combo.Suggest.popup.style.display = 'none';
			combo.Suggest.popup.innerHTML = markup;
			contentBody.appendChild(combo.Suggest.popup);
			combo.Suggest.append = combo.Suggest.popup.getElementsByTagName('td')[0];
		}
		combo.Suggest.element = elm;
		combo.Suggest.BS_INITIALIZED = true;
	},
	handleKeyNav: function( evt, isUp ) {
		if(gClientIsIE5) return true;
		if(evt.keyCode) {
			switch(evt.keyCode) {
				case 9: // TAB
					if(combo.Suggest.popup.selectedSuggestion)
						combo.Suggest.popup.selectedSuggestion.onmousedown();
					break;
				case 13: // ENTER
					if(isUp)
						return false;
					if(combo.Suggest.popup.selectedSuggestion) {
						combo.Suggest.popup.selectedSuggestion.onmousedown();
						if(evt.preventDefault) evt.preventDefault();
						return false;
					}
					break;
				case 27: // ESC
					combo.Suggest.__hidePopup();
					combo.Suggest.lastValue = combo.Suggest.element.value;
					break;
				case 38: // UP
					if(combo.Suggest.popupActive)
						combo.Suggest.__previousSuggestion();
					if(evt.preventDefault) evt.preventDefault();
					break;
				case 40: // DOWN
					if(combo.Suggest.popupActive)
						combo.Suggest.__nextSuggestion();
					if(evt.preventDefault) evt.preventDefault();
					break;
				default:
					return true;
					break;
			}
		}
	},
	handleActivity: function( elm, evt ) {
		if(gClientIsIE5) return;
		if(!combo.Suggest.BS_INITIALIZED)
			combo.Suggest.init(elm);
		if(elm.value == '') {
			combo.Suggest.__hidePopup();
			combo.Suggest.lastValue = elm.value;
		}
		else if(elm.value != combo.Suggest.lastValue) {
			if(combo.Suggest.timeout)
				clearTimeout(combo.Suggest.timeout);
			combo.Suggest.timeout = setTimeout(combo.Suggest.requestSuggestion, combo.Suggest.BS_TIMEOUT)
		}
	},
	requestSuggestion: function() {
		if(combo.Suggest.element.value=='') {
			combo.Suggest.__hidePopup();
			return;

		}
		combo.Suggest.lastValue = combo.Suggest.element.value;
		combo.Suggest.parseResponse(combo.Suggest.element.value);
	},

	parseResponse: function( response ) {
		var append = combo.Suggest.append,
		    elm = combo.Suggest.element;
		var suggestList = [];
		if(combo.Suggest.onFillCombo) 
			combo.Suggest.onFillCombo(response, suggestList);
		if(suggestList.length) {
			var spt = '';
			combo.Suggest.suggestions = [];
			for(var i=0; suggestList[i]; i++) {
				combo.Suggest.suggestions[i] = suggestList[i].n;
				spt += '<div class="suggest_entry" onmouseover="combo.Suggest.__setActiveSuggestion(this)" onmouseout="combo.Suggest.__unsetActiveSuggestion(this)" onmousedown="combo.Suggest.__useSuggestion(' + i + ',' + suggestList[i].id + ')">';
				spt += highlightSloppy(suggestList[i].n, combo.Suggest.lastValue);
				spt += '<div class="suggest_dist">' + suggestList[i].d + '</div>';
				spt += '</div>';
			}
			append.innerHTML = spt;
			combo.Suggest.__showPopup();
		}
		else {
			combo.Suggest.__hidePopup();
		}
		combo.Suggest.popup.selectedSuggestion = null;
	},
	__setActiveSuggestion: function( elm ) {
		if(combo.Suggest.popup.selectedSuggestion)
			combo.Suggest.__unsetActiveSuggestion(combo.Suggest.popup.selectedSuggestion);
		DOM.addClass(elm, 'suggest_entry_selected');
		combo.Suggest.popup.selectedSuggestion = elm;
	},
	__unsetActiveSuggestion: function( elm ) {
		DOM.removeClass(elm, 'suggest_entry_selected');
	},
	__nextSuggestion: function() {
		if(combo.Suggest.popup.selectedSuggestion && combo.Suggest.popup.selectedSuggestion.nextSibling)
			var newSuggestion = combo.Suggest.popup.selectedSuggestion.nextSibling;
		else 
			var newSuggestion = combo.Suggest.append.firstChild;
		combo.Suggest.__setActiveSuggestion(newSuggestion);
	},
	__previousSuggestion: function() {
		if(combo.Suggest.popup.selectedSuggestion && combo.Suggest.popup.selectedSuggestion.previousSibling)
			var newSuggestion = combo.Suggest.popup.selectedSuggestion.previousSibling;
		else 
			var newSuggestion = combo.Suggest.append.lastChild;
		combo.Suggest.__setActiveSuggestion(newSuggestion);
	},
	__useSuggestion: function( index, id ) {
		combo.Suggest.element.value = combo.Suggest.suggestions[index];
		document.forms[0].Ort.value = locations[id].name;
		if(combo.Suggest.afterSelection) combo.Suggest.afterSelection(id);
		combo.Suggest.__hidePopup();
	},
	__showPopup: function() {
		if(combo.Suggest.element.value=='') {
			combo.Suggest.__hidePopup();
			return;
		}
		var elm = combo.Suggest.element,
			popup = combo.Suggest.popup;
		var elmPos = getDimensions(elm);
		var left = elmPos.x, top = elmPos.y + (elm.offsetHeight);
		popup.style.left = left + 'px';
		popup.style.top  = top + 'px';
		popup.style.display = 'none'; 
		popup.style.display = 'block';
		combo.Suggest.popupActive = true;
	},
	__hidePopup: function() {
		if(gClientIsIE5) return;
		var hideIt = function() {
			combo.Suggest.popup.style.display = 'none';
		}
		setTimeout(hideIt, 100);
		combo.Suggest.popupActive = false;
		combo.Suggest.popup.selectedSuggestion = null;
		combo.Suggest.lastValue = '';
	}
};

