var __spreadArrays = (this && this.__spreadArrays) || function () {
    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
    for (var r = Array(s), k = 0, i = 0; i < il; i++)
        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
            r[k] = a[j];
    return r;
};
(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports);
        if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define(["require", "exports", "./AtomBinder"], factory);
    }
})(function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var AtomBinder_1 = require("./AtomBinder");
    var isSelectableItem = {};
    var AtomSelectableList = /** @class */ (function () {
        function AtomSelectableList(allowMultipleSelection, valuePath, labelPath) {
            if (allowMultipleSelection === void 0) { allowMultipleSelection = false; }
            this.allowMultipleSelection = allowMultipleSelection;
            this.valuePath = valuePath;
            this.labelPath = labelPath;
            this.selectedItems = [];
            this.mValue = undefined;
            if (!this.valuePath) {
                this.valuePath = function (x) { return x; };
            }
            if (!this.labelPath) {
                this.labelPath = function (x) { return x.label || x; };
            }
            this.items = [];
        }
        Object.defineProperty(AtomSelectableList.prototype, "selectedIndex", {
            get: function () {
                if (this.selectedItems.length) {
                    return this.items.indexOf(this.selectedItems[0]);
                }
                return -1;
            },
            set: function (n) {
                this.selectedItems.clear();
                if (n === -1) {
                    this.updateBindings(true);
                    return;
                }
                this.selectedItems.add(this.items[n]);
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(AtomSelectableList.prototype, "selectedItem", {
            get: function () {
                if (!this.selectedItems.length) {
                    return null;
                }
                var s = this.selectedItems[0];
                return s ? s.item : null;
            },
            set: function (item) {
                this.selectedItems.clear();
                if (!item) {
                    this.updateBindings(true);
                    return;
                }
                var si = this.items.find(function (s) { return s.item === item; });
                si.select();
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(AtomSelectableList.prototype, "label", {
            get: function () {
                var _this = this;
                var labels = this.selectedItems.map(function (x) { return _this.labelPath(x.item); });
                if (this.allowMultipleSelection) {
                    return labels;
                }
                return labels[0] || null;
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(AtomSelectableList.prototype, "selectAll", {
            get: function () {
                if (this.items.length) {
                    return this.items.length === this.selectedItems.length;
                }
                return false;
            },
            set: function (v) {
                var _a;
                if (v) {
                    (_a = this.selectedItems).splice.apply(_a, __spreadArrays([0, this.selectedItems.length], this.items));
                }
                else {
                    this.selectedItems.clear();
                }
                AtomBinder_1.AtomBinder.refreshItems(this.selectedItems);
                for (var _i = 0, _b = this.items; _i < _b.length; _i++) {
                    var iterator = _b[_i];
                    AtomBinder_1.AtomBinder.refreshValue(iterator, "selected");
                }
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(AtomSelectableList.prototype, "value", {
            get: function () {
                var _this = this;
                if (this.allowMultipleSelection && this.items.length) {
                    return this.selectedItems.map(function (x) { return _this.valuePath(x.item); });
                }
                if (this.selectedItems.length) {
                    return this.valuePath(this.selectedItems[0].item);
                }
                return this.mValue;
            },
            set: function (v) {
                this.mValue = v;
                if (!this.allowMultipleSelection) {
                    v = [v];
                }
                var va = v;
                this.replaceSelectedInternal(va, false);
            },
            enumerable: false,
            configurable: true
        });
        /**
         * Remove all items
         * @param clearValue clear Selection
         */
        AtomSelectableList.prototype.clear = function (clearValue) {
            if (clearValue === void 0) { clearValue = false; }
            if (clearValue) {
                this.replaceSelectedInternal([], false);
            }
            this.items.clear();
        };
        /**
         * Append to existing items
         * @param source source items
         * @param total total number of items
         */
        AtomSelectableList.prototype.append = function (source, total) {
            var _this = this;
            var values = this.value;
            if (!this.allowMultipleSelection) {
                values = [values];
            }
            var map = source.map(function (x) {
                var item = _this.newItem(x);
                if (values && values.length) {
                    var v_1 = _this.valuePath(x);
                    if (values.find(function (v1) { return v1 === v_1; })) {
                        item.selected = true;
                    }
                }
                return item;
            });
            this.total = total;
            this.items.addAll(map);
            this.mValue = undefined;
            this.updateBindings(true);
        };
        AtomSelectableList.prototype.replace = function (source, start, size) {
            var _this = this;
            var values = this.value;
            if (!this.allowMultipleSelection) {
                values = [values];
            }
            this.selectedItems.clear();
            var map = source.map(function (x) {
                var item = _this.newItem(x);
                if (values && values.length) {
                    var v_2 = _this.valuePath(x);
                    if (values.find(function (v1) { return v1 === v_2; })) {
                        item.selected = true;
                    }
                }
                return item;
            });
            var a = source;
            if (a.total) {
                map.total = a.total;
            }
            this.items.replace(map, start, size);
            this.mValue = undefined;
            this.updateBindings(true);
        };
        AtomSelectableList.prototype.find = function (item) {
            var itemF = function (i) { return item(i); };
            if (typeof item !== "function") {
                var e_1 = item;
                itemF = function (i) { return i === e_1; };
            }
            return this.items.find(function (i) { return itemF(i.item); });
        };
        AtomSelectableList.prototype.select = function (item) {
            var i = item;
            if (i.itemType === isSelectableItem) {
                i.select();
                return;
            }
            var si = this.items.find(function (x) { return x.item === item; });
            si.select();
        };
        AtomSelectableList.prototype.deselect = function (item) {
            var i = item;
            if (i.itemType === isSelectableItem) {
                i.deselect();
                return;
            }
            var si = this.items.find(function (x) { return x.item === item; });
            si.deselect();
        };
        AtomSelectableList.prototype.toggle = function (item) {
            var i = item;
            if (i.itemType === isSelectableItem) {
                i.toggle();
                return;
            }
            var si = this.items.find(function (x) { return x.item === item; });
            si.toggle();
        };
        AtomSelectableList.prototype.replaceSelected = function (va) {
            this.replaceSelectedInternal(va, true);
        };
        AtomSelectableList.prototype.replaceSelectedInternal = function (va, refreshValue) {
            var _this = this;
            if (va === void 0) { va = []; }
            if (refreshValue === void 0) { refreshValue = true; }
            var newItems = !va ? [] : this.items.filter(function (x) {
                var vp = _this.valuePath(x.item);
                var existing = va.find(function (y) { return y === vp; });
                return existing ? true : false;
            });
            var s = this.selectedItems.slice();
            this.selectedItems.clear();
            for (var _i = 0, s_1 = s; _i < s_1.length; _i++) {
                var iterator = s_1[_i];
                AtomBinder_1.AtomBinder.refreshValue(iterator, "selected");
            }
            if (newItems.length) {
                this.selectedItems.replace(newItems);
            }
            this.updateBindings(refreshValue);
        };
        AtomSelectableList.prototype.updateBindings = function (refreshValue) {
            if (refreshValue === void 0) { refreshValue = true; }
            // to prevent recursive updates...
            if (refreshValue) {
                AtomBinder_1.AtomBinder.refreshValue(this, "value");
            }
            AtomBinder_1.AtomBinder.refreshValue(this, "label");
            AtomBinder_1.AtomBinder.refreshValue(this, "selectAll");
            AtomBinder_1.AtomBinder.refreshValue(this, "selectedItem");
            AtomBinder_1.AtomBinder.refreshValue(this, "selectedIndex");
        };
        AtomSelectableList.prototype.newItem = function (item) {
            var self = this;
            var newItem = {
                item: item,
                itemType: isSelectableItem,
                select: null,
                deselect: null,
                toggle: null,
                get selected() {
                    var _this = this;
                    return self.selectedItems.find(function (x) { return x === _this; }) ? true : false;
                },
                set selected(v) {
                    if (v) {
                        if (this.selected) {
                            return;
                        }
                        self.clearSelected();
                        self.selectedItems.add(this);
                    }
                    else {
                        self.selectedItems.remove(this);
                    }
                    AtomBinder_1.AtomBinder.refreshValue(this, "selected");
                    self.updateBindings(true);
                }
            };
            newItem.select = function () {
                newItem.selected = true;
            };
            newItem.deselect = function () {
                newItem.selected = false;
            };
            newItem.toggle = function () {
                newItem.selected = !newItem.selected;
            };
            return newItem;
        };
        AtomSelectableList.prototype.clearSelected = function () {
            if (!this.allowMultipleSelection) {
                var si = this.selectedItem;
                this.selectedItems.clear();
                AtomBinder_1.AtomBinder.refreshValue(si, "selected");
            }
        };
        return AtomSelectableList;
    }());
    exports.default = AtomSelectableList;
});
//# sourceMappingURL=AtomSelectableList.js.map