/*
	Autocomplete / Custom Dropdown script
	Copyright © 2008-2009 Frank Pelliccio, all rights reserved.
	
	Unauthorized duplication and / or distribution is
	strictly prohibited.

	Frank Pelliccio
	0xD media / design / development
	http://0xD.com
*/

var results = new Array();
var resultIDs = new Array();
var selected = -1;
var submitted = false;
var currentsearch = '';
var resultsvisible = false;
var noblur = false;
var processing = false;
var pending = false;
var userselected = false;
var strCurrentElement = '';

var acColor = '#808080';
var acSelectColor = '#b51f82';

var delay = 300; //ms between keystrokes

String.prototype.trim = function(x) {
	if (x=='left')
		return this.replace(/^\s*/,'');
	if (x=='right')
		return this.replace(/\s*$/,'');
	if (x=='normalize')
		return this.replace(/\s{2,}/g,' ').trim();

	return this.trim('left').trim('right');
} 

function initAC(strElement) {
	if (strElement != strCurrentElement) {
		results = new Array();
		selected = -1;
		submitted = false;
		currentsearch = '';
		resultsvisible = false;
		noblur = false;
		processing = false;
		pending = false;
		userselected = false;

		clearResults();

		strCurrentElement = strElement;
	}
}

function cancelEvent(e) {
	if (!e)
		e = window.event;

	if (e.stopPropagation)
		e.stopPropagation();
	else
		e.cancelBubble = true;
}

function selectItem(index) {
	noblur = false;
	if (userselected) {
		currentsearch = results[index].replace(/&nbsp;/gi,'').trim();
		var intID = document.getElementById('int' + strCurrentElement + 'ID')
		if (intID) {
			intID.value = resultIDs[index];
		}
	}

	submitForm();
}

function findPos(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		curleft = obj.offsetLeft
		curtop = obj.offsetTop
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft
			curtop += obj.offsetTop
		}
	}
	return [curleft,curtop];
}

function processData(strElement, strCompareString) {
	if (!pending) {
		initAC(strElement);

		if (results.length > 0) {
			var newHTML = '';
			var acroot = document.getElementById('ac' + strCurrentElement + 'root');
			var searchtext = document.getElementById('str' + strCurrentElement);
			var isDropDown = (acroot.className == 'xdDropDown');
			
			if (isDropDown)
				strCompareString = '';
			
			var matchLength = strCompareString.length;
			var matchStart = 0;
			var tempMatch = '';
			strCompareString = strCompareString.toLowerCase();

			var ac = document.getElementById('ac' + strCurrentElement);

			for (i=0;i<results.length;i++) {
				tempMatch = results[i].toLowerCase();
				matchStart = tempMatch.indexOf(strCompareString);
				tempMatch = results[i].substring(0, matchStart) + '<b>' + results[i].substring(matchStart, matchStart + matchLength) + '</b>' + results[i].substring(matchStart + matchLength, results[i].length);
				newHTML += '<div id="' + strCurrentElement + 'acresult' + i + '" onmousedown="userselected=true;selectItem(' + i + ');" class="dropdownItem" onmouseout="noblur=false;" onmouseexit="noblur=false;" onmouseover="highlight(' + i + ');">';
				newHTML += tempMatch + '</div>\r\n';
			}


			resultsvisible = true;

			var pos = findPos(searchtext);
			acroot.style.left = pos[0];
			acroot.style.top = pos[1] + searchtext.offsetHeight;

			if (isDropDown)
				acroot.style.width = searchtext.offsetWidth + 20;
			else
				acroot.style.width = searchtext.offsetWidth;

			acroot.style.overflow = 'auto';
			acroot.style.height = 100;
			acroot.onmousedown = function(e){noblur=true;cancelEvent(e);};
			acroot.onclick = 'noblur=true;'

			acroot.style.display = 'block';
			ac.innerHTML = newHTML;
		}
		else {
			clearResults();
		}
	}

	processing = false;
}
			
function validateData(e) {
	var keynum;
	var handled = false;

	if(window.event)
		keynum = e.keyCode;
	else if(e.which)
		keynum = e.which;

	// Escape
	if (keynum == 27) {
		noblur = false;
		userselected = false;
		hideResults(strCurrentElement);
		handled = true;
	}
	// Backspace
	else if (keynum == 8) {
		userselected = false;
		reloadData(e);
	}
	// Up Arrow
	else if (keynum == 38) {
		userselected = true;
		select(-1);
		handled = true;
	}
	// Down arrow
	else if (keynum == 40) {
		forceSearch(strCurrentElement);
		userselected = true;
		select(1);
		handled = true;
	}
	// Enter
	else if ((keynum == 13) && (selected >= 0)) {
		cancelEvent(e);
		selectItem(selected);
		handled = true;
		submitForm();
	}
	else {
		noblur = false;
		userselected = false;
	}

	if (handled) {
		if(window.event)
			window.event.keyCode = 0;

		return false;
	}
}

function reloadData(e) {
	var keynum;
	
	if (e) {
		if(window.event)
			keynum = e.keyCode;
		else if(e.which)
			keynum = e.which;
	}

	if ((keynum == null) || (keynum == 27)){
		if(window.event)
			window.event.keyCode = 0;

		return true;
	}
	else if ((keynum == 13) && (selected >= 0)) {
		if(window.event)
			window.event.keyCode = 0;

		cancelEvent(e);
		return true;
	}
	else {
		pending = true;
		selected = -1;
		processRequest();
	}
}

