var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
(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 });
    exports.AtomList = void 0;
    var AtomBinder_1 = require("./AtomBinder");
    /**
     *
     *
     * @export
     * @class AtomList
     * @extends {Array<T>}
     * @template T
     */
    var AtomList = /** @class */ (function (_super) {
        __extends(AtomList, _super);
        // private version: number = 1;
        function AtomList() {
            var _this = _super.call(this) || this;
            _this.startValue = 0;
            _this.totalValue = 0;
            _this.sizeValue = 10;
            // tslint:disable-next-line
            _this["__proto__"] = AtomList.prototype;
            _this.next = function () {
                _this.start = _this.start + _this.size;
            };
            _this.prev = function () {
                if (_this.start >= _this.size) {
                    _this.start = _this.start - _this.size;
                }
            };
            return _this;
        }
        Object.defineProperty(AtomList.prototype, "start", {
            get: function () {
                return this.startValue;
            },
            set: function (v) {
                if (v === this.startValue) {
                    return;
                }
                this.startValue = v;
                AtomBinder_1.AtomBinder.refreshValue(this, "start");
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(AtomList.prototype, "total", {
            get: function () {
                return this.totalValue;
            },
            set: function (v) {
                if (v === this.totalValue) {
                    return;
                }
                this.totalValue = v;
                AtomBinder_1.AtomBinder.refreshValue(this, "total");
            },
            enumerable: false,
            configurable: true
        });
        Object.defineProperty(AtomList.prototype, "size", {
            get: function () {
                return this.sizeValue;
            },
            set: function (v) {
                if (v === this.sizeValue) {
                    return;
                }
                this.sizeValue = v;
                AtomBinder_1.AtomBinder.refreshValue(this, "size");
            },
            enumerable: false,
            configurable: true
        });
        /**
         * Adds the item in the list and refresh bindings
         * @param {T} item
         * @returns {number}
         * @memberof AtomList
         */
        AtomList.prototype.add = function (item) {
            var i = this.length;
            var n = this.push(item);
            AtomBinder_1.AtomBinder.invokeItemsEvent(this, "add", i, item);
            AtomBinder_1.AtomBinder.refreshValue(this, "length");
            // this.version++;
            return n;
        };
        /**
         * Add given items in the list and refresh bindings
         * @param {Array<T>} items
         * @memberof AtomList
         */
        AtomList.prototype.addAll = function (items) {
            for (var _i = 0, items_1 = items; _i < items_1.length; _i++) {
                var item = items_1[_i];
                var i = this.length;
                this.push(item);
                AtomBinder_1.AtomBinder.invokeItemsEvent(this, "add", i, item);
                AtomBinder_1.AtomBinder.refreshValue(this, "length");
            }
            // tslint:disable-next-line:no-string-literal
            var t = items["total"];
            if (t) {
                this.total = t;
            }
            // this.version++;
        };
        /**
         * Replaces list with given items, use this
         * to avoid flickering in screen
         * @param {T[]} items
         * @memberof AtomList
         */
        AtomList.prototype.replace = function (items, start, size) {
            this.length = items.length;
            for (var i = 0; i < items.length; i++) {
                this[i] = items[i];
            }
            this.refresh();
            // tslint:disable-next-line:no-string-literal
            var t = items["total"];
            if (t) {
                this.total = t;
            }
            if (start !== undefined) {
                this.start = start;
            }
            if (size !== undefined) {
                this.size = size;
            }
        };
        /**
         * Inserts given number in the list at position `i`
         * and refreshes the bindings.
         * @param {number} i
         * @param {T} item
         * @memberof AtomList
         */
        AtomList.prototype.insert = function (i, item) {
            var n = this.splice(i, 0, item);
            AtomBinder_1.AtomBinder.invokeItemsEvent(this, "add", i, item);
            AtomBinder_1.AtomBinder.refreshValue(this, "length");
        };
        /**
         * Removes item at given index i and refresh the bindings
         * @param {number} i
         * @memberof AtomList
         */
        AtomList.prototype.removeAt = function (i) {
            var item = this[i];
            this.splice(i, 1);
            AtomBinder_1.AtomBinder.invokeItemsEvent(this, "remove", i, item);
            AtomBinder_1.AtomBinder.refreshValue(this, "length");
        };
        /**
         * Removes given item or removes all items that match
         * given lambda as true and refresh the bindings
         * @param {(T | ((i:T) => boolean))} item
         * @returns {boolean} `true` if any item was removed
         * @memberof AtomList
         */
        AtomList.prototype.remove = function (item) {
            if (item instanceof Function) {
                var index = 0;
                var removed = false;
                for (var _i = 0, _a = this; _i < _a.length; _i++) {
                    var it = _a[_i];
                    if (item(it)) {
                        this.removeAt(index);
                        removed = true;
                        continue;
                    }
                    index++;
                }
                return removed;
            }
            var n = this.indexOf(item);
            if (n !== -1) {
                this.removeAt(n);
                return true;
            }
            return false;
        };
        /**
         * Removes all items from the list and refreshes the bindings
         * @memberof AtomList
         */
        AtomList.prototype.clear = function () {
            this.length = 0;
            this.refresh();
        };
        AtomList.prototype.refresh = function () {
            AtomBinder_1.AtomBinder.invokeItemsEvent(this, "refresh", -1, null);
            AtomBinder_1.AtomBinder.refreshValue(this, "length");
            // this.version++;
        };
        AtomList.prototype.watch = function (f, wrap) {
            if (wrap) {
                var fx_1 = f;
                f = (function () {
                    var p = [];
                    // tslint:disable-next-line:prefer-for-of
                    for (var i = 0; i < arguments.length; i++) {
                        var iterator = arguments[i];
                        p.push(iterator);
                    }
                    return fx_1.call(this, p);
                });
            }
            return AtomBinder_1.AtomBinder.add_CollectionChanged(this, f);
        };
        return AtomList;
    }(Array));
    exports.AtomList = AtomList;
    // tslint:disable
    Array.prototype["add"] = AtomList.prototype.add;
    Array.prototype["addAll"] = AtomList.prototype.addAll;
    Array.prototype["clear"] = AtomList.prototype.clear;
    Array.prototype["refresh"] = AtomList.prototype.refresh;
    Array.prototype["remove"] = AtomList.prototype.remove;
    Array.prototype["removeAt"] = AtomList.prototype.removeAt;
    Array.prototype["watch"] = AtomList.prototype.watch;
    Array.prototype["replace"] = AtomList.prototype.replace;
    Array.prototype["insert"] = AtomList.prototype.insert;
});
//# sourceMappingURL=AtomList.js.map