// suggest widget functionality for searching
// (c) 2007 Loco (Loohuis Consulting), http://www.loohuis-consulting.nl/
// This work is licensed under a 
// Creative Commons Attribution-Share Alike 3.0 Netherlands License
// see http://www.loohuis-consulting.nl/development/cc-by-sa.php

// detect IE and below
var OLD_IE = false;
var suggestElm = 'plaatspcode';

// server side script
var scriptURL = window.location.protocol + '//' + window.location.host + window.location.pathname;
var timer;
var hidetimer;
var delay = 700;
var KEYUP = 38;
var KEYDN = 40;
var KEYENTER = 13;
var hasSuggests= false;
var highlight = -1;
var suggestions;
var acBase;
var buffer;

// set up the action when the HTML has loaded
window.addEvent('load', autoSuggestInit);

// initialize
function autoSuggestInit() {
	// track old browsers
	if (document.id('OLD_IE')) {
		OLD_IE = true;
	}
	var searchtext = document.id(suggestElm);
	// assign key handler
	// don't do suggestions in older IE's because of display bugs
	if (searchtext && !OLD_IE) {
		searchtext.addEvent('keydown', keyHandler.bind(searchtext), false);
		searchtext.addEvent('blur', hideSuggest.bind(searchtext), false);
		// don't let browser interfere
		searchtext.setProperty("autocomplete", "off");
	}
}

//
// event handlers
//

// main keystroke event handler
function keyHandler(e) {
	e = e || window.event;
	var key = e.keyCode;

	switch(key) {
		case KEYENTER:
			hideSuggest();
			return false;
			exit;
			break;

		case KEYUP:
			processUp();
			break;

		case KEYDN:
			processDown();
			break;

		default:
			hideSuggest();
			// clear the current timeout
			clearTimeout(timer);
			// set up a timeout to load suggestions
			timer = setTimeout(getSuggests, delay);
	}
}

// handle clicks on suggestions
function clickHandler(e) {
	// mix in some Prototype (yuck)
	var elm = Event.element(e);
//	alert(elm.id);
//	var searchtext = document.getElementById(suggestElm);
	$(suggestElm).value = elm.id;
	hideSuggest();
}

// get suggestions from server
function getSuggests()
{
	var searchtext = document.getElementById(suggestElm);
	if (searchtext.value.length) { // only if there's content
		var getRequest = 'suggest=' + escape(searchtext.value);
		xmlhttpPost(scriptURL, getRequest, handleResponse);
	}
}

// hide suggest layer after small delay
function hideSuggest(e)
{
	hidetimer = setTimeout(_hide, 100);
}

function _hide()
{
	clearTimeout(hidetimer);
	var suggest = document.getElementById('suggest');
	suggest.style.display = 'none';
	hasSuggests = false;
	highlight = -1;
}

// load a suggested query
function loadSuggestion()
{
	var suggestForm = document.getElementById('searchform');
	suggestForm.submit();
}

// handle up event
function processUp()
{
	if (hasSuggests) {
		var suggest = document.getElementById('suggest');
		var list = suggest.firstChild;
		opts = list.childNodes;
		if (highlight > 0) {
			opts[highlight].className = 'suggestion';
			highlight--;
			opts[highlight].className = 'suggestion active';
			var searchtext = document.getElementById(suggestElm);
			autoComplete(searchtext, suggestions[highlight]);
		}
	}
}

// handle down event
function processDown()
{
	if (hasSuggests) {
		var suggest = document.getElementById('suggest');
		var list = suggest.firstChild;
		opts = list.childNodes;
		if (highlight < opts.length - 1) {
			if (highlight >= 0)
				opts[highlight].className = 'suggestion';
			highlight++;
			opts[highlight].className = 'suggestion active';
			var searchtext = document.getElementById(suggestElm);
			autoComplete(searchtext, suggestions[highlight]);
		}
	}
}

// do autocomplete to str in input elm
function autoComplete(elm, str)
{
	var len = acBase.length;
	add = str.substr(len);
	elm.value = acBase + add;
	if (elm.setSelectionRange) {
		elm.setSelectionRange(len, str.length);
	}
	else { // IE
		var oRange = elm.createTextRange();
		oRange.moveStart("character", len);
		oRange.moveEnd("character", add.length);
		oRange.select();
		elm.caretPos = len;
	}
}

//
// AJAX request handling
//

// process a response from the server
function handleResponse(response)
{
	// buffer input for autocompletion
	var searchtext = document.getElementById(suggestElm);
	acBase = searchtext.value;

	suggestions = response.split(';');
	// display returned suggestions in suggest list
	if (suggestions.length > 1) {
		var list = document.getElementById('suggest');
		// delete child ul
		while (list.childNodes.length)
			list.removeChild(list.firstChild);
		// create new list
		var ul = document.createElement('ul');
		var i = 0;
		for (var s in suggestions) {
			if (typeof suggestions[s] != 'function') { // avoid prototype extensions
				var li = document.id(document.createElement('li'));
				li.id = suggestions[s];
				var a = document.createElement('a');
				var tn = document.createTextNode(suggestions[s]);
				li.appendChild(tn);
				ul.appendChild(li);
				li.addEvent('click', clickHandler.bind(li), false);
			}
		}
		list.appendChild(ul);
		list.style.display = 'block';
		hasSuggests = true;
	}
	else
		hideSuggest();
	// if at least one suggestion is present, do autocomplete
	if (suggestions[0].length) {
		var searchtext = document.getElementById(suggestElm);
		autoComplete(searchtext, suggestions[0]);
	}
}

// after http://www.onlamp.com/pub/a/onlamp/2005/05/19/xmlhttprequest.html
function xmlhttpPost(url, querystring) {
	var xmlHttpReq = false;
	// Mozilla/Safari
	if (window.XMLHttpRequest) {
		xmlHttpReq = new XMLHttpRequest();
	}
	// IE
	else if (window.ActiveXObject) {
		xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
	}
	xmlHttpReq.open('POST', url, true);
	xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	xmlHttpReq.onreadystatechange = function() {
		if (xmlHttpReq.readyState == 4) {
			handleResponse(xmlHttpReq.responseText);
		}
	}
	xmlHttpReq.send(querystring);
}

// http://www.quirksmode.org/js/findpos.html
function findPosX(obj)
{
	var curleft = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curleft += obj.offsetLeft
			obj = obj.offsetParent;
		}
	}
	else if (obj.x)
		curleft += obj.x;
	return curleft;
}

function findPosY(obj)
{
	var curtop = 0;
	if (obj.offsetParent)
	{
		while (obj.offsetParent)
		{
			curtop += obj.offsetTop
			obj = obj.offsetParent;
		}
	}
	else if (obj.y)
		curtop += obj.y;
	return curtop;
}


