var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
import { bindable, bindingMode, customAttribute, ViewSlot, ViewCompiler, Container, createOverrideContext, BindingEngine, autoinject, TaskQueue } from "aurelia-framework";
import 'select2';
import { GridDataSource } from "../../data/data-source";
import { Datacontext } from "../../data/data-context";
import { I18N } from "aurelia-i18n";
import { UIInternal } from "./../../utils/ui-internal";
function createCustomSelect2DataAdapter() {
    var AjaxAdapter = jQuery.fn.select2.amd.require('select2/data/ajax');
    var Utils = jQuery.fn.select2.amd.require('select2/utils');
    function CustomArrayAdapter($element, options) {
        CustomArrayAdapter.__super__.constructor.call(this, $element, options);
    }
    ;
    Utils.Extend(CustomArrayAdapter, AjaxAdapter);
    CustomArrayAdapter.prototype.select = function (data) {
        var $option = this.$element.find('option').filter(function (i, elm) {
            return elm.value == data.id.toString();
        });
        if ($option.length === 0) {
            $option = this.option(data);
            this.addOptions($option);
        }
        CustomArrayAdapter.__super__.select.call(this, data);
    };
    CustomArrayAdapter.prototype.unselect = function (data) {
        data._addedOn = undefined;
        return CustomArrayAdapter.__super__.unselect.call(this, data);
    };
    return CustomArrayAdapter;
}
export var Select2Attribute = (function () {
    function Select2Attribute(element, viewCompiler, container, datacontext, i18n, bindingEngine, taskQueue) {
        this.element = element;
        this.viewCompiler = viewCompiler;
        this.container = container;
        this.datacontext = datacontext;
        this.i18n = i18n;
        this.bindingEngine = bindingEngine;
        this.taskQueue = taskQueue;
        this.dataSource = null;
        this.pageSize = 25;
    }
    Select2Attribute.prototype.attached = function () {
        var _this = this;
        if (this.select) {
            return;
        }
        var options = {};
        this.fillOptions(options);
        options.language = {
            errorLoading: function () { return _this.i18n.tr("select2.errorLoading", { ns: "common" }); },
            inputTooShort: function () { return _this.i18n.tr("select2.inputTooShort", { ns: "common" }); },
            loadingMore: function () { return _this.i18n.tr("select2.loadingMore", { ns: "common" }); },
            noResults: function () { return _this.i18n.tr("select2.noResults", { ns: "common" }); },
            searching: function () { return _this.i18n.tr("select2.searching", { ns: "common" }); }
        };
        this.select = $(this.element).select2(options);
        this.select2Container = this.select.data("select2").$container;
        var $el = $(this.element);
        var $containerSelection = $el.data("select2").$selection;
        if (this.value != null && Object.keys(this.value).length > 0 && Object.keys(this.value).indexOf('id') > -1) {
            this.select.val(this.value.id + "").trigger("change");
        }
        else {
            this.select.val(this.value).trigger("change");
        }
        if (Array.isArray(this.value)) {
            var observer = this.bindingEngine.collectionObserver(this.value);
            observer.subscribe(function () {
                var _a;
                (_a = _this.select) === null || _a === void 0 ? void 0 : _a.val(_this.value).trigger("change");
            });
        }
        this.synchronizeClasses();
        this.select.on("select2:unselect", function (event) {
            if (event.originalEvent) {
                return;
            }
            var data = event.params.data;
            var targetHTMLElt = event.target;
            if (Array.isArray(_this.value)) {
                if (_this.value.some(function (x) { return x == data.id; })) {
                    var index = _this.value.findIndex(function (x) { return x == data.id; });
                    _this.value.splice(index, 1);
                }
            }
            else {
                if (_this.value == data.id) {
                    _this.value = null;
                }
                else if (Object.keys(_this.value).length > 0 && Object.keys(_this.value).indexOf('id') > -1 && _this.value.id == data.id) {
                    _this.value = null;
                }
            }
            window.dispatchEvent(UIInternal.createEvent("select2:change"));
        });
        this.select.on("select2:select", function (event) {
            if (event.originalEvent) {
                return;
            }
            if (Array.isArray(_this.value)) {
                var data = event.params.data;
                _this.value.push(data.id);
            }
            else {
                var targetHTMLElt = event.target;
                if (_this.value != null && Object.keys(_this.value).length > 0 && Object.keys(_this.value).indexOf('id') > -1) {
                    _this.value = { id: event.params.data.id.toString(), text: event.params.data.text };
                }
                else {
                    if (_this.value != targetHTMLElt.value) {
                        var numberValue = Number(targetHTMLElt.value);
                        if (!Number.isNaN(numberValue))
                            _this.value = numberValue;
                        else
                            _this.value = targetHTMLElt.value;
                    }
                }
            }
            window.dispatchEvent(UIInternal.createEvent("select2:change"));
        });
        $(document).on('focus', '.select2-selection.select2-selection--single', function (e) {
            $(this).closest(".select2-container").siblings('select:enabled').select2('open');
        });
        this.select.on('select2:closing', function (e) {
            $(e.target).data("select2").$selection.one('focus focusin', function (e) {
                e.stopPropagation();
            });
        });
        this.select.on('select2:open', function (e) {
            var _a;
            if (e.currentTarget.tagName.toUpperCase() == 'SELECT') {
                (_a = $('.select2-search--dropdown input.select2-search__field').get(0)) === null || _a === void 0 ? void 0 : _a.focus();
                $('.select2-search--dropdown input.select2-search__field').trigger('focus');
                setTimeout(function () {
                    var _a;
                    (_a = $('.select2-search--dropdown input.select2-search__field').get(0)) === null || _a === void 0 ? void 0 : _a.focus();
                    $('.select2-search--dropdown input.select2-search__field').trigger('focus');
                }, 0);
            }
        });
        this.startClassesSyncObserver();
        if (this.createOptions != null) {
            var select2Instance = this.select.data("select2");
            var $dropdown = select2Instance.$dropdown.children().first();
            this.removeFn = this.insert($dropdown.get(0), "<template><span click.trigger='addFn()' class='select2-create-button' if.bind='canAdd'><ui-icon icon='digi-plus-circle'></ui-icon><span t='" + this.createOptions.label + "'></span></span></template>", this);
        }
    };
    Object.defineProperty(Select2Attribute.prototype, "canAdd", {
        get: function () {
            if (this.createOptions.enabled == null)
                return true;
            if (this.createOptions.enabled === false || this.createOptions.enabled === true)
                return this.createOptions.enabled;
            return this.createOptions.enabled();
        },
        enumerable: false,
        configurable: true
    });
    Select2Attribute.prototype.addFn = function () {
        $(this.element).select2("close");
        if (this.createOptions.this == null) {
            this.createOptions.this = this.element.au.select2.scope.bindingContext;
        }
        this.createOptions.fn.call(this.createOptions.this);
    };
    Select2Attribute.prototype.insert = function (containerElement, html, viewModel) {
        var viewFactory = this.viewCompiler.compile(html);
        var view = viewFactory.create(this.container);
        var anchorIsContainer = true;
        var viewSlot = new ViewSlot(containerElement, anchorIsContainer);
        viewSlot.add(view);
        view.bind(viewModel, createOverrideContext(viewModel));
        return function () {
            viewSlot.remove(view);
            view.unbind();
        };
    };
    Select2Attribute.prototype.valueChanged = function (newVal, oldVal) {
        var _this = this;
        if (this.select) {
            $(this.element).find('*').each(function () {
                $.removeData(this, 'data');
            });
            if (this.value != null && Object.keys(this.value).length > 0 && Object.keys(this.value).indexOf('id') > -1) {
                this.taskQueue.queueMicroTask(function () {
                    _this.select.val(newVal.id).trigger("change");
                });
            }
            else {
                if (newVal == null)
                    this.select.val('').trigger("change");
                else if (newVal == "0") {
                    this.select.val(null).trigger("change");
                }
                else {
                    this.select.val(newVal).trigger("change");
                }
            }
        }
    };
    Select2Attribute.prototype.detached = function () {
        if (this.removeFn != null) {
            this.removeFn();
        }
        if (this.select) {
            this.select.off("change");
            this.select.off('select2:select');
            this.select.off('select2:unselect');
            this.select.off('select2:open');
            this.select.select2("destroy");
        }
        this.select = null;
        if (this.observer != null) {
            this.observer.disconnect();
            this.observer = null;
        }
    };
    Select2Attribute.prototype.addHiddenDivToBody = function () {
        var div = document.createElement("div");
        div.style.display = "none";
        document.body.appendChild(div);
        return div;
    };
    Select2Attribute.prototype.getValue = function (item, propertyPath) {
        var sepIndex = propertyPath.indexOf('.');
        if (sepIndex > -1) {
            var leftPart = propertyPath.substring(0, sepIndex);
            var rightPart = propertyPath.substr(sepIndex + 1);
            return this.getValue(item[leftPart], rightPart);
        }
        else {
            return item[propertyPath];
        }
    };
    Select2Attribute.prototype.fillOptions = function (options) {
        var _this = this;
        if (this.dataSource != null) {
            var ds = this.dataSource;
            var templateSelectionFunction = null;
            var minimumInputLength = 0;
            $.extend(options, {
                ajax: {
                    dataType: 'json',
                    delay: 250,
                    data: function (params) {
                        return {
                            q: params.term,
                            page: params.page
                        };
                    },
                    processResults: function (data, page) {
                        var cleanData = data.results.map(function (item) {
                            if (_this.optionsValue != null && _this.optionsText != null) {
                                return {
                                    id: item[_this.optionsValue],
                                    text: _this.getValue(item, _this.optionsText),
                                    data: item
                                };
                            }
                        });
                        return {
                            results: cleanData,
                            pagination: {
                                more: data.more
                            }
                        };
                    },
                    transport: function (params, success, failure) {
                        var fail = function () { };
                        var currentPage = params.data.page != null ? params.data.page : 1;
                        var startRow = (currentPage - 1) * _this.pageSize;
                        var endRow = startRow + _this.pageSize;
                        var callBack = function (rowsThisPage, lastRow) {
                            var data = {
                                results: rowsThisPage,
                                more: lastRow > endRow
                            };
                            success(data);
                        };
                        var p = {
                            startRow: startRow,
                            endRow: endRow,
                            successCallback: callBack,
                            failCallback: failure,
                            sortModel: [
                                { colId: _this.replaceTranslation(_this.optionsText), sort: 'ASC' }
                            ]
                        };
                        var sortModel = _this.getSortModelFromSortColumn(_this.sortColumn);
                        if (sortModel != null && sortModel.length > 0) {
                            p.sortModel = sortModel;
                        }
                        ds.getRowsForSelect2(p, params.data.q, _this.evalFilterProperties);
                        return ds;
                    }
                },
                escapeMarkup: function (markup) { return markup; },
                minimumInputLength: minimumInputLength,
                dataAdapter: createCustomSelect2DataAdapter()
            });
            if (this.templateResultFn != null) {
                options.templateResult = this.templateResultFn;
            }
            if (templateSelectionFunction != null) {
                options.templateSelection = templateSelectionFunction;
            }
        }
    };
    Object.defineProperty(Select2Attribute.prototype, "evalFilterProperties", {
        get: function () {
            var _this = this;
            if (this.filterProperties != null && this.filterProperties.length > 0) {
                var filterProperties = eval(this.filterProperties);
                return filterProperties.map(function (x) { return _this.replaceTranslation(x); });
            }
            return [];
        },
        enumerable: false,
        configurable: true
    });
    Select2Attribute.prototype.getSortModelFromSortColumn = function (sortColumn) {
        var _this = this;
        if (sortColumn == null || sortColumn.length == 0)
            return null;
        var sortModel = [];
        if (sortColumn.indexOf(',') > -1) {
            var sortColumns = sortColumn.split(',');
            sortColumns.forEach(function (col) {
                sortModel.push({
                    colId: _this.replaceTranslation(col),
                    sort: _this.getSortDirection(col)
                });
            });
        }
        else {
            sortModel.push({
                colId: this.replaceTranslation(sortColumn),
                sort: this.getSortDirection(sortColumn)
            });
        }
        return sortModel;
    };
    Select2Attribute.prototype.getSortDirection = function (col) {
        if (col.indexOf(' ') > -1) {
            return col.split(' ')[1];
        }
        else
            return 'ASC';
    };
    Select2Attribute.prototype.replaceTranslation = function (col) {
        if (col.indexOf('_translation') > -1) {
            return col.replace('_translation', this.datacontext.translatePropertyName);
        }
        return col;
    };
    Select2Attribute.prototype.synchronizeClasses = function () {
        var sourceClassList = this.element.classList;
        var containerClassList = this.select2Container.get(0).classList;
        for (var i = 0; i < containerClassList.length; i++) {
            var className = containerClassList[i];
            if (!className.startsWith("select2")) {
                if (!sourceClassList.contains(className)) {
                    this.select2Container.removeClass(className);
                }
            }
        }
        for (var i = 0; i < sourceClassList.length; i++) {
            var className = sourceClassList[i];
            if (!className.startsWith("select2")) {
                if (!containerClassList.contains(className)) {
                    this.select2Container.addClass(className);
                }
            }
        }
    };
    Select2Attribute.prototype.startClassesSyncObserver = function () {
        var _this = this;
        this.observer = new MutationObserver(function (mutations) {
            mutations.forEach(function (mutation) {
                if (mutation.attributeName == "class") {
                    _this.synchronizeClasses();
                }
            });
        });
        var config = { attributes: true };
        this.observer.observe(this.element, config);
    };
    __decorate([
        bindable({ defaultBindingMode: bindingMode.twoWay }),
        __metadata("design:type", Object)
    ], Select2Attribute.prototype, "value", void 0);
    __decorate([
        bindable({ defaultBindingMode: bindingMode.oneTime }),
        __metadata("design:type", GridDataSource)
    ], Select2Attribute.prototype, "dataSource", void 0);
    __decorate([
        bindable({ defaultBindingMode: bindingMode.oneTime }),
        __metadata("design:type", String)
    ], Select2Attribute.prototype, "optionsValue", void 0);
    __decorate([
        bindable({ defaultBindingMode: bindingMode.oneTime }),
        __metadata("design:type", String)
    ], Select2Attribute.prototype, "optionsText", void 0);
    __decorate([
        bindable({ defaultBindingMode: bindingMode.oneTime }),
        __metadata("design:type", Object)
    ], Select2Attribute.prototype, "createOptions", void 0);
    __decorate([
        bindable({ defaultBindingMode: bindingMode.oneTime }),
        __metadata("design:type", String)
    ], Select2Attribute.prototype, "sortColumn", void 0);
    __decorate([
        bindable({ defaultBindingMode: bindingMode.oneTime }),
        __metadata("design:type", String)
    ], Select2Attribute.prototype, "filterProperties", void 0);
    __decorate([
        bindable({ defaultBindingMode: bindingMode.oneTime }),
        __metadata("design:type", Function)
    ], Select2Attribute.prototype, "templateResultFn", void 0);
    Select2Attribute = __decorate([
        customAttribute("select2"),
        autoinject,
        __metadata("design:paramtypes", [Element, ViewCompiler, Container, Datacontext, I18N, BindingEngine, TaskQueue])
    ], Select2Attribute);
    return Select2Attribute;
}());

//# sourceMappingURL=select2-attribute.js.map
