var AUTOCOMPLETE_TIMEOUT = 0;

function Autocomplete(params)
{
    this.id = params.id;
    this.text = null;
    this.urldelegate = params.urldelegate;
    this.typenotify = params.typenotify;
    this.changenotify = params.changenotify;
    this.listdelegate = params.listdelegate;

    this.onTextChange = Autocomplete_onTextChange;
    this.onBlur = Autocomplete_onBlur;
    this.onChange = Autocomplete_onChange;
    
    this.hide = Autocomplete_hide;
    this.show = Autocomplete_show;
    this.fillList = Autocomplete_fillList;
    this.setText = Autocomplete_setText;
    this.loadTip = Autocomplete_loadTip;
    
    this.holder = $(this.id);
    if (this.holder != null) 
    {
        var ctl = this;
        this.holder.onkeyup = function () { ctl.onTextChange(this.value); };
        this.holder.onblur = function () { ctl.onBlur(); };
        this.holder.onchange = function () { ctl.onChange(this.value); };
        Element.writeAttribute(this.holder,"autocomplete", "off");
        this.holder.autocompleteObj = this;
    }
    
    this.tip = document.createElement("div");
    this.tip.style.display = "none";
    this.tip.style.position = "absolute";
    this.tip.style.top = "0px";
    this.tip.style.left = "0px";
    if (params.tipcss) this.tip.className = params.tipcss;
    
	var firstChild = null;
	if ( document.body.childNodes && document.body.childNodes.length > 0)
		firstChild = document.body.childNodes[ 0 ];
  	document.body.insertBefore( this.tip, firstChild );
        
    this.timerID = null;
    this.timerChangeID = null;
}

function Autocomplete_onTextChange(text)
{
    if (text != this.text)
    {
        if (text.length == 0) this.hide();
        else {
            var ctl = this;
            this.text = text;
            if (this.typenotify) this.typenotify(text);
            if (this.urldelegate) 
            {
                var url = this.urldelegate(text);
                if (this.timerID) { window.clearTimeout(this.timerID); this.timerID = null; }
                this.timerID = window.setTimeout(function () { ctl.loadTip(url) }, AUTOCOMPLETE_TIMEOUT);
            }
            else if (this.listdelegate) {
                if (this.timerID) { window.clearTimeout(this.timerID); this.timerID = null; }
                this.timerID = window.setTimeout(function () { ctl.fillList(ctl.listdelegate(text)) }, AUTOCOMPLETE_TIMEOUT);                
            }
                
        }
    }
}

function Autocomplete_onChange(text)
{
    if (this.changenotify)
    {
        var ctl = this;
        if (this.timerChangeID) { window.clearTimeout(this.timerChangeID); this.timerChangeID = null; }
        this.timerChangeID = window.setTimeout(function () { ctl.changenotify(text); ctl.timerChangeID=null; }, AUTOCOMPLETE_TIMEOUT);
    }
}

function Autocomplete_loadTip(url)
{
    this.timerID = null;
    var ctl = this;
    new Ajax.Request(url, { 
        method: 'get', 
        onSuccess: function (transport) { ctl.show(transport) }
    });
}

function Autocomplete_onBlur()
{
    if (this.timerID) { window.clearTimeout(this.timerID); this.timerID = null; }
    var ctl = this;
    this.text = this.holder.value;
    window.setTimeout(function() { ctl.hide() }, AUTOCOMPLETE_TIMEOUT);
}

function Autocomplete_hide()
{
    this.tip.style.left = 0;
    this.tip.style.top = 0;
    this.tip.style.display = "none";
}

function Autocomplete_show(transfer)
{
    if (!transfer.responseXML) return;
    
    var items = new Array();
    try
    {
        
        var doc = transfer.responseXML.documentElement;
        if (doc.childNodes)
        {
            var i;
            for (i=0; i<doc.childNodes.length; i++)
            {
                var node = doc.childNodes[i];
                if (node.childNodes && node.childNodes.length) items[items.length] = (node.childNodes[0].nodeValue);
            }
        }
    } catch (e) { }
    
    this.fillList(items);
}

function Autocomplete_fillList(items) {
    if (items.length)
    {
        var html = "";
        var i;
        for (i=0; i<items.length; i++)
        {
            if (i > 0) html += "<br/>";
            html += "<a href=\"javascript://\" onmousedown=\"AUTOCOMPLETE_sel('" + items[i].replace("\\","\\\\").replace("\'","\\\'") + "','" + this.id + "')\">" + items[i] + "</a>";
        }

        html += "<!--[if lte IE 6.5]><iframe></iframe><![endif]-->";
        
        var p = Element.cumulativeOffset(this.holder);
        var s = Element.cumulativeScrollOffset(this.holder);
        var b = Element.cumulativeScrollOffset(document.body);
        var d = Element.getDimensions(this.holder);
        
        this.tip.style.display = "block";
        this.tip.innerHTML = html;
        this.tip.style.left = (p.left - s.left + b.left) + "px";
        this.tip.style.top = (p.top + d.height - s.top + b.top) + "px";
        this.tip.style.width = d.width + "px";
    }
    else
    {
        this.hide();
    }
}

function Autocomplete_setText(text)
{
    if (this.timerChangeID) { window.clearTimeout(this.timerChangeID); this.timerChangeID = null; }
    
    this.text = text;
    this.holder.value = text;
    this.hide();
    
    if (this.changenotify) this.changenotify(text);
}

function AUTOCOMPLETE_sel(text,id)
{
    var ctl = $(id);
    if (ctl && ctl.autocompleteObj) ctl.autocompleteObj.setText(text);
}

function AUTOCOMPLETE_changenotify(text, id)
{
    var ctl = $(id);
    if (ctl && ctl.autocompleteObj && ctl.autocompleteObj.changenotify) ctl.autocompleteObj.changenotify(text);
}
