var allUISearchBox = [];

$.fn.searchbox = function(options) {
	var defaults = {
	    'maxitems': {},
	    'select': 'open',
	    'title': true
	    };
	
	var caller = this,
	    options = $.extend({}, defaults, options),
	    sb = new SearchBox(caller, options);	

	allUISearchBox.push(sb);
};

function SearchBox(caller, options) {
	var self = this,
        input = $(caller),
        options = options,
        val = '',
        container = $('<div></div>')
                        .addClass('ui-searchbox-container');

    /* privát */

    var killAll = function() {
        self.hide();
        self.clear();
        };
    
    
    var open = function(active) {
        location.replace(active.attr('href'));
        return false;
        }; 
    
    
    var select = function(active) {
        val = active.html();
        input.val(active.html()).change();
        killAll();
        return false;
        };
    
    
    var callback = function(active) {
        if (options.select) {
            switch(options.select) {
                case 'open':
                   return open(active);
                   break;
                case 'select':
                    return select(active);
                    break;
                default:
                    if ($.isFunction(options.select))
                        return options.select(active);
                    break;
                }
            }
        };


    var refresh = function() {
        $.getJSON('/ajax/search/getList',
            {'search_target': input.val(), 'filter': options.filter, 'maxitems': options.maxitems},
            function(result) {
                var show = false;
                
                self.clear();

                for (var category in result.data) {
                    if (result.data[category]['items']) {
                        show = true;
                        
                        if (options.title) {
                            container.append('<span class="ui-searchbox-category">'+result.data[category]['title']+'</span>');
                            } 
                            
                        for (var item in result.data[category]['items']) {
                            var i = result.data[category]['items'][item],
                                link = $('<a href="'+result.data[category].link+item+'">'+i.value+'</a>');
                            
                            if (i.data) for (d in i.data) link.data(d, i.data[d]);
                            container.append(link);
                            }
                        }
                    }
                    
                container.find('a')
                    .hover(function() {
                        var link = $(this);
                        link.parent().find('.state-hover').removeClass('state-hover').blur();
                        link.addClass('state-hover');
                        return false;                        
                        })
                    .click(function(event) { callback($(this)); return false; });

                if(show && container.css('display') == 'none') self.show();
                else if(!show && container.css('display') != 'none') self.hide();
                
                $('a:first', container).mouseover();
                input.focus();
                });
            };

    /* konstrukt */

    input
        .val('')
        .attr('autocomplete', 'off')
        .addClass("ui-searchbox-input")
        .wrap('<div class="ui-searchbox-wrapper"></div>')
        .closest('div')
            .append(container.hide());

    container
        .width(input.outerWidth())
        .css('margin-top', input.outerHeight());

    input.keyup(function(event) {
        var ival = input.val();
        
        if (ival != val) {
            val = ival;
            refresh();
            if (ival.length == 0) killAll();
            }
        });

    input.keydown(function(event) {
		var e = event.which,
            active = $('.state-hover', container);
		
		switch(e) {
            case 40: // down arrow
                if (active.size() == 0) {
                    container.find('a:eq(0)').mouseover();
                    }
                else {
                    var next = active.next('a');
                    if (next.length == 0) next = active.next('span').next('a');
                    if (next.length != 0) {
                        active.mouseout();
                        next.mouseover();
                        }
                    }
                return false;
                break;

            case 38: // up arrow
                var prev = active.prev('a');
                active.mouseout();
                if (prev.length == 0) prev = active.prev('span').prev('a');
                if (prev.length != 0) prev.mouseover();
                return false;
                break;
			
            case 27: // escape
				killAll();
				break;

            case 9: //tab
                if (container.css('display') != 'none') {
                    select(active);
                    killAll();
                    $(":input:eq(" + $(":input").index(input) + 1 + ")").mouseover();
                    }
                break;

            case 13: // enter
                return callback(active);
                break;
            }
        });
        
        
    $(document).click(killAll);

    /* public */

    this.show = function() {
        container.show();
        };

    this.hide = function() {
        container.hide();
        };
 
    this.clear = function() {
        container.empty();
        };
};

