/*
Requires:

Server-side file 'autosearch.php' which is passed variable 'searchfor'
and returns a list of results, each followed with "\n"

A form with id 'searchform'

An input box with the following attributes: (onfocus bit is optional)
id=searchfor onfocus="this.value='';" onkeyup="ajs_suggest();" autocomplete=off

Around the input box:
<div id=as_container>.....<div id=autosearch></div></div>

The following styles:

#autosearch {
	display: none;
	position: absolute;
	left: 5px;
	top: 19px;
	width: auto;
	/*max-height: 300px;+/
	/*height: expression( this.scrollHeight > 300 ? "300px" : "auto" ); /* Hack for IE lack of max-height +/
	/*overflow-y: auto;+/
	overflow: visible;
	border: 1px solid #CDCDBA;
	background-color: #F9F9F2;
}
* html div#autosearch {
	margin-top: 1px; /* Hack for IE +/
}
.sr {
	background-color: #F9F9F2;
}
.srs {
	background-color: #F2F2E5;
	cursor: pointer;
}
*/


/* If set to true the search term of the selected suggestion is taken
   from between <!--s--> and <!--e-->                                  */
var ajs_extractSearchTerm = true;

/* Number of characters to be typed before query is sent */
var ajs_numChars = 2;

/* Number of results visible in the div at one time */
var ajs_visibleresults = 10;


/* END CONFIG */





// Sets up XMLHttpRequest object.
// Returns null if browser doesn't support AJAX
function getXmlHttpRequestObject () {
	var xmlHttp;
	try {
		// Firefox, Opera 8.0+, Safari
		xmlHttp=new XMLHttpRequest();
	} catch (e) {
		// Internet Explorer
		try {
			xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e) {
			try {
				xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
			} catch (e) {
				return null;
			}
		}
	}
	return xmlHttp;
}



var ajs_request = getXmlHttpRequestObject();
var ajs_initialised = false;
var ajs_sf, ajs_as;

// onkeyup handler for the search textbox with id 'searchfor'
// Starts the AJAX request
function ajs_suggest() {
	if (!ajs_initialised) {
		ajs_sf = document.getElementById('searchfor');
		ajs_as = document.getElementById('autosearch');
		ajs_sf.onkeydown = ajs_keydown;
		ajs_sf.onblur = ajs_blur;
		ajs_initialised = true;
	}
	
	if (ajs_request.readyState == 4 || ajs_request.readyState == 0) {
		var query = ajs_sf.value;
		query = query.replace(/^\s+/, '').replace(/\s+$/, '');
		if (query.length < ajs_numChars) {
			ajs_emptyResults();
			ajs_sf.currentQuery = '';
			return;
		}
		if (ajs_sf.currentQuery && ajs_sf.currentQuery == query) {
			return;
		}
		ajs_sf.currentQuery = query;
		
		ajs_request.open("GET", 'autosearch.php?searchfor=' + escape(query), true);
		ajs_request.onreadystatechange = ajs_handleResponse;
		ajs_request.send(null);
	}
}


// Called when the AJAX response is returned
// Writes suggestion to div with id 'autosearch'
function ajs_handleResponse() {
	if (ajs_request.readyState == 4) {
		ajs_emptyResults();
		var res = ajs_request.responseText.split("\n");
		if (res.length > 1) {
			var idx;
			for(i=0; i < res.length - 1; i++) {
				idx = ajs_as.numResults;
				ajs_as.results[ajs_as.numResults++] = res[i];
				ajs_as.innerHTML += '<div class="sr"'
						 +  ' onmouseover="ajs_mouseover(' + idx + ')"'
						 +  ' onclick="ajs_mouseclick(' + idx + ')">'
						 +  res[i]
						 +  '</div>';
			}
			ajs_showResults();
		}
	}
}


function ajs_keydown(e) {
	e = e || window.event;
	switch (e.keyCode) {
	case 13: // return
		if (ajs_as.selectedIndex != -1) {
			ajs_mouseclick(ajs_as.selectedIndex);
			return false;
		}
		break;
	case 27: // escape
		ajs_hideResults();
		return false;
		break;
	case 38: // up arrow
		ajs_handleup();
		return false;
		break;
	case 40: // down arrow
		ajs_handledown();
		return false;
		break;
	}
	return true;
}

function ajs_blur(e) {
	setTimeout('ajs_blur_wait()',200);
}

function ajs_blur_wait() {
	ajs_emptyResults();
	ajs_sf.currentQuery = '';
}

function ajs_hideResults() {
	ajs_as.style.display = 'none';
}

function ajs_ishidden() {
	return ajs_as.style.display == 'none';
}

function ajs_showResults() {
	ajs_as.style.display = 'block';
	ajs_as.selectedIndex = -1;
	ajs_as.scrollTop = 0;
}

function ajs_emptyResults() {
	ajs_hideResults();
	ajs_as.innerHTML = '';
	ajs_as.numResults = 0;
	ajs_as.selectedIndex = -1;
	ajs_as.results = [];
}


function ajs_mouseover(idx) {
	ajs_as.selectedIndex = idx;
	ajs_sf.focus();
	
	ajs_highlightsel();
}

function ajs_mouseclick(idx) {
	var str = ajs_as.results[idx];
	if (ajs_extractSearchTerm) {
		var matches = str.match(/<!--s-->(.+)<!--e-->/);
		ajs_sf.value = matches[1];
	} else {
		ajs_sf.value = str;
	}
	document.getElementById('searchform').submit();
}

function ajs_handleup() {
	if (ajs_as.numResults > 0 && ajs_ishidden()) {
		ajs_showResults();
		return;
	}
	
	var item_height = ajs_as.offsetHeight/ajs_visibleresults;

	if (ajs_as.selectedIndex == 0) {
		return;
	} else if (ajs_as.selectedIndex < 0) {
		ajs_as.selectedIndex = ajs_as.numResults - 1;
		ajs_as.scrollTop = ajs_as.numResults*item_height - ajs_as.offsetHeight;
	} else {
		ajs_as.selectedIndex--;
	}
		
	ajs_highlightsel();
	
	/* Check scroll pos is in range */
	if (ajs_as.scrollTop > item_height*(ajs_as.selectedIndex+ajs_visibleresults) - ajs_as.offsetHeight) {
		ajs_as.scrollTop -= item_height;
	}
}

function ajs_handledown() {
	if (ajs_as.numResults > 0 && ajs_ishidden()) {
		ajs_showResults();
		return;
	}

	if (ajs_as.selectedIndex == ajs_as.numResults - 1)
		return;
	else if (ajs_as.selectedIndex < 0)
		ajs_as.selectedIndex = 0;
	else
		ajs_as.selectedIndex++;
		
	ajs_highlightsel();
	
	/* Check scroll pos is in range */
	var item_height = ajs_as.offsetHeight/ajs_visibleresults;
	if (ajs_as.scrollTop < item_height*(ajs_as.selectedIndex+1) - ajs_as.offsetHeight) {
		ajs_as.scrollTop += item_height;
	}
}

function ajs_highlightsel() {
	var divs = ajs_as.getElementsByTagName('div');

	for (i = 0; i < divs.length; i++) {
		if (i == ajs_as.selectedIndex) {
			divs[i].className = 'srs';
		} else {
			divs[i].className = 'sr';
		}
	}
}
