//
//  This script was created
//  by Mircho Mirev
//  mo /mo@momche.net/
//
//	:: feel free to use it BUT
//	:: if you want to use this code PLEASE send me a note
//	:: and please keep this disclaimer intact
//

function cAutocomplete( sInputId )
{
	this.init( sInputId )
}

cAutocomplete.CS_NAME = 'Autocomplete component'
cAutocomplete.CS_OBJ_NAME = 'AC_COMPONENT'
cAutocomplete.CS_LIST_SUFFIX = 'ACList'

cAutocomplete.CB_AUTOINIT = true

cAutocomplete.CN_OFFSET_TOP = 1
cAutocomplete.CN_OFFSET_LEFT = 0

cAutocomplete.CN_LINE_HEIGHT = 19
cAutocomplete.CN_NUMBER_OF_LINES = 10
cAutocomplete.CN_HEIGHT_FIX = 2

cAutocomplete.CN_CLEAR_TIMEOUT = 300
cAutocomplete.CN_SHOW_TIMEOUT = 200

cAutocomplete.nCount = 0

cAutocomplete.autoInit = function()
{
	var nI = 0
	var hACE = null

	var aInputs = document.getElementsByTagName( 'INPUT' )
	for( nI = 0; nI < aInputs.length; nI ++ )
	{
		if( aInputs[ nI ].type.toLowerCase() == 'text' )
		{
		 	var sLangAtt = aInputs[ nI ].getAttribute( 'acdropdown' )
			if( sLangAtt != null && sLangAtt.length > 0 )
			{
				if( aInputs[ nI ].id == '' )
				{
					aInputs[ nI ].id = cAutocomplete.CS_OBJ_NAME + cAutocomplete.nCount
				}
				hACE = new cAutocomplete( aInputs[ nI ].id )
			}
		}
	}

	var aSelects = document.getElementsByTagName( 'SELECT' )
	for( nI = 0; nI < aSelects.length; nI ++ )
	{
	 	var sLangAtt = aSelects[ nI ].getAttribute( 'acdropdown' )
		if( sLangAtt != null && sLangAtt.length > 0 )
		{
			if( aSelects[ nI ].id == '' )
			{
				aSelects[ nI ].id = cAutocomplete.CS_OBJ_NAME + cAutocomplete.nCount
			}
			hACE = new cAutocomplete( aSelects[ nI ].id )
		}
	}
}

if( cAutocomplete.CB_AUTOINIT )
{
	if( window.attachEvent ) 
	{
		window.attachEvent( 'onload', cAutocomplete.autoInit )
	}
	else if( window.addEventListener )
	{
		window.addEventListener( 'load', cAutocomplete.autoInit, false )
	}
}

cAutocomplete.prototype.init = function( sInputId )
{
	this.sInputId = sInputId
	this.sListId = sInputId + cAutocomplete.CS_LIST_SUFFIX

	this.hActiveSelection = null
	
	var hInput = document.getElementById( this.sInputId )
	hInput.hAutocomplete = this

	//the value of the input before the list is displayed
	this.sActiveValue = ''
	this.bListDisplayed = false
	this.nItemsDisplayed = 0
	
	this.sObjName = cAutocomplete.CS_OBJ_NAME + (cAutocomplete.nCount++)
	this.hObj = this.sObjName
	eval( this.hObj + '= this' )

	this.createList()
	this.initInput()
}
 
cAutocomplete.prototype.initInput = function()
{
	var hInput = document.getElementById( this.sInputId )
	if( hInput.attachEvent ) 
	{
		hInput.attachEvent( 'onkeyup', cAutocomplete.onInputKeyUp )
		hInput.attachEvent( 'onkeydown', cAutocomplete.onInputKeyDown )
		hInput.attachEvent( 'onblur', cAutocomplete.onInputBlur )
		hInput.attachEvent( 'focus', cAutocomplete.onInputFocus )
	}
	else if( hInput.addEventListener )
	{
		hInput.addEventListener( 'keyup', cAutocomplete.onInputKeyUp, false )
		hInput.addEventListener( 'keydown', cAutocomplete.onInputKeyDown, false )
		hInput.addEventListener( 'blur', cAutocomplete.onInputBlur, false )
		hInput.addEventListener( 'focus', cAutocomplete.onInputFocus, false )
	}
}