function debug(strMessage) {
	strMessage += '\r\n';
	
	var debugwin = document.getElementById('acdebugwin');
	
	if (!debugwin) {
		var body = document.getElementsByTagName('body')[0];
		debugwin = document.createElement('textarea');
		debugwin.id = 'acdebugwin';
		debugwin.style.width = 400;
		debugwin.style.height = 250;
		var button = document.createElement('input');

		button.type = 'button'
		button.value = 'Clear';
		button.onclick = function() { document.getElementById('acdebugwin').innerHTML = ''; };

		body.appendChild(debugwin);
		body.appendChild(button);
	}
	
	debugwin.innerHTML += strMessage;
}

function highlight(index) {
	noblur = true;

	if (selected >= 0) {
		unselect(selected);
	}

	selected = index;

	if ((selected >= 0) && (selected < results.length)) {
		var divX = document.getElementById(strCurrentElement + 'acresult' + selected);

		if (divX) {
			divX.style.backgroundColor = acSelectColor;
			divX.style.color = '#ffffff';

			ensureVisible(divX);
		}
	}
}

function ensureVisible(divItem) {
	var acroot = document.getElementById('ac' + strCurrentElement + 'root');
	var acTop = acroot.offsetTop;
	var acHeight = acroot.offsetHeight;
	var acRelTop = acroot.scrollTop;
	var acRelBottom = acroot.scrollTop + acHeight;

	var divTop = divItem.offsetTop;
	var divHeight = divItem.offsetHeight;
	var divBottom = divTop + divHeight;

	if (divTop < acRelTop)
		acroot.scrollTop = divTop;
	else if (divBottom > acRelBottom)
		acroot.scrollTop = divTop - (acHeight - divHeight) + 2;
}

function select(direction) {
	var next = selected + direction;

	if (next < 0)
		next = 0;
	else if (next >= results.length)
		next = results.length - 1;
		
	if (selected >= 0)
		unselect(selected);

	highlight(next);
}

function unselect(index) {
	if ((index >= 0) && (index < results.length)) {
		var divX = document.getElementById(strCurrentElement + 'acresult' + index);
		divX.style.backgroundColor = '#ffffff';
		divX.style.color = acColor;
	}
}
			
function processRequest() {
	if ((!pending) && (!processing) && (strCurrentElement)) {
		current = document.getElementById('str' + strCurrentElement).value.trim().toLowerCase();

		if ((!submitted) && (currentsearch != current)) {

			if (current) {
				processing = true;

				if (current.length > 0) {
					fetchResults(strCurrentElement, escape(current));
				}
				else {
					processing = false;
					pending = false;
					userselected = false;
					clearResults();
				}
			}
			else {
				userselected = false;
				clearResults();
			}
		}
	}
	else {
		setTimeout("processRequest()", delay);
		pending = false;
	}	
}

function fetchResults(strElement, search) {
	strCurrentElement = strElement;

	var url = 'http://' + window.location.hostname + '/autocomplete.asp?' + strCurrentElement + '=' + search;
	var head = document.getElementsByTagName('head')[0];
	var scriptTag = document.getElementById('ac' + strCurrentElement + 'Script');

	if (scriptTag)
		head.removeChild(scriptTag);
								
	script = document.createElement('script');
	script.src = url;
	script.type = 'text/javascript';
	script.id = 'ac' + strCurrentElement + 'Script';
	head.appendChild(script);
}
			
function hideResults(strElement) {
	if ((!noblur) && (strElement)) {
		selected = -1;
		resultsvisible = false;
		var acroot = document.getElementById('ac' + strElement + 'root');
		acroot.style.display = 'none'
		if (acroot.className == 'xdDropDown') {
			dropDownImage('off');
		}
	}
}
			
function submitForm() {
	if (!submitted) {
		if (strCurrentElement) {
			submitted = true;
			if (userselected) {
				document.getElementById('str' + strCurrentElement).value = currentsearch;
			}

			hideResults();
		}

		initAC('');

		submitted = false;
		return true;
	}

	return false;
}

function clearResults() {
	hideResults(strCurrentElement);
	currentsearch = '';
	results = new Array();
	resultIDs = new Array();
}

function forceSearch(strElement) {
	if (!resultsvisible) {
		initAC(strElement);

		if (results.length > 0) {
			processData(strCurrentElement, document.getElementById('str' + strCurrentElement).value);
		}
		else {
			var searchtext = document.getElementById('str' + strCurrentElement);
			if (searchtext) {
				currentsearch = '';
				processRequest();
			}
		}
	}
}

function dropDownImage(strState) {
	if (strCurrentElement)
		document.getElementById('btn' + strCurrentElement + 'Off').src = window.location.protocol + '//' + window.location.hostname + ':' + window.location.port + '/images/dropdown_button_grey_' + strState + '_20_24.gif';
}

function dropDown(strElement, arrData, arrIDs) {
	userselected = false;
	selected = -1;

	initAC(strElement);

	if (resultsvisible) {
		clearResults();
	}
	else {
		results = arrData;
		resultIDs = arrIDs;
		dropDownImage('on');
		processData(strCurrentElement, '');
	}
}
