if (! Naf.isLoaded('Naf.Autocomplete'))
{
	Naf.Autocomplete = function(id, url) {
		this.id = Naf.Registry.put(this)
		this.input = $(id)
		this.input.setAttribute('aid', this.id)
		this.url = url
		
		this.container = document.createElement('div')
		Element.extend(this.container)
		this.container.className = 'naf_autocomplete'
		this.container.style.position = 'absolute'
		this.container.innerHTML = '<button onclick="Element.hide(this.parentNode); return false;" style="float:right;border-style:none;background:transparent;">&times;</button><br />'
		
		Element.hide(this.container)
		this.input.parentNode.insertBefore(this.container, this.input.nextSibling)
		
		Event.observe(this.input, 'keydown', this.offer)
		Event.observe(this.container, 'keydown', this.nextOffer)
	}
	Naf.Autocomplete.handleKey = function(ac, code) {
		switch (code) {
			case Event.KEY_ESC :
				Element.hide(ac.container)
				return true
				break;
			case Event.KEY_DOWN :
				if (ac.container.visible())
				{
					var list = ac.container.getElementsByTagName('a')
					if (list.length)
					{
						list.item(0).focus()
						return true
					}
				}
				break;
			default:
				return false
				break;
		}
		return false
	}
	Naf.Autocomplete.prototype.nextOffer = function(e) {
		var a = Event.element(e)
		var c = a.parentNode
		switch (e.keyCode) {
			case Event.KEY_ESC :
				Element.hide(c)
				ac.input.focus()
				Event.stop(e)
				return true
				break;
			case Event.KEY_DOWN :
				if (a.nextSibling)
					a.nextSibling.focus()
				else
					c.getElementsByTagName('a').item(0).focus()
				
				Event.stop(e)
				return true
				break;
			case Event.KEY_UP:
				if (a.previousSibling)
					a.previousSibling.focus()
				else
					c.lastChild.focus()
				
				Event.stop(e)
				return true
				break;
			default:
				ac.input.focus()
				return false
				break;
		}
	}
	Naf.Autocomplete.prototype.offer = function(e) {
		var ac = Naf.Autocomplete.instance(e)
		Event.stop(e)
		if (Naf.Autocomplete.handleKey(ac, e.keyCode))
			return ;

		ac.clearOffers()
		
		var v = ac.input.value.strip()
		if (v.length < 3) return
		new Ajax.Request(
			ac.url,
			{
				method:'post',
				parameters:{q:v},
				onSuccess:function(r) {
					try {
						eval('var json = ' + r.responseText)
						if ('error' == json.code)
						{
							alert("- " + json.error_list.join("\n- "))
						} else {
							ac.clearOffers()
							var url
							for (var i = 0; i < json.data.length; ++i)
							{
								if ('url' in json.data[i])
									ac.container.innerHTML += '<a style="display:block;" href="' + json.data[i].url + '">' + json.data[i].text + '</a>'
								else
									ac.container.innerHTML += '<a style="display:block;" href="' + json.data[i].url + '" onclick="$(\'' + ac.input.getAttribute('id') + '\').value=\'' + json.data[i].text + '\'; Naf.Registry.get(' + ac.id + ').hideOffers(); return false;">' + json.data[i].text + '</a>'
							}
							if (ac.container.hasChildNodes())
							{
								ac.scaleContainer()
								Element.show(ac.container)
							}
						}
					} catch (e) {
						alert(r.responseText)
						alert(e.message)
					}
				},
				onFailure:function(r) {
					alert('HTTP request failed!')
				}
			});
	}
	Naf.Autocomplete.prototype.clearOffers = function() {
		var list = this.container.getElementsByTagName('a')
		for (var i = 0; i < list.length; ++i)
			this.container.removeChild(list.item(i))
	}
	Naf.Autocomplete.prototype.hideOffers = function() {
		this.container.hide()
	}
	Naf.Autocomplete.prototype.scaleContainer = function() {
		this.container.style.width = Element.getWidth(this.input) + 'px'
		var h = Element.getHeight(this.input)
		var p = Position.cumulativeOffset(this.input)
		this.container.style.left = p[0] + 'px'
		this.container.style.top = (p[1] + h) + 'px'
	}
	Naf.Autocomplete.instance = function(e) {
		return Naf.Registry.get(parseInt(Event.element(e).getAttribute('aid')))
	}
}