cAutocomplete.prototype.createList = function()
{
	var hInput = document.getElementById( this.sInputId )

	var hContainer = document.createElement( 'DIV' )
	hContainer.className = 'autocomplete_holder'
	hContainer.id = this.sListId
	hContainer.hAutocomplete = this
	
	var hFirstBorder =  document.createElement( 'DIV' )
	hFirstBorder.className = 'autocomplete_firstborder'
	var hSecondBorder =  document.createElement( 'DIV' )
	hSecondBorder.className = 'autocomplete_secondborder'

	var hList = document.createElement( 'UL' )
	hList.className = 'autocomplete'
	
	var hListItem = null
	var hListItemLink = null
	var hArrKey = null
	var hArrEl = null

	if( hInput.tagName.toLowerCase() != 'select' )
	{
		var hArr = this.getListArray()
		
		for( hArrKey in hArr )
		{
			sArrEl = hArr[ hArrKey ]
			hListItem = document.createElement( 'LI' )
			hListItemLink = document.createElement( 'A' )
			hListItemLink.href = '#'
			hListItemLink.innerHTML = sArrEl
			hListItem.appendChild( hListItemLink )
			hList.appendChild( hListItem )
		}
	}
	else
	{
		for( var nI = 0; nI < hInput.options.length; nI++ )
		{
			sArrEl = hInput.options.item( nI ).text
			hListItem = document.createElement( 'LI' )
			hListItemLink = document.createElement( 'A' )
			hListItemLink.href = '#'
			hListItemLink.innerHTML = sArrEl
			hListItem.appendChild( hListItemLink )
			hList.appendChild( hListItem )
		}
	}

	if( hInput.tagName.toLowerCase() == 'select' )
	{
		var hNewInput = document.createElement( 'INPUT' )
		hNewInput.type = 'text'
		hNewInput.style.width = hInput.offsetWidth
		hInput.parentNode.replaceChild( hNewInput, hInput )
		hNewInput.id = this.sInputId
		hNewInput.hAutocomplete = this
	}

	hSecondBorder.appendChild( hList )
	hFirstBorder.appendChild( hSecondBorder )
	hContainer.appendChild( hFirstBorder )
	document.body.appendChild( hContainer )
	
	if( hContainer.attachEvent ) 
	{
		hContainer.attachEvent( 'onclick', cAutocomplete.onItemClick )
	}
	else if( hContainer.addEventListener )
	{
		hContainer.addEventListener( 'click', cAutocomplete.onItemClick, false )
	} 
}

cAutocomplete.prototype.hasOptionsAvailable = function( sStartsWith )
{
	var hArr = this.getListArray()
	for( hArrKey in hArr )
	{
		if( ( hArr[ hArrKey ].indexOf( sStartsWith ) == 0 ) && ( hArr[ hArrKey ].length > sStartsWith.length ) )
		{
			return true
		}
	}
	return false
}

cAutocomplete.prototype.getListArray = function()
{
	var hInput = document.getElementById( this.sInputId )
	var sAA = hInput.getAttribute( 'autocomplete_list' ).toString()
	var sAAS = hInput.getAttribute( 'autocomplete_list_sort' )
	var hArr = null

	if( sAA.indexOf( 'array:' ) >= 0 )
	{
		hArr = eval( sAA.substring( 6 ) )
	}
	else if(  sAA.indexOf( 'list:' ) >= 0 )
	{
		hArr = sAA.substring( 5 ).split( '|' )
	}
	
	if( sAAS != null )
	{
		return hArr.sort()
	}
	else
	{
		return hArr
	}
}

