/**
 * Search Suggest
 * Tues, 14 Oct 2008 16:13:30 GMT
 */
function searchSuggest(options)
{
    this.init(options);
}

searchSuggest.prototype =
{
    boxselector: null,
    inputselector: null,
    open: false,
    prevsearch: null,
    selected: 0,
    timer: null,
    url: null,
    
    init: function(options)
    {
        this.boxselector = "#"+options.boxid;
        this.inputselector = "#"+options.inputid;
        this.url = options.url;
        
        if(options.enterPress != undefined)
        {
            this.enterPress = options.enterPress;
        }
        
        $(this.boxselector).css("width", $(this.inputselector).width()+2+"px");
        $(this.inputselector).attr("autocomplete", "off");
        $(this.inputselector).keydown(this.preserveScope(this, this.keyDownEvent));
        $(this.inputselector).keypress(this.preserveScope(this, this.keyPressEvent));
        $("body").click(this.preserveScope(this, this.closeSuggestBox));
    },
    
    preserveScope: function(context, method, argument)
    {
        return function(argument2)
        {
            arg = (argument == undefined) ? argument2 : argument;
            
            return method.call(context, arg);
        };
    },
    
    enterPress: function() { },
    
    closeSuggestBox: function()
    {
        $(this.boxselector).css("display", "none");
        $(this.boxselector+" div").removeClass("hover");
        this.open = false;
        this.stopTimer();
    },
    
    openSuggestBox: function()
    {
        $(this.boxselector).css("display", "block");
        this.open = true;
        this.selected = 0;
    },
    
    keyDownEvent: function(event)
    {
        if(this.open && event.which == 38)
        {
            this.select(this.selected - 1);
        }
        
        else if(this.open && event.which == 40)
        {
            this.select(this.selected + 1);
        }
        
        else if(event.which == 27 || event.which == 9)
        {
            this.closeSuggestBox();
        }
        
        else if(event.which == 46 || event.which == 32 || event.which == 8 || (event.which >= 65 && event.which <= 90))
        {
            this.startTimer();
        }
    },
    
    keyPressEvent: function(event)
    {
        if(this.open && this.selected != 0 && event.which == 13)
        {
            value = $(this.boxselector+" div").eq(this.selected - 1).data("value");
            this.selectValue(value);
            return false;
        }
    },
    
    startTimer: function()
    {
        if(this.timer != null)
        {
            this.stopTimer();
        }
        
        this.timer = window.setTimeout(this.preserveScope(this, this.getSuggestions), 300);
    },
    
    stopTimer: function()
    {
        window.clearTimeout(this.timer);
    },
    
    getSuggestions: function()
    {
        value = $(this.inputselector).val();
        
        if(!isNaN(value) || value.length < 3)
        {
            this.closeSuggestBox();
            return;
        }
        
        if(value == this.prevsearch)
        {
            this.openSuggestBox();
            return;
        }
        
        var instance = this;        
        $.ajax(
        {
            type: "GET",
            url: this.url,
            data: "search=" + value,
            success: function(data)
            {
                (instance.preserveScope(instance, instance.populateSuggestBox, data))();
            }
        });
        
        this.prevsearch = value;
    },
    
    select: function(index)
    {
        divs = $(this.boxselector+" div");
        
        if(index > divs.length)
        {
            index = 1;
        }
        
        else if(index < 1)
        {
            index = divs.length;
        }

        divs.removeClass("hover");
        divs.eq(index-1).addClass("hover");
        this.selected = index;
    },
    
    selectValue: function(value)
    {
        $(this.inputselector).val(value);
        this.closeSuggestBox();
        this.stopTimer();
        this.enterPress();
    },
    
    createSuggestElement: function(suggest, index)
    {
        el = document.createElement("div");
        
        value = $(suggest).attr("value");
        display = $(suggest).attr("display") || value;
        
        $(el).append(display);
        $(el).data("value", value);
        
        var instance = this;
        $(el).click(function()
        {
            (instance.preserveScope(instance, instance.selectValue, $(this).data("value")))();
        });
        
        $(el).mouseover(this.preserveScope(this, this.select, index));
        
        return el;
    },
    
    populateSuggestBox: function(data)
    {
        $(this.boxselector).empty();
        this.openSuggestBox();
        
        var suggests = $("suggest", data);
        
        if(suggests.length == 0)
        {
            $(this.boxselector).text("No results found.");
        }
                    
        for(i = 0; i < suggests.length; i++)
        {
            el = this.createSuggestElement(suggests[i], i + 1);
            
            $(this.boxselector).append(el);
        }
    }
};