(function () {
    window.easyUtils = window.easyUtils || {};

    var $input;
    window.easyUtils.autocomplete = function (targetSelector, callback) {
        $input = $(targetSelector);
        var timeout = null;
        var submit = function () {
            callback();
        };
        $input.on('input', function () {
            if (timeout !== null) {
                window.clearTimeout(timeout);
            }
            timeout = window.setTimeout(submit, 300);
        });
    };
})();


function easyAutocomplete(name, sourceOrLoadPath, onchange, rootElement, options) {
    if (typeof options === "undefined") {
        options = {};
    }
    var hiddenInput = $('#' + name);
    var source;
    if (typeof(sourceOrLoadPath) === 'string') {
        source = function (request, response) {
            $.getJSON(sourceOrLoadPath, {
                term: request.term
            }, function (json) {
                response(rootElement ? json[rootElement] : json);
            });
        };
    } else {
        source = sourceOrLoadPath;
    }
    var ac = $('#' + name + '_autocomplete').autocomplete({
        source: source,
        minLength: 0,
        select: function (event, ui) {
            $(this).val(ui.item.value);
            hiddenInput.val(ui.item.id);
            if (typeof(onchange) === 'function') {
                onchange(event, ui);
            }
            hiddenInput.change();
            return false;
        },
        change: function (event, ui) {
            if (!ui.item) {
                $(this).val('');
                hiddenInput.val('');
                if (typeof(onchange) === 'function') {
                    onchange(event, ui);
                }
                hiddenInput.change();
            }
        },
        position: (options['position'] || {
            collision: "flip"
        }),
        autoFocus: options['auto_focus'] !== false
    }).css('margin-right', 0).click(function () {
        $(this).select();
    });

    if (typeof(onchange) === 'function') {
        $.data(ac[0], 'ac_onchange_callback', onchange);
    }

    if (options['activate_on_input_click']) {
        ac.on('click', function () {
            ac.focus().val('');
            ac.trigger('keydown');
            ac.autocomplete("search", "");
        });
    }

    if (!options['no_button']) {
        $("<button type='button'>&nbsp;</button>")
            .attr("tabIndex", -1)
            .attr("title", $('#' + name + '_autocomplete').attr("title"))
            .insertAfter(ac)
            .button({
                icons: {
                    primary: "ui-icon-triangle-1-s"
                },
                text: false
            })
            .removeClass("ui-corner-all")
            .addClass("ui-corner-right ui-button-icon")
            .css('font-size', '10px')
            .css('margin-left', -1)
            .click(function () {
                if (ac.autocomplete("widget").is(":visible")) {
                    ac.autocomplete("close");
                    ac.blur();
                    return;
                }
                $(this).blur();
                ac.focus().val('');
                ac.autocomplete("search", "");
            });
    }
    return ac;
}

function initEasyAutocomplete() {
    if (isIE()) {
        $(".easy-autocomplete-tag").addClass("IE-ui-autocomplete-input").find('input').addClass("ui-autocomplete-input");
        $(document).on("click, blur, focus, mouseover", ".easy-autocomplete-tag[data-easy-autocomplete]", function (event) {
            var t = $(this);
            t.closest('.IE-ui-autocomplete-input').removeClass('IE-ui-autocomplete-input').find('input').removeClass("ui-autocomplete-input");
            initEasyAutocompleteFor(t);
        });
    } else {
        $(".easy-autocomplete-tag[data-easy-autocomplete]").each(function (index, item) {
            initEasyAutocompleteFor($(item));
        });
    }
}

function initEasyAutocompleteFor(item) {
    if ($(item).data().autocompleteLoaded) {
        // skip
    } else {
        eval($.base64.decode($(item).data().easyAutocomplete, true));
        $(item).data().autocompleteLoaded = true;
    }
}

function initEasyInlineEdit() {
    $('.multieditable-container:not(.multieditable-initialized)').each(function () {
        initInlineEditForContainer(this);
    });
}

$(document).ready(initEasyAutocomplete);

