jQuery(document).ready(function ($) {
    $.fn.extend({
        hiliteOccurrancesOf: function (texts) {
            var i = 0;
            var value = this.text();
            var lvalue = value.toLowerCase();
            var ltexts = $.map(texts, function (v) { return v.toLowerCase(); });
            var parts = [];

            function findNextMatch(subject, startIndex) {
                var match = null;
                var matchIndex = -1;
                for (var i = 0; i < texts.length; i++) {
                    var idx = subject.indexOf(texts[i], startIndex);
                    if (idx != -1 && (matchIndex == -1 || idx < matchIndex)) {
                        match = texts[i];
                        matchIndex = idx;
                    }
                }
                return match == null ? null : { match: match, index: matchIndex };
            }

            while (true) {
                var match = findNextMatch(lvalue, i);
                parts[parts.length] = value.substring(i, match == null ? value.length : match.index);
                if (match == null) {
                    break;
                }
                parts[parts.length] = value.substring(match.index, match.index + match.match.length);
                i = match.index + match.match.length;
            }

            this.empty();
            var self = this;
            $.each(parts, function (i, v) {
                var even = i % 2 == 0;
                self.append($(even ? '<span></span>' : '<b></b>').text(v));
            });

            return this;
        }
    });

    function ProductsAutocompleter(elem, options, autocompleteOptions) {
        var o = $.extend({
            url: 'search_suggest.php',
            data: {}
        }, options || {});
        var acOpts = $.extend({
            fillCallback: function (container, value, query) {
                var product = value.product;
                var category = value.category;
                var cat = $('<li class="category"></li>').text(value.category);
                var prod = $('<li class="product"></li>').text(value.product);
                prod.hiliteOccurrancesOf(value.query);
                container
                    .append($('<ul class="product-suggest-entry"></ul>').append(prod).append(cat));
            },
            textCallback: function (value) {
                return value.product;
            }
        }, autocompleteOptions || {});
        this.elem = $(elem);
        this.options = o;
        this.autocompleteOptions = acOpts;
        this.init();
    }
    $.extend(ProductsAutocompleter.prototype, {
        init: function () {
            var self = this;
            this.elem.data('xtcProductsAutocompleter', this);
            var opts = $.extend({}, this.autocompleteOptions);
            opts.searchCallback = function (query, resultHandler) {
                var data = $.extend(self.options.data, { q: query });
                var callback = function (data) {
                    resultHandler.call(window, data);
                };
                $.get(self.options.url, data, callback, 'json');
            };
            this.elem.autocomplete(opts);
        }
    });

    $.fn.extend({
        xtcAutocompleteProducts: function (options, autocompleteOptions) {
            new ProductsAutocompleter(this, options, autocompleteOptions);
            return this;
        }
    });

    $('#quicksearch-keywords').xtcAutocompleteProducts();
});

