/**********************************************************

	Selection Object

	Version: 0.3 (Beta)
	Author: Fred Snyder
	Company: Castwide Technologies
	URL: http://castwide.com
	Date Created: March 31, 2006
	Date Modified: April 6, 2006

	Updates:
	04/06/2006 - Added requireMatch option

	This application is free for use, modification, and
	and distribution.  This header, including the above
	notices and credits, must remain intact and unchanged.

**********************************************************/

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;
}

function CWOption(txt, val) {
	this.text = txt;
	this.value = val;
}

function cwSelectForce(cnt) {
	cnt.selectedIndex = 0;
	cnt.selector.input.value = cnt.options[cnt.selectedIndex].value;
	cnt.focus();
}

function cwSelectTimeout(sel) {

	sel.select.style.width = (sel.input.clientWidth + 20) + 'px';
	/*
	sel.select.style.top = (sel.input.offsetTop + sel.input.clientHeight) + 'px';
	sel.select.style.left = sel.input.offsetLeft + 'px';
	*/
	sel.select.style.top = (findPosY(sel.input) + sel.input.clientHeight) + 'px';
	sel.select.style.left = findPosX(sel.input) + 'px';

	var sofar = ( sel.caseSensitive == true ? sel.input.value : sel.input.value.toUpperCase() );
	// Clear the selection box
	if (sel.select.options.length > 0) {
		sel.select.innerHTML = '';
	}
	if (sel.input.value == '') {
		if (sel.dropToggle == false) {
			sel.select.style.display = 'none';
			return;
		}
	}
	for (i = 0; i < sel._options.length; i++) {
		if (sel.useText == true) {
			var cmp = sel._options[i].text;
		} else {
			var cmp = sel._options[i].value;
		}
		if (sel.caseSensitive == false) {
			cmp = cmp.toUpperCase();
		}
		//if (cmp.substr(0, sofar.length) == sofar) {
		if (cmp.indexOf(sofar) != -1) {
			if ( (sel.select.options.length == 0) && (sel.autoComplete == true) ) {
				sel.input.value = sel._options[i].value;
				var bios = new BIOSelection();
				bios.setSelectionRange(sel.input, sofar.length, sel._options[i].value.length);
			}
			var opt = new Option(sel._options[i].text, sel._options[i].value);
			sel.select.options.add(opt);
		} /*else {
			if (sel.select.options.length > 0) {
				break;
			}
		}*/
	}
	sel.select.selectedIndex = -1;
	sel.dropToggle = false;
	if (sel.select.options.length > 0) {
		sel.select.size = (sel.select.options.length > 15 ? 15 : sel.select.options.length);
		if (sel.select.size == 1) sel.select.size = 2;
		sel.select.style.display = 'inline';
		sel.undo = sel.input.value;
	} else {
		sel.select.style.display = 'none';
		if (sel.requireMatch == true) {
			sel.input.value = sel.undo;
			sel.undo = '';
			cwSelectTimeout(sel);
		}
	}
}

