
function ListBox(ulElement, field)
{
	if (!ulElement || (ulElement.className != 'listbox') || (ulElement.tagName != 'UL')) { return }

	var listBox = this;
	var listItems = Array();
	var events = new Events();
	var ulElement = ulElement;
	var itemSelected;
	var field = field;


	function ListItem(liElement, itemIndex)
	{
		var listItem = this;
		var itemIndex = itemIndex;

		this.liElement = liElement;


		this.setSelected = function(isSelected)
		{
			switch (isSelected)
			{
				case false:

					liElement.className = '';

					break;

				case true:

					liElement.className = 'selected';

					if (field)
					{
						field.value = liElement.attributes['key'].value;
					}

					itemSelected = itemIndex;

					if ((liElement.offsetTop + liElement.offsetHeight) > (ulElement.scrollTop + ulElement.clientHeight))
					{
						ulElement.scrollTop = (liElement.offsetTop + liElement.offsetHeight) - ulElement.clientHeight;
					}
					else if (liElement.offsetTop < ulElement.scrollTop)
					{
						ulElement.scrollTop = liElement.offsetTop;
					}

					break;

			}
		}


		var onMouseDown = function(e)
		{
			listBox.selectItem(itemIndex);

			if (e.preventDefault)
			{
				e.preventDefault();
			}

			ulElement.focus();

			return false;
		}

		if (liElement.className == 'selected')
		{
			itemSelected = itemIndex;
		}

		events.add(liElement, 'mousedown', onMouseDown);
	}


	this.selectItem = function(ndx)
	{
		for (var i = 0; i < listItems.length; i++)
		{
			listItems[i].setSelected(false);
		}

		listItems[ndx].setSelected(true);
	}


	var onKeyDown = function(e)
	{		
		switch (e.keyCode)
		{
			case 35:  // End

				if (listItems.length > 0)
				{
					listBox.selectItem(listItems.length-1);
				}

				break;

			case 36:  // Home

				if (listItems.length > 0)
				{
					listBox.selectItem(0);
				}

				break;

			case 38:  // Up arrow

				if (itemSelected > 0)
				{
					listBox.selectItem(itemSelected-1);
				}

				break;

			case 40: // Down arrow

				if (itemSelected + 1 < listItems.length)
				{
					listBox.selectItem(itemSelected+1);
				}

				break;

			default:

				return;
		}

		if (e.preventDefault)
		{
			e.preventDefault();
		}

		return false;
	}


	var items = ulElement.getElementsByTagName("LI");

	for (var i = 0; i < items.length; i++)
	{
		var item = items[i];
		var listItem = new ListItem(item, i);
		listItems.push(listItem);
	}

	if (itemSelected)
	{
		this.selectItem(itemSelected);
	}
	else if (listItems.length > 0)
	{
		this.selectItem(0);
	}	

	events.add(ulElement, 'keydown', onKeyDown);
}

function initListBox(elementID, fieldID)
{
	var ul = document.getElementById(elementID);
	var field = document.getElementById(fieldID);

	if (ul)
	{
		return new ListBox(ul, field);
	}
	else
	{
		return;
	}
}