function removeAutocompleteFromMultiselectTag(id, default_value, input_name) {
    $('input[name="' + input_name + '"]').remove();
    var element = $('#' + id + '_autocomplete');
    element.autocomplete({
        select: function () {
        }, change: function () {
        }
    });
    element.attr('id', id);
    element.attr('name', input_name);
    element.change(function () {
        element.attr('value', $("#" + id + ".ui-autocomplete-input").val());
    });
    element.parent().next().hide();
    element.val(default_value);
}

function easyComboboxTag(id, name, possibleValues, selectedValues, default_value) {
    easyMultiselectTag(id, name, possibleValues, selectedValues, false);
    removeAutocompleteFromMultiselectTag(id, default_value, name);
}

function easyMultiselectTag(id, name, possibleValues, selectedValues, show_toggle_button, options) {
    if (typeof options === "undefined") {
        options = {};
    }
    var entities,
        entityArray = $('#' + id + '_entity_array'),
        ac = $('#' + id + '_autocomplete');

    if (show_toggle_button) {
        var link_ac_toggle = $('<a>').attr('class', 'icon-add clear-link');
        var option;
        var select;
        link_ac_toggle.click(function () {
            select = $('<select>').prop('multiple', true).prop('size', 5).prop('name', name);
            $.each(possibleValues, function (i, v) {
                option = $('<option>').prop('value', v.id).text(v.value);
                option.prop('selected', selectedValues.indexOf(v.id) > -1);
                select.append(option);
            });
            $(this).closest('.easy-multiselect-tag-container').html(select);
            return false;
        });
        ac.parent().addClass('input-append');
        ac.after(link_ac_toggle);
    }

    entities = $.map(possibleValues, function (val) {
        if (selectedValues && (selectedValues.indexOf(val.id) > -1) || (selectedValues.indexOf(val.id.toString()) > -1)) {
            return {
                id: val.id,
                name: val.value
            };
        }
    });

    entityArray.entityArray({
        inputNames: name,
        entities: entities,
        afterRemove: function (entity) {
            ac.trigger('change');
        }
    });

    ac.autocomplete($.extend({}, {
        source: function (request, response) {
            var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
            response($.map(possibleValues, function (val) {
                if (!request.term || matcher.test(val.value)) {
                    return val;
                }
            }));
        },
        minLength: 0,
        select: function (event, ui) {
            entityArray.entityArray('add', {
                id: ui.item.id,
                name: ui.item.value
            });
            ac.trigger('change');
            return false;
        },
        change: function (event, ui) {
            if (!ui.item) {
                $(this).val('');
            }
        },
        position: {
            collision: "flip"
        },
        autoFocus: false
    }, (options || {}))).data("ui-autocomplete")._renderItem = function (ul, item) {
        return $("<li>")
            .data("item.autocomplete", item)
            .append(item.label)
            .appendTo(ul);
    };
    $("<button type='button'>&nbsp;</button>")
        .attr("tabIndex", -1)
        .insertAfter(ac)
        .button({
            icons: {
                primary: "ui-icon-triangle-1-s"
            },
            text: false
        })
        .removeClass("ui-corner-all")
        .addClass("ui-corner-right ui-button-icon")
        .css('font-size', '10px')
        .css('margin-left', -1)
        .click(function () {
            if (ac.autocomplete("widget").is(":visible")) {
                ac.autocomplete("close");
                ac.blur();
                return;
            }
            $(this).blur();
            ac.focus().val('');
            ac.trigger('keydown');
            ac.autocomplete("search", "");
        });
}


function setEasyAutoCompleteValue(select_element_id, value_id, value_name) {
    var ac = $('#' + select_element_id + '_autocomplete');
    var sel = $('#' + select_element_id);
    if (ac) {
        ac.val(value_name);
        sel.attr('value', value_id);
        var onchange = $.data(ac[0], 'ac_onchange_callback');
        if (typeof(onchange) === 'function')
            onchange();
    } else {
        sel.attr('value', value_id);
    }
    sel.change();
}