cAutocomplete.prototype.showOptions = function()
{
	if( this.hActiveSelection )
	{
		this.hActiveSelection.className = ''
	}

	var hInput = document.getElementById( this.sInputId )
	var nTop = getObject.getSize( 'offsetTop', hInput )
	var nLeft = getObject.getSize( 'offsetLeft', hInput )
	
	this.sActiveValue = hInput.value
	var sStartWith = this.sActiveValue
	
	var hContainer = document.getElementById( this.sListId )
	hContainer.style.width = document.getElementById( this.sInputId ).offsetWidth

	var hList = hContainer.getElementsByTagName( 'UL' ).item( 0 )
	var hItems = hList.childNodes
	var hLinkItem = null
	var nCount = 0
	for( var nI = 0; nI < hItems.length; nI++ )
	{
		if( hItems.item( nI ).nodeType != 1 ) continue
		hLinkItem = getSubNodeByName( hItems.item( nI ), 'a' )
		if( hLinkItem )
		{
			if( sStartWith.length = 0 || sStartWith.length >= hLinkItem.innerHTML.length || hLinkItem.innerHTML.toLowerCase().indexOf( sStartWith.toLowerCase() ) != 0 )
			{
				hItems.item( nI ).style.display = 'none'
			}
			else
			{
				hItems.item( nI ).style.display = 'block'
				nCount++
			}
		}
	}
	
	if( nCount > 0 )
	{
		var nNumLines = ( nCount < cAutocomplete.CN_NUMBER_OF_LINES ) ? nCount : cAutocomplete.CN_NUMBER_OF_LINES;
		hList.style.height = nNumLines * cAutocomplete.CN_LINE_HEIGHT + cAutocomplete.CN_HEIGHT_FIX + 'px'
	
		hContainer.style.top = nTop + hInput.offsetHeight + cAutocomplete.CN_OFFSET_TOP + 'px'
		hContainer.style.left = nLeft + cAutocomplete.CN_OFFSET_LEFT + 'px'
		hContainer.style.visibility = 'visible'
		this.bListDisplayed = true
	}
	else
	{
		hContainer.style.visibility = 'hidden'
		this.bListDisplayed = false
	}
	this.nItemsDisplayed = nCount
}

cAutocomplete.prototype.hideOptions = function()
{
	var hContainer = document.getElementById( this.sListId )
	hContainer.style.visibility = 'hidden'
}


//nAP - advance to position
cAutocomplete.prototype.selectOption = function( hNewOption )
{
	if( this.hActiveSelection )
	{
		if( this.hActiveSelection == hNewOption )
		{
			return
		}
		else
		{
			this.hActiveSelection.className = ''
		}
	}
	this.hActiveSelection = hNewOption
	var hInput = document.getElementById( this.sInputId )
	if( this.hActiveSelection != null )
	{
		this.hActiveSelection.className = 'selected'
		hInput.value = this.hActiveSelection.innerHTML
	}
	else
	{
		hInput.value = this.sActiveValue
	}
}

cAutocomplete.prototype.deselectOption = function( )
{
	if( this.hActiveSelection != null )
	{
		this.hActiveSelection.className = ''
		this.hActiveSelection = null
	}
}

cAutocomplete.prototype.clearList = function()
{
	this.deselectOption()
	this.hideOptions()
	this.bListDisplayed = false
}

cAutocomplete.prototype.getPrevDisplayedItem = function( hItem )
{
	if( hItem == null )
	{
		var hContainer = document.getElementById( this.sListId )
		var hList = hContainer.getElementsByTagName( 'UL' ).item( 0 )
		hItem = hList.childNodes.item( hList.childNodes.length - 1 )
	}
	else
	{
		hItem = getPrevNodeSibling( hItem.parentNode )
	}
	while( hItem != null )
	{
		if( hItem.style.display == 'block' )
		{
			return hItem
		}
		hItem = hItem.previousSibling
	}
	return null
}

cAutocomplete.prototype.getNextDisplayedItem = function( hItem )
{
	if( hItem == null )
	{
		var hContainer = document.getElementById( this.sListId )
		var hList = hContainer.getElementsByTagName( 'UL' ).item( 0 )
		hItem = hList.childNodes.item( 0 )
	}
	else
	{
		hItem =  getNextNodeSibling( hItem.parentNode )
	}
	while( hItem != null )
	{
		if( hItem.style.display == 'block' )
		{
			return hItem
		}
		hItem = hItem.nextSibling
	}
	return null
}


