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);
};
var __values = (this && this.__values) || function(o) {
    var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
    if (m) return m.call(o);
    if (o && typeof o.length === "number") return {
        next: function () {
            if (o && i >= o.length) o = void 0;
            return { value: o && o[i++], done: !o };
        }
    };
    throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
var __read = (this && this.__read) || function (o, n) {
    var m = typeof Symbol === "function" && o[Symbol.iterator];
    if (!m) return o;
    var i = m.call(o), r, ar = [], e;
    try {
        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
    }
    catch (error) { e = { error: error }; }
    finally {
        try {
            if (r && !r.done && (m = i["return"])) m.call(i);
        }
        finally { if (e) throw e.error; }
    }
    return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
};
import { computedFrom } from "aurelia-framework";
import { UIInternal } from "./../../utils/ui-internal";
var NODE_ID = 0;
var UITreeModel = (function () {
    function UITreeModel(children, maxNodes, autoCheckable, autoSort) {
        if (maxNodes === void 0) { maxNodes = 0; }
        if (autoCheckable === void 0) { autoCheckable = true; }
        if (autoSort === void 0) { autoSort = true; }
        this.maxNodes = maxNodes;
        this.children = [];
        this.nodes = [];
        this.autoSort = autoSort;
        this.children = children.map(function (child) { return new UITreeNode(child, null, autoCheckable); });
        this.nodes = this.getExpandedTree(this.applyAutoSort(this.children));
    }
    UITreeModel.prototype.applyAutoSort = function (items) {
        if (this.autoSort === true) {
            return items.sortBy('label');
        }
        else if (this.autoSort === false) {
            return items;
        }
        else if (typeof this.autoSort == 'function') {
            return items.sort(this.autoSort);
        }
        return items;
    };
    UITreeModel.prototype.filter = function (query) {
        this.nodes = this.getExpandedTree(this.applyAutoSort(this.filterNodes(this.children, query)));
    };
    UITreeModel.prototype.expandNode = function (nodeId) {
        var _this = this;
        var hierarchy = this.findNodeHierarchy(nodeId, this.nodes);
        hierarchy === null || hierarchy === void 0 ? void 0 : hierarchy.forEach(function (x) {
            if (x.expanded) {
                return;
            }
            var index = _this.nodes.indexOf(x);
            if (index >= 0) {
                _this.toggleExpand(index);
            }
        });
    };
    UITreeModel.prototype.findNodeHierarchy = function (nodeId, nodes) {
        var e_1, _a;
        var _b;
        var node = nodes.find(function (x) { return x.id == nodeId; });
        if (node != null) {
            return [node];
        }
        try {
            for (var nodes_1 = __values(nodes), nodes_1_1 = nodes_1.next(); !nodes_1_1.done; nodes_1_1 = nodes_1.next()) {
                var x = nodes_1_1.value;
                if (((_b = x.children) === null || _b === void 0 ? void 0 : _b.length) == 0) {
                    continue;
                }
                var foundChildren = this.findNodeHierarchy(nodeId, x.children);
                if ((foundChildren === null || foundChildren === void 0 ? void 0 : foundChildren.length) > 0) {
                    foundChildren.splice(0, 0, x);
                    return foundChildren;
                }
            }
        }
        catch (e_1_1) { e_1 = { error: e_1_1 }; }
        finally {
            try {
                if (nodes_1_1 && !nodes_1_1.done && (_a = nodes_1.return)) _a.call(nodes_1);
            }
            finally { if (e_1) throw e_1.error; }
        }
        return null;
    };
    UITreeModel.prototype.toggleExpand = function (index) {
        var node = this.nodes[index];
        if (false == node.isExpandable) {
            return;
        }
        node.expanded = !node.expanded;
        if (node.expanded) {
            var injectedChildren = this.getExpandedTree([node]);
            this.nodes = __spreadArray(__spreadArray(__spreadArray([], __read(this.nodes.slice(0, index)), false), __read(injectedChildren), false), __read(this.nodes.slice(index + 1)), false);
        }
        else {
            var lastIndex = this.nodes.lastIndex(node.id, "parentId");
            while (this.nodes[lastIndex].expanded) {
                lastIndex = this.nodes.lastIndex(this.nodes[lastIndex].id, "parentId");
            }
            this.nodes = __spreadArray(__spreadArray([], __read(this.nodes.slice(0, index + 1)), false), __read(this.nodes.slice(lastIndex + 1)), false);
        }
    };
    UITreeModel.prototype.toggleMore = function (index) {
        var node = this.nodes[index];
        node.showingMore = !node.showingMore;
        var parentIndex = this.nodes.index(node.parentId, "id");
        var injectedChildren = this.applyAutoSort(this.nodes[parentIndex].children);
        if (!node.showingMore) {
            if (injectedChildren.length === 0) {
                injectedChildren.push(new UITreeNode({ id: "node-empty", leaf: true }, node));
            }
            if (this.maxNodes > 0 && injectedChildren.length > this.maxNodes) {
                injectedChildren = __spreadArray([], __read(injectedChildren.slice(0, this.maxNodes)), false);
            }
        }
        this.nodes = __spreadArray(__spreadArray(__spreadArray(__spreadArray([], __read(this.nodes.slice(0, parentIndex + 1)), false), __read(injectedChildren), false), [
            this.nodes[index]
        ], false), __read(this.nodes.slice(index + 1)), false);
    };
    UITreeModel.prototype.getChecked = function () {
        var checked = [];
        this.getCheckedNodes(this.children, checked);
        return checked;
    };
    UITreeModel.prototype.getCheckedNodes = function (nodes, checked) {
        var _this = this;
        nodes.forEach(function (node) {
            if (node.checked === 1) {
                checked.push(node);
            }
            if (node.children) {
                _this.getCheckedNodes(node.childNodes, checked);
            }
        });
    };
    UITreeModel.prototype.getExpandedTree = function (children) {
        var _this = this;
        var nodes = [];
        children.forEach(function (child) {
            nodes.push(child);
            if (child.expanded) {
                nodes.push.apply(nodes, __spreadArray([], __read(_this.getExpandedTree(_this.getChildren(child))), false));
            }
        });
        return nodes;
    };
    UITreeModel.prototype.filterNodes = function (nodes, query) {
        var _this = this;
        var queryNotEmpty = (query || '').length > 0;
        return nodes.filter(function (child) {
            var retVal = _this.nodeMatchesQuery(child, query);
            child.muted = queryNotEmpty && false == retVal;
            if (!child.leaf) {
                child.filtered = _this.filterNodes(child.childNodes, query);
                if (queryNotEmpty && child.filtered.length > 0) {
                    child.expanded = true;
                }
                retVal = retVal || child.filtered.length > 0;
            }
            return retVal;
        });
    };
    UITreeModel.prototype.nodeMatchesQuery = function (node, query) {
        return !query || (node.label != null && node.label.ascii().toLocaleLowerCase().includes(query.ascii().toLocaleLowerCase()));
    };
    UITreeModel.prototype.getChildren = function (node) {
        var injectedChildren = this.applyAutoSort(node.children);
        if (injectedChildren.length === 0) {
            injectedChildren.push(new UITreeNode({ id: "node-empty", leaf: true }, node));
        }
        if (this.maxNodes > 0 && injectedChildren.length > this.maxNodes) {
            injectedChildren = __spreadArray(__spreadArray([], __read(injectedChildren.slice(0, this.maxNodes)), false), [
                new UITreeNode({ id: "node-more", leaf: true }, node)
            ], false);
        }
        return injectedChildren;
    };
    return UITreeModel;
}());
export { UITreeModel };
export var UITreeNode = (function () {
    function UITreeNode(node, parent, autoCheckable) {
        if (autoCheckable === void 0) { autoCheckable = true; }
        var _this = this;
        this.parent = parent;
        this.childNodes = [];
        this.filtered = null;
        this.level = 0;
        this.checked = 0;
        this.isSelectable = true;
        this.isExpandable = true;
        this.muted = true;
        this.mainActionsLength = 0;
        this.dropdownActionsLength = 0;
        this.id = node.id || "node__".concat(NODE_ID++);
        this.label = node.label;
        this.model = node.model;
        this.icon = node.icon;
        this.iconOpen = node.iconOpen;
        this.iconClosed = node.iconClosed;
        this.leaf = !!node.leaf;
        this.expanded = node.expanded;
        this.isSelectable = node.isSelectable == null ? true : node.isSelectable;
        if (this.isSelectable) {
            this.selected = node.selected;
            if (this.selected) {
                this.toggleCheck(false, autoCheckable);
            }
        }
        else {
            this.selected = false;
        }
        this.isExpandable = node.isExpandable == null ? true : node.isExpandable;
        this.disabled = node.disabled;
        this.muted = node.muted;
        this.actions = node.actions;
        if (parent) {
            this.level = parent.level + 1;
            this.parentId = parent.id;
        }
        if (node.children) {
            this.childNodes = node.children.map(function (child) { return new UITreeNode(child, _this, autoCheckable); });
        }
    }
    Object.defineProperty(UITreeNode.prototype, "nodeIcon", {
        get: function () {
            return (this.leaf ? this.icon : this.expanded ? this.iconOpen : this.iconClosed) || this.icon;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(UITreeNode.prototype, "checkIcon", {
        get: function () {
            return this.checked === 2
                ? "tree-check-half"
                : this.checked
                    ? "tree-check-on"
                    : "tree-check-off";
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(UITreeNode.prototype, "expandIcon", {
        get: function () {
            return this.expanded ? "digi-move-line-down" : "digi-move-line";
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(UITreeNode.prototype, "children", {
        get: function () {
            return this.filtered || this.childNodes;
        },
        enumerable: false,
        configurable: true
    });
    UITreeNode.prototype.hasSelectedChild = function () {
        return this.children.find(function (c) { return c.selected || c.hasSelectedChild(); }) != null;
    };
    UITreeNode.prototype.toggleCheck = function (isInitial, autoCheckable) {
        var _this = this;
        if (isInitial === void 0) { isInitial = true; }
        if (autoCheckable === void 0) { autoCheckable = true; }
        this.checked = this.checked ? 0 : 1;
        if (isInitial) {
            window.dispatchEvent(UIInternal.createEvent("nodeselection", this.checked));
        }
        if (autoCheckable) {
            this.children.forEach(function (c) {
                c.updateChild("checked", _this.checked);
            });
            if (this.parent && this.parent.updateCheckedPartial) {
                this.parent.updateCheckedPartial();
            }
        }
    };
    UITreeNode.prototype.updateCheckedPartial = function () {
        var allChecked = this.children.every(function (node) { return node.checked === 1; });
        var allUnchecked = this.children.every(function (node) { return node.checked === 0; });
        this.checked = allChecked ? 1 : allUnchecked ? 0 : 2;
        if (this.parent && this.parent.updateCheckedPartial) {
            this.parent.updateCheckedPartial();
        }
    };
    UITreeNode.prototype.updateChild = function (prop, v) {
        this[prop] = v;
        this.children.forEach(function (c) {
            c.updateChild(prop, v);
        });
    };
    Object.defineProperty(UITreeNode.prototype, "_mainActions", {
        get: function () {
            var _this = this;
            var actions = [];
            if (this.actions != null) {
                actions = this.actions.filter(function (action) { return false == action.asDropdown && (action.display === true || (typeof action.display == 'function' && action.display(_this))); });
            }
            this.mainActionsLength = actions.length;
            return actions;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(UITreeNode.prototype, "mainActions", {
        get: function () {
            return this._mainActions;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(UITreeNode.prototype, "_dropdownActions", {
        get: function () {
            var _this = this;
            var actions = [];
            if (this.actions != null) {
                actions = this.actions.filter(function (action) { return action.asDropdown && (action.display === true || (typeof action.display == 'function' && action.display(_this))); });
            }
            this.dropdownActionsLength = actions.length;
            return actions;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(UITreeNode.prototype, "dropdownActions", {
        get: function () {
            return this._dropdownActions;
        },
        enumerable: false,
        configurable: true
    });
    UITreeNode.prototype.assignActions = function (actions) {
        var _this = this;
        this.actions = actions.map(function (action) {
            var copy = new UITreeAction(action);
            copy.label = action.getLabel(_this);
            return copy;
        });
        return this;
    };
    __decorate([
        computedFrom("leaf", "icon", "expanded", "iconOpen", "iconClosed"),
        __metadata("design:type", Object),
        __metadata("design:paramtypes", [])
    ], UITreeNode.prototype, "nodeIcon", null);
    __decorate([
        computedFrom("checked"),
        __metadata("design:type", Object),
        __metadata("design:paramtypes", [])
    ], UITreeNode.prototype, "checkIcon", null);
    __decorate([
        computedFrom("expanded"),
        __metadata("design:type", Object),
        __metadata("design:paramtypes", [])
    ], UITreeNode.prototype, "expandIcon", null);
    __decorate([
        computedFrom("filtered", "childNodes"),
        __metadata("design:type", Object),
        __metadata("design:paramtypes", [])
    ], UITreeNode.prototype, "children", null);
    __decorate([
        computedFrom('mainActionsLength'),
        __metadata("design:type", Array),
        __metadata("design:paramtypes", [])
    ], UITreeNode.prototype, "mainActions", null);
    __decorate([
        computedFrom('dropdownActionsLength'),
        __metadata("design:type", Array),
        __metadata("design:paramtypes", [])
    ], UITreeNode.prototype, "dropdownActions", null);
    return UITreeNode;
}());
var UITreeAction = (function () {
    function UITreeAction(init) {
        this.asDropdown = true;
        this.display = true;
        Object.assign(this, init);
    }
    UITreeAction.prototype.getLabel = function (node) {
        return this.generateLabel ? this.generateLabel(node) : this.label;
    };
    return UITreeAction;
}());
export { UITreeAction };

//# sourceMappingURL=ui-tree-model.js.map