function CWSelect(id) {
	this.useText = true;
	this.caseSensitive = false;
	this.autoComplete = true;
	this.requireMatch = true;

	this.dropToggle = false;

	this.undo = '';

	this._options = new Array();

	this.addOption = function(text, value) {
		this._options.push(new CWOption(text, value));
		//this._options = this._options.sort(cwSelectSort);
	}

	this.sortOptions = function() {
		this._options = this._options.sort(cwSelectSort);
	}

	this.input = document.getElementById(id);
	this.nextInput = this.input.nextSibling;
	while (this.nextInput) {
		if (this.nextInput.focus) {
			break;
		}
		this.nextInput = this.nextInput.nextSibling;
	}

	/******************************************************
	Input Field Setup
	******************************************************/

	this.input.setAttribute('autocomplete', 'off');
	this.input.selector = this;
	this.input.value = '';

	/******************************************************
	Selection Box Setup
	******************************************************/

	this.select = document.createElement('SELECT');
	this.input.parentNode.insertBefore(this.select, this.input.nextSibling);
	this.select.name = 'cwselect-' + this.input.id;
	this.select.id = 'cwselect-' + this.input.id;
	this.select.style.position = 'absolute';
	this.select.style.display = 'none';
	this.select.selector = this;

	/******************************************************
	Input Field Events
	******************************************************/

	this.input.onblur = function(e) {
		var evt = new BIOEvent(e);
		var sel = evt.target().selector;
		if (sel.select.selectedIndex == -1) {
			sel.select.style.display = 'none';
		}
	}

	this.input.onkeydown = function(e) {
		var evt = new BIOEvent(e);
		var sel = evt.target().selector;
		if (evt.keyCode() == 40) {
			if (sel.select.style.display == 'inline') {
				sel.select.selectedIndex = 0;
				sel.select.focus();
				if (!window.event) setTimeout('cwSelectForce(document.getElementById(\'' + sel.select.id + '\'));', 1);
			}
			evt.setKeyCode(null);
			evt.stopPropagation();
			evt.preventDefault();
			return false;
		}
		if ( (evt.keyCode() == 8) && (sel.autoComplete == true) ) {
			var bios = new BIOSelection();
			sel.input.value = sel.input.value.substr(0, bios.getSelectionRangeStart(sel.input) - 1);
			evt.setKeyCode(null);
			evt.stopPropagation();
			evt.preventDefault();
			setTimeout('cwSelectTimeout(document.getElementById(\'' + evt.target().id + '\').selector)', 0);
			return false;
		}
		if (evt.keyCode() == 8) {
			sel.undo = sel.input.value;
			setTimeout('cwSelectTimeout(document.getElementById(\'' + evt.target().id + '\').selector)', 0);
		}
		if ( (evt.keyCode() == 13) || (evt.keyCode() == 9) ) {
			// Key is enter or tab
			// If requireMatch is set, force the value to be a valid option or
			// blank if none match.
			if (sel.requireMatch == true) {
				var opt = sel.select.selectedIndex;
				if ( (opt == -1) && (sel.select.options.length > 0) ) {
					opt = 0;
				}
				if (opt != -1) {
					sel.input.value = sel.select.options[opt].value;
				} else {
					sel.input.value = '';
				}
			}
			if (sel.nextInput) {
				sel.nextInput.focus();
			}
			evt.setKeyCode(null);
			evt.stopPropagation();
			evt.preventDefault();
			return false;
		}
	}

	this.input.onkeypress = function(e) {
		var evt = new BIOEvent(e);
		var sel = evt.target().selector;
		var asc = evt.keyCode();
		if ( ( (asc >= 32) && (asc <= 126) ) || (sel.autoComplete == false) ) {
			if (asc != 9) {
				sel.undo = sel.input.value;
				setTimeout('cwSelectTimeout(document.getElementById(\'' + evt.target().id + '\').selector)', 0);
			}
		}
	}

	this.input.onclick = function(e) {
		var evt = new BIOEvent(e);
		var sel = evt.target().selector;
		if (sel.input.value == '') {
			sel.dropToggle = true;
			cwSelectTimeout(evt.target().selector);
		}
	}

	this.input.ondblclick = function(e) {
		var evt = new BIOEvent(e);
		var sel = evt.target().selector;
		sel.dropToggle = true;
		cwSelectTimeout(evt.target().selector);
	}

	/******************************************************
	Selection Box Events
	******************************************************/

	this.select.onblur = function(e) {
		var evt = new BIOEvent(e);
		var sel = evt.target().selector;
		sel.select.style.display = 'none';
		sel.input.value = sel.select.options[sel.select.selectedIndex].value;
	}

	this.select.onkeydown = function(e) {
		var evt = new BIOEvent(e);
		var sel = evt.target().selector;
		var asc = evt.keyCode();
		if (asc == 38) {
			if (sel.select.selectedIndex == 0) {
				sel.input.focus();
				sel.input.select();
			}
		} else if ( (asc == 13) || (asc == 9) ) {
			sel.input.value = sel.select[sel.select.selectedIndex].value;
			sel.select.blur();
			sel.select.style.display = 'none';
			if (sel.nextInput) {
				sel.nextInput.focus();
			}
			evt.stopPropagation();
			sel.select.selectedIndex = -1;
			return false;
		} else if (asc == 8) {
			evt.stopPropagation();
			return false;
		}
	}

	this.select.onmouseover = function(e) {
		var evt = new BIOEvent(e);
		if (evt.target().selectedIndex == -1) evt.target().selectedIndex = 0;
	}

	this.select.onclick = function(e) {
		var evt = new BIOEvent(e);
		var sel = (evt.target().selector ? evt.target().selector : evt.target().parentNode.selector);
		sel.input.value = sel.select[sel.select.selectedIndex].value;
		sel.select.blur();
		sel.select.style.display = 'none';
		if (sel.nextInput) {
			sel.nextInput.focus();
		}
		sel.select.selectedIndex = -1;
	}

	this.select.onchange = function(e) {
		var evt = new BIOEvent(e);
		var sel = evt.target().selector;
		if (sel.select.selectedIndex != -1) {
			sel.input.value = sel.select.options[sel.select.selectedIndex].value;
		}
	}

}

function cwSelectSort(a, b) {
	var first = new String(a.text);
	var second = new String(b.text);
	if (first.toUpperCase() < second.toUpperCase()) {
		return -1;
	} else if (first.toUpperCase() > second.toUpperCase()) {
		return 1;
	}
	return 0;
}