cAutocomplete.onInputKeyDown = function ( hEvent )
{
	if( hEvent == null )
	{
		hEvent = window.event
	}
	var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget
	var hAC = hElement.hAutocomplete
	var hContainer = document.getElementById( hAC.sListId )
	var hEl = getParentByTagName( hElement, 'A' )
	if( hContainer != null && hAC.bListDisplayed )
	{
		var hLI = null
		var hLINext = null
		//the new active selection
		if( hEvent.keyCode == 13 || hEvent.keyCode == 27 )
		{
			hAC.clearList()
			return
		}
		if( hEvent.keyCode == 38 )
		{
			//up
			hLINext = hAC.getPrevDisplayedItem( hAC.hActiveSelection )
			if( hLINext != null )
			{
				hAC.selectOption( hLINext.childNodes.item(0) )
				if( hAC.nItemsDisplayed > cAutocomplete.CN_NUMBER_OF_LINES )
				{
					hAC.hActiveSelection.scrollIntoView()
				}
			}
			else
			{
				hAC.selectOption( null )
			}
		}
		else if ( hEvent.keyCode == 40 )
		{
			//down
			hLINext = hAC.getNextDisplayedItem( hAC.hActiveSelection )
			if( hLINext != null )
			{
				hAC.selectOption( hLINext.childNodes.item(0) )
				if( hAC.nItemsDisplayed > cAutocomplete.CN_NUMBER_OF_LINES )
				{
					hAC.hActiveSelection.scrollIntoView( false )
				}
			}
			else
			{
				hAC.selectOption( null )
			}
		}
	}
	if ( ( hEvent.keyCode == 40 ) || ( hEvent.keyCode == 38 ) )
	{
		hEvent.cancelBubble = true
		hEvent.returnValue = false
		return false
	}
}

cAutocomplete.onInputKeyUp = function ( hEvent )
{
	if( hEvent == null )
	{
		hEvent = window.event
	}
	if ( ( hEvent.keyCode == 40 ) || ( hEvent.keyCode == 38 ) || ( hEvent.keyCode == 13 ) || ( hEvent.keyCode == 27 ) )
	{
		hEvent.cancelBubble = true
		hEvent.returnValue = false
		return false
	}
	var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget
	var hAC = hElement.hAutocomplete
	var sStartValue = hElement.value
	if( hAC.hShowTimeout )
	{
		clearTimeout( hAC.hShowTimeout )
		hAC.hShowTimeout = null
	}
	hAC.hShowTimeout = setTimeout( hAC.hObj+'.showOptions()', cAutocomplete.CN_SHOW_TIMEOUT )
}

cAutocomplete.onInputBlur = function( hEvent )
{
	if( hEvent == null )
	{
		hEvent = window.event
	}
	var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget
	var hAC = hElement.hAutocomplete
	if( !hAC.hClearTimeout )
	{
		hAC.hClearTimeout = setTimeout( hAC.hObj+'.clearList()', cAutocomplete.CN_CLEAR_TIMEOUT )
	}
}

cAutocomplete.onInputFocus = function( hEvent )
{
	if( hEvent == null )
	{
		hEvent = window.event
	}
	var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget
	var hAC = hElement.hAutocomplete
	if( hAC.hClearTimeout )
	{
		clearTimeout( hAC.hClearTimeout )
		hAC.hClearTimeout = null
	}
}

cAutocomplete.onItemClick = function( hEvent )
{
	if( hEvent == null )
	{
		hEvent = window.event
	}
	var hElement = ( hEvent.srcElement ) ? hEvent.srcElement : hEvent.originalTarget
	var hContainer = getParentByProperty( hElement, 'className', 'autocomplete_holder' )
	var hEl = getParentByTagName( hElement, 'A' )
	if( hContainer != null )
	{
		var hAC = hContainer.hAutocomplete
		hAC.selectOption( hEl )
		var hInput = document.getElementById( hAC.sInputId )
		hInput.focus()
	}
}