function businessSelect(filter, results, selected, fieldName, exclude)
{
    var ya = this;

    function newSearch()
    {
        filter.data("page", 0);
        filter.data("filterName", $(".filter-name", filter).val());
        searchForBusinesses();
    }

    function searchForBusinesses()
    {
        $.getJSON("/ajax/businesses",
            {
              'page'  : filter.data("page"),
              'count' : filter.data("itemsPerPage"),
              'name'  : filter.data("filterName")
            },
            $.bind(ya, displayBusinessesList, $(".bus-sel-list", results))
        );
    }

    function displayBusinessesList(itemsHolder, data)
    {
        var total = data.total;
        var items = data.items;

        itemsHolder.empty();
        $.each(items, function ()
            {
                itemsHolder.append(ya.createBusinessItem(this));
            }
        );
        if ( total <= filter.data("itemsPerPage") )
        {
            $(".bus-sel-nav").hide();
        }
        else
        {
            $(".bus-sel-nav").show();
            var lastPage = Math.ceil(total / 10) - 1;
            if ( lastPage <= filter.data("page") )
            {
                $(".bus-sel-next", results).hide();
            }
            else
            {
                $(".bus-sel-next", results).show();
            }
            if ( filter.data("page") == 0 )
            {
                $(".bus-sel-prev", results).hide();
            }
            else
            {
                $(".bus-sel-prev", results).show();
            }
        }
    }

    function createBusinessItem(info)
    {
        var holder = $("<li class='bus-sel-item'></li>");
        var isAdded = isItemAdded(info);
        if ( isAdded )
        {
            holder.addClass("bus-sel-item-selected");
        }
        var header = $("<h4></h4>");
        var n = [info.name];
        if ( info.form )
        {
            n[n.length] = info.form;
        }
        if ( info.legal_name )
        {
            n[n.length] = info.legal_name;
        }
        header.text(n.join(', '));
        header.append($("<span></span>").text("(#" + info.id + ")"));
        holder.append(header);
        holder.data("item", info);
        holder.append(info.address);

        holder.hover(ya.itemOver, ya.itemOut);
        if ( isAdded )
        {
            holder.click(function () {
                    ya.itemRemove($(this).data("item"));
                }
            );
        }
        else
        {
            holder.click( function () {
                    ya.itemAdd($(this).data("item"));
                }
            );
        }
        return holder;
    }

    function createSelectedBusinessItem(info)
    {
        var holder = $("<li class='bus-sel-item'></li>");
        var header = $("<h4></h4>");
        var input  = $("<input type='hidden' />");
        var del    = $("<a href='#' class='bus-sel-remove'>удалить</a>");
        input.attr("name", fieldName + "[]");
        input.val(info.id);

        var n = [info.name];
        if ( info.form )
        {
            n[n.length] = info.form;
        }
        if ( info.legal_name )
        {
            n[n.length] = info.legal_name;
        }
        header.text(n.join(', '));
        header.append($("<span></span>").text("(#" + info.id + ")"));
        holder.append(header);
        holder.append(input);
        holder.data("item", info);
        holder.append(info.address);
        del.click( function () {
                ya.itemRemove($(this).parent().data("item"));
                return false;
            }
        );
        holder.append(del);
        holder.hover(ya.itemOver, ya.itemOut);
        return holder;
    }

    function itemOver()
    {
        $(this).addClass("bus-sel-item-hover");
    }

    function itemOut()
    {
        $(this).removeClass("bus-sel-item-hover");
    }

    function isItemAdded(info)
    {
        return (findItem(selected, info.id) !== null || $.inArray(info.id, exclude) >= 0);
    }

    function itemAdd(info)
    {
        if ( !isItemAdded(info) 
            && (ya.maxSelected == -1 || ya.maxSelected > getAddedCount()) )
        {
            selected.append(ya.createSelectedBusinessItem(info));
            var elem = findItem(results, info.id);
            if ( elem )
            {
                $(elem).replaceWith(ya.createBusinessItem(info));
            }
        }
    }

    function getAddedCount()
    {
        return $("li", selected).length;
    }
    
    function findItem(holder, id)
    {
        var items = $("li", holder).get();
        for ( var i = 0; i < items.length; i++)
        {
            if ($(items[i]).data("item").id == id )
            {
               return items[i];
            }
        }
        return null;
    }

    function itemRemove(info)
    {
        var id = info.id;
        var data = info;
        var selItem = findItem(selected, id);
        if ( selItem )
        {
            $(selItem).remove();
        }
        var item = findItem($(".bus-sel-list", results), id);
        if ( item )
        {
            $(item).replaceWith(ya.createBusinessItem(data));
        }
    }

    function nextPage()
    {
        filter.data("page", filter.data("page") + 1);
        searchForBusinesses();
        return false;
    }

    function prevPage()
    {
        filter.data("page", filter.data("page") - 1);
        searchForBusinesses();
        return false;
    }

    function getSelectedItems()
    {
        return $("li", selected);
    }
    
    this.newSearch  = newSearch;
    this.itemAdd    = itemAdd;
    this.nextPage   = nextPage;
    this.prevPage   = prevPage;
    this.itemOver   = itemOver;
    this.itemOut    = itemOut;
    this.itemRemove = itemRemove;
    this.getSelectedItems = getSelectedItems;
    this.createBusinessItem = createBusinessItem;
    this.createSelectedBusinessItem = createSelectedBusinessItem;
    this.getAddedCount = getAddedCount;
    this.maxSelected = -1;

    filter
        .data("page", 0)
        .data("itemsPerPage", 10)
        .data("filterName", "");
    $(".filter-name", filter).keydown(function (event) {
            if ( event.keyCode == 13 )
            {
                newSearch();
                return false;
            }
        }
    );
    $(".filter-search", filter).click(newSearch);
    $(".bus-sel-next", results).click(ya.nextPage);
    $(".bus-sel-prev", results).click(ya.prevPage);
}

