



function SloppyRegExp( matchOn, mods ) {
	var cm, matched, upper, i, realMatch = '', sub = b25.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(!b25)
	var b25 = {};

/**
 * b25 Suggest interface
 */
b25.Suggest = {
	BS_URI: '/lookup.html?str=',
	BS_TIMEOUT: 100,
	BS_INITIALIZED: false,
	sub: [
		'aàáâãäåæāăą',
		'iìíîïīĭĩ',
		'eèéêëēĕėęě',
		'oòóôõöōŏő',
		'uyùúûüýũūŭůű',
		' ?'
	],
	request: null,
	timeout: false,
	element: null,
	popup: null,
	append: null,
	popupActive: false,
	lastValue: '',
	init: function( elm ) {
		if(!b25.Suggest.popup) {
			var contentBody = document.getElementById('bodyconstraint') || document.body;
			// Strange whitespaces/indentation of entries in IE if I remove this table...
			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;
			b25.Suggest.popup = document.createElement('div');
			b25.Suggest.popup.setAttribute('id', 'suggest_popup');
			b25.Suggest.popup.style.display = 'none';
			b25.Suggest.popup.innerHTML = markup;
			contentBody.appendChild(b25.Suggest.popup);
			b25.Suggest.append = b25.Suggest.popup.getElementsByTagName('td')[0];
		}
		b25.Suggest.element = elm;
		b25.Suggest.BS_INITIALIZED = true;
	},
	initRequestObject: function() {
		b25.Suggest.request = null;
		var req;
		try { req = new ActiveXObject("Msxml2.XMLHTTP"); }
		catch(err) {
			try { req = new ActiveXObject("Microsoft.XMLHTTP"); }
			catch(err) { req = null; }
		}
		if(!req && (typeof(XMLHttpRequest)!="undefined")) {
			req = new XMLHttpRequest();
		}
		b25.Suggest.request = req;
	},
	handleKeyNav: function( evt, isUp ) {
		if(gClientIsIE5) return true;
		if(evt.keyCode) {
			switch(evt.keyCode) {
				case 9: // TAB
					if(b25.Suggest.popup.selectedSuggestion)
						b25.Suggest.popup.selectedSuggestion.onmousedown();
					break;
				case 13: // ENTER
					if(isUp)
						return false;
					if(b25.Suggest.popup.selectedSuggestion) {
						b25.Suggest.popup.selectedSuggestion.onmousedown();
						if(evt.preventDefault) evt.preventDefault();
						return false;
					}
					break;
				case 27: // ESC
					b25.Suggest.__hidePopup();
					b25.Suggest.lastValue = b25.Suggest.element.value;
					break;
				case 38: // UP
					if(b25.Suggest.popupActive)
						b25.Suggest.__previousSuggestion();
					if(evt.preventDefault) evt.preventDefault();
					break;
				case 40: // DOWN
					if(b25.Suggest.popupActive)
						b25.Suggest.__nextSuggestion();
					if(evt.preventDefault) evt.preventDefault();
					break;
				default:
					return true;
					break;
			}
		}
	},
	handleActivity: function( elm, evt ) {
		if(gClientIsIE5) return;
		if(!b25.Suggest.BS_INITIALIZED)
			b25.Suggest.init(elm);
		if(elm.value == '') {
			b25.Suggest.__hidePopup();
			b25.Suggest.lastValue = elm.value;
		}
		else if(elm.value != b25.Suggest.lastValue) {
			if(b25.Suggest.timeout)
				clearTimeout(b25.Suggest.timeout);
			b25.Suggest.timeout = setTimeout(b25.Suggest.requestSuggestion, b25.Suggest.BS_TIMEOUT)
		}
	},
	requestSuggestion: function() {
		if(b25.Suggest.element.value=='') {
			b25.Suggest.__hidePopup();
			return;
		}
		b25.Suggest.initRequestObject();
		var req = b25.Suggest.request,
		    url = b25.Suggest.BS_URI + encodeURIComponent(b25.Suggest.element.value);
		req.onreadystatechange = b25.Suggest.responseHandler;
		req.open('GET', url, true);
		req.send('');
		b25.Suggest.lastValue = b25.Suggest.element.value;
	},
	responseHandler: function() {
		if(b25.Suggest.request.readyState==4) {
			switch(b25.Suggest.request.status) {
				case 200: // 200 OK
					b25.Suggest.parseResponse(b25.Suggest.request.responseText);
					break;
				case 404: // 404 Not Found
				default:
					window.status = 'b25 Suggest error: Server returned HTTP code ' + b25.Suggest.request.status;
					break;
			}
		}
	},
	parseResponse: function( response ) {
		var append = b25.Suggest.append,
		    elm = b25.Suggest.element;
		var suggestList = [];
		var rl = response.split('\n');
		for(var i=0; rl[i]; i+=2)
			suggestList.push({
				n: rl[i],
				d: (rl[i+1] > 0) ? rl[i+1] + '&#160;' + $t_hotels : $t_hotels_around
			});
		
		if(suggestList.length) {
			var spt = '';
			b25.Suggest.suggestions = [];
			for(var i=0; suggestList[i]; i++) {
				b25.Suggest.suggestions[i] = suggestList[i].n;
				spt += '<div class="suggest_entry" onmouseover="b25.Suggest.__setActiveSuggestion(this)" onmouseout="b25.Suggest.__unsetActiveSuggestion(this)" onmousedown="b25.Suggest.__useSuggestion(' + i + ')">';
				spt += highlightSloppy(suggestList[i].n, b25.Suggest.lastValue);
				spt += '<div class="suggest_dist">' + suggestList[i].d + '</div>';
				spt += '</div>';
			}
			append.innerHTML = spt;
			b25.Suggest.__showPopup();
		}
		else {
			b25.Suggest.__hidePopup();
		}
		b25.Suggest.popup.selectedSuggestion = null;
	},
	__setActiveSuggestion: function( elm ) {
		if(b25.Suggest.popup.selectedSuggestion)
			b25.Suggest.__unsetActiveSuggestion(b25.Suggest.popup.selectedSuggestion);
		DOM.addClass(elm, 'suggest_entry_selected');
		b25.Suggest.popup.selectedSuggestion = elm;
	},
	__unsetActiveSuggestion: function( elm ) {
		DOM.removeClass(elm, 'suggest_entry_selected');
	},
	__nextSuggestion: function() {
		if(b25.Suggest.popup.selectedSuggestion && b25.Suggest.popup.selectedSuggestion.nextSibling)
			var newSuggestion = b25.Suggest.popup.selectedSuggestion.nextSibling;
		else // wrap around
			var newSuggestion = b25.Suggest.append.firstChild;
		b25.Suggest.__setActiveSuggestion(newSuggestion);
	},
	__previousSuggestion: function() {
		if(b25.Suggest.popup.selectedSuggestion && b25.Suggest.popup.selectedSuggestion.previousSibling)
			var newSuggestion = b25.Suggest.popup.selectedSuggestion.previousSibling;
		else // wrap around
			var newSuggestion = b25.Suggest.append.lastChild;
		b25.Suggest.__setActiveSuggestion(newSuggestion);
	},
	__useSuggestion: function( index ) {
		b25.Suggest.element.value = b25.Suggest.suggestions[index];
		b25.Suggest.__hidePopup();
		//var frm = DOM.getParentOrSelf(b25.Suggest.element, 'form');
		//if(frm['ifl']) frm['ifl'].value = '1';
	},
	__showPopup: function() {
		if(b25.Suggest.element.value=='') {
			b25.Suggest.__hidePopup();
			return;
		}
		var elm = b25.Suggest.element,
			popup = b25.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'; // hide to force redraw, fixes rendering bug in ff 1.0.x
		popup.style.display = 'block';
		b25.Suggest.popupActive = true;
	},
	__hidePopup: function() {
		if(gClientIsIE5) return;
		var hideIt = function() {
			b25.Suggest.popup.style.display = 'none';
		}
		setTimeout(hideIt, 100);
		b25.Suggest.popupActive = false;
		// XXX: really do this here?
		b25.Suggest.popup.selectedSuggestion = null;
		b25.Suggest.lastValue = '';
	}
};


