var __extends = (this && this.__extends) || (function () {
    var 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 function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
define(["require", "exports", "wijmo/wijmo", "wijmo/wijmo.nav"], function (require, exports, wjcCore, wjcSelf) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    window['wijmo'] = window['wijmo'] || {};
    window['wijmo']['nav'] = wjcSelf;
    var TreeView = (function (_super) {
        __extends(TreeView, _super);
        function TreeView(element, options) {
            var _this = _super.call(this, element) || this;
            _this._itmPath = new _BindingArray('items');
            _this._dspPath = new _BindingArray('header');
            _this._imgPath = new _BindingArray();
            _this._html = false;
            _this._animated = true;
            _this._xpndOnClick = true;
            _this._autoColl = true;
            _this._showChk = false;
            _this._srch = '';
            _this._isReadOnly = true;
            _this.itemsSourceChanged = new wjcCore.Event();
            _this.loadingItems = new wjcCore.Event();
            _this.loadedItems = new wjcCore.Event();
            _this.itemClicked = new wjcCore.Event();
            _this.selectedItemChanged = new wjcCore.Event();
            _this.checkedItemsChanged = new wjcCore.Event();
            _this.isCollapsedChanging = new wjcCore.Event();
            _this.isCollapsedChanged = new wjcCore.Event();
            _this.isCheckedChanging = new wjcCore.Event();
            _this.isCheckedChanged = new wjcCore.Event();
            _this.formatItem = new wjcCore.Event();
            _this.dragStart = new wjcCore.Event();
            _this.dragOver = new wjcCore.Event();
            _this.drop = new wjcCore.Event();
            _this.dragEnd = new wjcCore.Event();
            _this.nodeEditStarting = new wjcCore.Event();
            _this.nodeEditStarted = new wjcCore.Event();
            _this.nodeEditEnding = new wjcCore.Event();
            _this.nodeEditEnded = new wjcCore.Event();
            var tpl = _this.getTemplate();
            _this.applyTemplate('wj-control wj-content wj-treeview', tpl, {
                _root: 'root'
            });
            var host = _this.hostElement;
            wjcCore.setAttribute(host, 'role', 'tree', true);
            wjcCore.addClass(_this._root, TreeView._CNDL);
            wjcCore.setAttribute(_this._root, 'role', 'group', true);
            _this.addEventListener(host, 'mousedown', _this._mousedown.bind(_this));
            _this.addEventListener(host, 'click', _this._click.bind(_this));
            _this.addEventListener(host, 'keydown', _this._keydown.bind(_this));
            _this.addEventListener(host, 'keypress', _this._keypress.bind(_this));
            _this.addEventListener(host, 'wheel', function (e) {
                if (host.scrollHeight > host.offsetHeight) {
                    if ((e.deltaY < 0 && host.scrollTop == 0) ||
                        (e.deltaY > 0 && host.scrollTop + host.offsetHeight >= host.scrollHeight)) {
                        e.preventDefault();
                        e.stopPropagation();
                    }
                }
            });
            _this.addEventListener(host, 'blur', function (e) {
                if (_this._edtNode && !wjcCore.contains(_this._edtNode.element, wjcCore.getActiveElement())) {
                    _this.finishEditing();
                }
            }, true);
            _this.initialize(options);
            _this.refresh();
            return _this;
        }
        Object.defineProperty(TreeView.prototype, "itemsSource", {
            get: function () {
                return this._items;
            },
            set: function (value) {
                if (this._items != value) {
                    this._items = wjcCore.asArray(value);
                    this.onItemsSourceChanged();
                    this._reload();
                }
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeView.prototype, "childItemsPath", {
            get: function () {
                return this._itmPath.path;
            },
            set: function (value) {
                if (value != this.childItemsPath) {
                    this._itmPath.path = value;
                    this._reload();
                }
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeView.prototype, "displayMemberPath", {
            get: function () {
                return this._dspPath.path;
            },
            set: function (value) {
                if (value != this.displayMemberPath) {
                    this._dspPath.path = value;
                    this._reload();
                }
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeView.prototype, "imageMemberPath", {
            get: function () {
                return this._imgPath.path;
            },
            set: function (value) {
                if (value != this.imageMemberPath) {
                    this._imgPath.path = value;
                    this._reload();
                }
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeView.prototype, "isContentHtml", {
            get: function () {
                return this._html;
            },
            set: function (value) {
                if (value != this._html) {
                    this._html = wjcCore.asBoolean(value);
                    this._reload();
                }
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeView.prototype, "showCheckboxes", {
            get: function () {
                return this._showChk;
            },
            set: function (value) {
                if (value != this._showChk) {
                    this._showChk = wjcCore.asBoolean(value);
                    this._reload();
                }
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeView.prototype, "autoCollapse", {
            get: function () {
                return this._autoColl;
            },
            set: function (value) {
                this._autoColl = wjcCore.asBoolean(value);
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeView.prototype, "isAnimated", {
            get: function () {
                return this._animated;
            },
            set: function (value) {
                if (value != this._animated) {
                    this._animated = wjcCore.asBoolean(value);
                }
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeView.prototype, "isReadOnly", {
            get: function () {
                return this._isReadOnly;
            },
            set: function (value) {
                this._isReadOnly = wjcCore.asBoolean(value);
            },
            enumerable: true,
            configurable: true
        });
        TreeView.prototype.startEditing = function (node) {
            if (this.isReadOnly) {
                return false;
            }
            if (!node) {
                node = this.selectedNode;
            }
            if (!node || node.isDisabled) {
                return false;
            }
            if (!this.finishEditing()) {
                return false;
            }
            var editor = node.element.querySelector('.' + TreeView._CNDT);
            if (!editor) {
                return false;
            }
            var e = new TreeNodeEventArgs(node);
            if (!this.onNodeEditStarting(e)) {
                return false;
            }
            editor.tabIndex = 0;
            editor.focus();
            editor.contentEditable = 'true';
            editor.style.cursor = 'auto';
            var rng = document.createRange();
            rng.selectNodeContents(editor);
            var sel = getSelection();
            sel.removeAllRanges();
            sel.addRange(rng);
            editor.focus();
            wjcCore.setAttribute(editor, 'autocomplete', 'off');
            wjcCore.setAttribute(editor, 'autocorrect', 'off');
            this._edtNode = node;
            this.onNodeEditStarted(e);
            return true;
        };
        TreeView.prototype.finishEditing = function (cancel) {
            var node = this._edtNode;
            if (node) {
                var editor = node.element.querySelector('.' + TreeView._CNDT);
                if (!editor) {
                    return false;
                }
                var e = new TreeNodeEventArgs(node);
                if (!this.onNodeEditEnding(e)) {
                    return false;
                }
                var item = node.dataItem, level = node.level;
                if (this.isContentHtml) {
                    if (cancel) {
                        editor.innerHTML = this._dspPath.getValue(item, level);
                    }
                    else {
                        this._dspPath.setValue(item, level, editor.innerHTML);
                    }
                }
                else {
                    if (cancel) {
                        editor.textContent = this._dspPath.getValue(item, level);
                    }
                    else {
                        this._dspPath.setValue(item, level, editor.textContent);
                    }
                }
                var rng = document.createRange();
                rng.selectNodeContents(editor);
                var sel = getSelection();
                sel.removeAllRanges();
                editor.contentEditable = 'false';
                editor.style.cursor = '';
                this._edtNode = null;
                this.onNodeEditEnded(e);
            }
            return true;
        };
        Object.defineProperty(TreeView.prototype, "allowDragging", {
            get: function () {
                return this._dd != null;
            },
            set: function (value) {
                if (value != this.allowDragging) {
                    if (wjcCore.asBoolean(value)) {
                        this._dd = new _TreeDragDropManager(this);
                    }
                    else {
                        this._dd.dispose();
                        this._dd = null;
                    }
                    var nodes = this.hostElement.querySelectorAll('.' + TreeView._CND);
                    for (var i = 0; i < nodes.length; i++) {
                        var node = nodes[i];
                        wjcCore.setAttribute(node, 'draggable', this._dd ? true : null);
                    }
                }
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeView.prototype, "expandOnClick", {
            get: function () {
                return this._xpndOnClick;
            },
            set: function (value) {
                this._xpndOnClick = wjcCore.asBoolean(value);
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeView.prototype, "selectedItem", {
            get: function () {
                return this._selNode ? this._selNode.dataItem : null;
            },
            set: function (value) {
                if (value != this.selectedItem) {
                    this.selectedNode = value ? this.getNode(value) : null;
                }
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeView.prototype, "selectedNode", {
            get: function () {
                return this._selNode;
            },
            set: function (value) {
                if (value != this.selectedNode) {
                    this._prevSel = this._selNode;
                    if (value) {
                        value.select();
                    }
                    else if (this._selNode) {
                        wjcCore.removeClass(this._selNode.element, TreeView._CSEL);
                        this._selNode = null;
                        this.onSelectedItemChanged();
                    }
                }
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeView.prototype, "selectedPath", {
            get: function () {
                var path = [];
                for (var nd = this.selectedNode; nd; nd = nd.parentNode) {
                    var text = this._dspPath.getValue(nd.dataItem, nd.level);
                    path.splice(0, 0, text);
                }
                return path;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeView.prototype, "checkedItems", {
            get: function () {
                if (this._chkItems == null) {
                    var tv = TreeView, qry = '.' + tv._CND + '.' + tv._CEMP + ' > input:checked.' + tv._CNDC, chk = this._root.querySelectorAll(qry);
                    this._chkItems = [];
                    for (var i = 0; i < chk.length; i++) {
                        var item = chk[i].parentElement[tv._DATAITEM_KEY];
                        this._chkItems.push(item);
                    }
                }
                return this._chkItems;
            },
            set: function (value) {
                if (this.showCheckboxes) {
                    var tv = TreeView, qry = '.' + tv._CND + '.' + tv._CEMP, chk = this._root.querySelectorAll(qry), changed = false;
                    for (var i = 0; i < chk.length; i++) {
                        var node = new TreeNode(this, chk[i]), checked = value.indexOf(node.dataItem) > -1;
                        if (node.isChecked != checked) {
                            node.isChecked = checked;
                            changed = true;
                        }
                    }
                    if (changed) {
                        this.onCheckedItemsChanged();
                    }
                }
            },
            enumerable: true,
            configurable: true
        });
        TreeView.prototype.checkAllItems = function (check) {
            if (this.showCheckboxes) {
                var tv = TreeView, qry = '.' + tv._CND + '.' + tv._CEMP, chk = this._root.querySelectorAll(qry), changed = false;
                for (var i = 0; i < chk.length; i++) {
                    var node = new TreeNode(this, chk[i]);
                    if (node.isChecked != check) {
                        node.isChecked = check;
                        changed = true;
                    }
                }
                if (changed) {
                    this.onCheckedItemsChanged();
                }
            }
        };
        Object.defineProperty(TreeView.prototype, "totalItemCount", {
            get: function () {
                var nodes = this.hostElement.querySelectorAll('.' + TreeView._CND);
                return nodes.length;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeView.prototype, "lazyLoadFunction", {
            get: function () {
                return this._lazyLoad;
            },
            set: function (value) {
                if (value != this._lazyLoad) {
                    this._lazyLoad = wjcCore.asFunction(value);
                    this._reload();
                }
            },
            enumerable: true,
            configurable: true
        });
        TreeView.prototype.getFirstNode = function (visible, enabled) {
            var first = this.hostElement.querySelector('.' + TreeView._CND), node = first ? new TreeNode(this, first) : null;
            if (visible && node && !node.element.offsetHeight) {
                node = node.next(visible, enabled);
            }
            if (enabled && node && node.isDisabled) {
                node = node.next(visible, enabled);
            }
            return node;
        };
        TreeView.prototype.getLastNode = function (visible, enabled) {
            var last = this.hostElement.querySelectorAll('.' + TreeView._CND + ':last-child'), node = last.length ? new TreeNode(this, last[last.length - 1]) : null;
            if (visible && node && !node.element.offsetHeight) {
                node = node.previous(visible, enabled);
            }
            if (enabled && node && node.isDisabled) {
                node = node.previous(visible, enabled);
            }
            return node;
        };
        Object.defineProperty(TreeView.prototype, "nodes", {
            get: function () {
                return TreeNode._getChildNodes(this, this._root);
            },
            enumerable: true,
            configurable: true
        });
        TreeView.prototype.getNode = function (item) {
            if (this._isDirty) {
                this._loadTree();
            }
            var nodes = this.hostElement.querySelectorAll('.' + TreeView._CND);
            for (var i = 0; i < nodes.length; i++) {
                var node = nodes[i];
                if (node[TreeView._DATAITEM_KEY] == item) {
                    return new TreeNode(this, node);
                }
            }
            return null;
        };
        TreeView.prototype.addChildNode = function (index, dataItem) {
            var nd = this._createNode(dataItem);
            var nodes = this.nodes;
            if (!nodes) {
                nd.move(this, DropPosition.Into);
            }
            else if (index < nodes.length) {
                nd.move(nodes[index], DropPosition.Before);
            }
            else {
                nd.move(nodes[nodes.length - 1], DropPosition.After);
            }
            return nd;
        };
        TreeView.prototype.collapseToLevel = function (level) {
            var animated = this._animated;
            var autoColl = this._autoColl;
            this._animated = this._autoColl = false;
            this._collapseToLevel(this.nodes, level, 0);
            this._animated = animated;
            this._autoColl = autoColl;
        };
        TreeView.prototype.loadTree = function (preserveOutlineState) {
            this._loadTree(preserveOutlineState);
        };
        TreeView.prototype.onItemsSourceChanged = function (e) {
            this.itemsSourceChanged.raise(this, e);
        };
        TreeView.prototype.onLoadingItems = function (e) {
            this.loadingItems.raise(this, e);
            return !e.cancel;
        };
        TreeView.prototype.onLoadedItems = function (e) {
            this.loadedItems.raise(this, e);
        };
        TreeView.prototype.onItemClicked = function (e) {
            this.itemClicked.raise(this, e);
        };
        TreeView.prototype.onSelectedItemChanged = function (e) {
            this.selectedItemChanged.raise(this, e);
        };
        TreeView.prototype.onCheckedItemsChanged = function (e) {
            this._chkItems = null;
            this.checkedItemsChanged.raise(this, e);
        };
        TreeView.prototype.onIsCollapsedChanging = function (e) {
            this.isCollapsedChanging.raise(this, e);
            return !e.cancel;
        };
        TreeView.prototype.onIsCollapsedChanged = function (e) {
            this.isCollapsedChanged.raise(this, e);
        };
        TreeView.prototype.onIsCheckedChanging = function (e) {
            this.isCheckedChanging.raise(this, e);
            return !e.cancel;
        };
        TreeView.prototype.onIsCheckedChanged = function (e) {
            this.isCheckedChanged.raise(this, e);
        };
        TreeView.prototype.onFormatItem = function (e) {
            this.formatItem.raise(this, e);
        };
        TreeView.prototype.onDragStart = function (e) {
            this.dragStart.raise(this, e);
            return !e.cancel;
        };
        TreeView.prototype.onDragOver = function (e) {
            this.dragOver.raise(this, e);
            return !e.cancel;
        };
        TreeView.prototype.onDrop = function (e) {
            this.drop.raise(this, e);
            return !e.cancel;
        };
        TreeView.prototype.onDragEnd = function (e) {
            this.dragEnd.raise(this, e);
        };
        TreeView.prototype.onNodeEditStarting = function (e) {
            this.nodeEditStarting.raise(this, e);
            return !e.cancel;
        };
        TreeView.prototype.onNodeEditStarted = function (e) {
            this.nodeEditStarted.raise(this, e);
        };
        TreeView.prototype.onNodeEditEnding = function (e) {
            this.nodeEditEnding.raise(this, e);
            return !e.cancel;
        };
        TreeView.prototype.onNodeEditEnded = function (e) {
            this.nodeEditEnded.raise(this, e);
        };
        TreeView.prototype.refresh = function () {
            _super.prototype.refresh.call(this);
            if (!this.isUpdating && this._isDirty) {
                this._loadTree();
            }
        };
        TreeView.prototype._reload = function () {
            this._isDirty = true;
            this.invalidate();
        };
        TreeView.prototype._createNode = function (dataItem) {
            var t = new TreeView(document.createElement('div'), {
                childItemsPath: this.childItemsPath,
                displayMemberPath: this.displayMemberPath,
                imageMemberPath: this.imageMemberPath,
                isContentHtml: this.isContentHtml,
                showCheckboxes: this.showCheckboxes,
                itemsSource: [dataItem]
            });
            return t.getFirstNode();
        };
        TreeView.prototype._mousedown = function (e) {
            if (!e.defaultPrevented) {
                var cb = wjcCore.closest(e.target, 'input.' + TreeView._CNDC), ne = wjcCore.closestClass(e.target, TreeView._CND), node = ne ? new TreeNode(this, ne) : null;
                if (node && !node.isDisabled) {
                    this.selectedNode = node;
                }
                this._dnIndet = cb && cb.indeterminate;
            }
        };
        TreeView.prototype._click = function (e) {
            var _this = this;
            if (!e.defaultPrevented) {
                var nodeElement = wjcCore.closestClass(e.target, TreeView._CND);
                if (nodeElement) {
                    var node_1 = new TreeNode(this, nodeElement), cb_1 = wjcCore.closest(e.target, 'input.' + TreeView._CNDC);
                    if (node_1.isDisabled) {
                        return;
                    }
                    if (!cb_1 && node_1.equals(this._edtNode)) {
                        return;
                    }
                    nodeElement.focus();
                    if (cb_1) {
                        e.preventDefault();
                        e.stopPropagation();
                        setTimeout(function () {
                            cb_1.indeterminate = false;
                            node_1.isChecked = !node_1.isChecked;
                            _this.onCheckedItemsChanged();
                        });
                    }
                    if (!cb_1) {
                        var el = e.target, ctrlKey = e.ctrlKey || e.metaKey, collToLevel = ctrlKey && !node_1.hasPendingChildren, rc = nodeElement.getBoundingClientRect(), offset = this.rightToLeft ? rc.right - e.clientX : e.clientX - rc.left, toggled = false;
                        if (offset <= el.offsetHeight) {
                            if (collToLevel) {
                                this.collapseToLevel(node_1.isCollapsed ? node_1.level + 1 : node_1.level);
                            }
                            else {
                                node_1.isCollapsed = !node_1.isCollapsed;
                            }
                            toggled = true;
                        }
                        else if (this.expandOnClick && node_1.isCollapsed) {
                            if (collToLevel) {
                                this.collapseToLevel(node_1.level);
                            }
                            else {
                                node_1.isCollapsed = false;
                            }
                            toggled = true;
                        }
                        if (toggled && collToLevel && this.selectedNode) {
                            this.selectedNode.ensureVisible();
                        }
                        if (!toggled && !this.isReadOnly) {
                            if (this.selectedNode && this.selectedNode.equals(this._prevSel)) {
                                this.startEditing();
                            }
                        }
                    }
                    if (this.selectedItem) {
                        this.onItemClicked();
                    }
                }
            }
        };
        TreeView.prototype._keydown = function (e) {
            if (!e.defaultPrevented) {
                var node = this._selNode, newNode = void 0, key = e.keyCode, handled = true;
                if (node && !node.isDisabled) {
                    switch (key) {
                        case wjcCore.Key.F2:
                            this.startEditing();
                            e.preventDefault();
                            break;
                        case wjcCore.Key.Escape:
                            this.finishEditing(true);
                            e.preventDefault();
                            break;
                        case wjcCore.Key.Up:
                        case wjcCore.Key.Down:
                            this.finishEditing();
                            break;
                        case wjcCore.Key.Enter:
                            if (this._edtNode) {
                                this.finishEditing();
                                key = wjcCore.Key.Down;
                            }
                            else {
                                this.startEditing();
                                e.preventDefault();
                            }
                            break;
                    }
                    if (this._edtNode) {
                        return;
                    }
                    if (this.rightToLeft) {
                        switch (key) {
                            case wjcCore.Key.Left:
                                key = wjcCore.Key.Right;
                                break;
                            case wjcCore.Key.Right:
                                key = wjcCore.Key.Left;
                                break;
                        }
                    }
                    switch (key) {
                        case wjcCore.Key.Left:
                            if (!node.isCollapsed && node.hasChildren) {
                                node.setCollapsed(true);
                            }
                            else {
                                node = node.parentNode;
                                if (node) {
                                    node.select();
                                }
                            }
                            break;
                        case wjcCore.Key.Right:
                            node.setCollapsed(false);
                            break;
                        case wjcCore.Key.Up:
                            newNode = node.previous(true, true);
                            break;
                        case wjcCore.Key.Down:
                            newNode = node.next(true, true);
                            break;
                        case wjcCore.Key.Home:
                            newNode = this.getFirstNode(true, true);
                            break;
                        case wjcCore.Key.End:
                            newNode = this.getLastNode(true, true);
                            break;
                        case wjcCore.Key.Space:
                            if (this.selectedItem) {
                                var cb = node.checkBox;
                                if (cb) {
                                    node.isChecked = !cb.checked;
                                    this.onCheckedItemsChanged();
                                }
                            }
                            break;
                        case wjcCore.Key.Enter:
                            if (this.selectedItem) {
                                this.onItemClicked();
                            }
                            break;
                        default:
                            handled = false;
                    }
                    if (handled) {
                        e.preventDefault();
                        if (newNode) {
                            newNode.select();
                        }
                    }
                }
            }
        };
        TreeView.prototype._keypress = function (e) {
            var _this = this;
            if (!e.defaultPrevented) {
                if (e.ctrlKey || e.metaKey || e.altKey)
                    return;
                if (e.target instanceof HTMLInputElement)
                    return;
                if (this._edtNode)
                    return;
                if (e.charCode > 32 && this.startEditing(this.selectedNode)) {
                    var edt = wjcCore.getActiveElement();
                    if (wjcCore.contains(this._edtNode.element, edt)) {
                        edt.textContent = String.fromCharCode(e.charCode);
                        e.preventDefault();
                        var rng = document.createRange();
                        rng.selectNodeContents(edt);
                        rng.collapse(false);
                        var sel = getSelection();
                        sel.removeAllRanges();
                        sel.addRange(rng);
                    }
                    return;
                }
                if (e.charCode > 32 || (e.charCode == 32 && this._srch)) {
                    e.preventDefault();
                    this._srch += String.fromCharCode(e.charCode).toLowerCase();
                    if (this._toSrch) {
                        clearTimeout(this._toSrch);
                    }
                    this._toSrch = setTimeout(function () {
                        _this._toSrch = null;
                        _this._srch = '';
                    }, TreeView._AS_DLY);
                    var item = this._findNext();
                    if (item == null && this._srch.length > 1) {
                        this._srch = this._srch[this._srch.length - 1];
                        item = this._findNext();
                    }
                    if (item != null) {
                        this.selectedItem = item;
                    }
                }
            }
        };
        TreeView.prototype._findNext = function () {
            if (this.hostElement && this.selectedItem) {
                var start = this.getNode(this.selectedItem), node = start, wrapped = false, skip = false;
                if (this._srch.length == 1) {
                    skip = true;
                }
                for (; node;) {
                    if (!node.isDisabled && !skip) {
                        var txt = node.element.textContent.trim().toLowerCase();
                        if (txt.indexOf(this._srch) == 0) {
                            return node.dataItem;
                        }
                    }
                    var next = node.next(true, true);
                    if (next == start && wrapped) {
                        break;
                    }
                    if (!next && !wrapped) {
                        next = this.getFirstNode(true, true);
                        wrapped = true;
                    }
                    node = next;
                    skip = false;
                }
            }
            return null;
        };
        TreeView.prototype._loadTree = function (preserveOutlineState) {
            var root = this._root;
            if (root) {
                if (!this.onLoadingItems(new wjcCore.CancelEventArgs())) {
                    return;
                }
                this._isDirty = false;
                var focus_1 = this.containsFocus();
                var sel = this.selectedItem;
                this.selectedItem = null;
                this._chkItems = null;
                this._ldLvl = -1;
                var collapsedMap = void 0;
                if (preserveOutlineState && wjcCore.isFunction(window['Map'])) {
                    collapsedMap = new Map();
                    var nodes = this.hostElement.querySelectorAll('.' + TreeView._CND);
                    for (var i = 0; i < nodes.length; i++) {
                        var node = nodes[i];
                        if (wjcCore.hasClass(node, TreeView._CCLD)) {
                            collapsedMap.set(node[TreeView._DATAITEM_KEY], true);
                        }
                    }
                }
                root.innerHTML = '';
                if (this._items) {
                    for (var i = 0; i < this._items.length; i++) {
                        this._addItem(root, 0, this._items[i]);
                    }
                }
                if (collapsedMap) {
                    var nodes = this.hostElement.querySelectorAll('.' + TreeView._CND);
                    for (var i = 0; i < nodes.length; i++) {
                        var node = nodes[i], hasList = TreeNode._isNodeList(node), collapsed = collapsedMap.get(node[TreeView._DATAITEM_KEY]);
                        wjcCore.toggleClass(node, TreeView._CCLD, collapsed == true);
                        wjcCore.setAttribute(node, 'aria-expanded', hasList ? (!collapsed).toString() : null);
                    }
                }
                if (focus_1 && !this.containsFocus()) {
                    this.focus();
                }
                this.selectedItem = sel;
                this.onLoadedItems();
                this._ldLvl = -1;
            }
        };
        TreeView.prototype._addItem = function (host, level, item) {
            var text = this._dspPath.getValue(item, level), imgSrc = this._imgPath.getValue(item, level), arr = wjcCore.asArray(this._itmPath.getValue(item, level), true);
            var node = document.createElement('div');
            wjcCore.addClass(node, TreeView._CND);
            node.tabIndex = 0;
            wjcCore.setAttribute(node, 'role', 'treeitem', true);
            var span = document.createElement('span');
            if (this.isContentHtml) {
                span.innerHTML = text;
            }
            else {
                span.textContent = text;
            }
            wjcCore.addClass(span, TreeView._CNDT);
            node.appendChild(span);
            if (imgSrc) {
                var img = document.createElement('img');
                img.src = imgSrc;
                node.insertBefore(img, node.firstChild);
            }
            if (this._showChk && !this._lazyLoad) {
                var cb = document.createElement('input');
                cb.type = 'checkbox';
                cb.tabIndex = -1;
                wjcCore.addClass(cb, TreeView._CNDC);
                node.insertBefore(cb, node.firstChild);
            }
            if (this._dd) {
                node.setAttribute('draggable', 'true');
            }
            host.appendChild(node);
            node[TreeView._DATAITEM_KEY] = item;
            if (arr && arr.length == 0 && !this.lazyLoadFunction) {
                arr = null;
            }
            if (arr) {
                var expanded = true;
                if (level > this._ldLvl) {
                    this._ldLvl = level;
                    if (arr.length == 0) {
                        wjcCore.addClass(node, TreeView._CCLD);
                        expanded = false;
                    }
                }
                else {
                    wjcCore.addClass(node, TreeView._CCLD);
                    expanded = false;
                    if (level < this._ldLvl) {
                        this._ldLvl = 10000;
                    }
                }
                if (arr.length > 0) {
                    var nodeList = document.createElement('div');
                    wjcCore.addClass(nodeList, TreeView._CNDL);
                    for (var i = 0; i < arr.length; i++) {
                        this._addItem(nodeList, level + 1, arr[i]);
                    }
                    host.appendChild(nodeList);
                    wjcCore.setAttribute(node, 'aria-expanded', expanded.toString(), true);
                    wjcCore.setAttribute(nodeList, 'role', 'group', true);
                }
            }
            else {
                wjcCore.addClass(node, TreeView._CEMP);
            }
            if (this.formatItem.hasHandlers) {
                this.onFormatItem(new FormatNodeEventArgs(item, node, level));
            }
        };
        TreeView.prototype._collapseToLevel = function (nodes, maxLevel, currentLevel) {
            for (var i = 0; i < nodes.length; i++) {
                var node = nodes[i];
                if (node.hasPendingChildren) {
                    continue;
                }
                node.isCollapsed = currentLevel >= maxLevel;
                if (node.hasChildren) {
                    this._collapseToLevel(node.nodes, maxLevel, currentLevel + 1);
                }
            }
        };
        TreeView.prototype._lazyLoadNode = function (node) {
            var host = this.hostElement;
            if (!wjcCore.hasClass(host, TreeView._CLDG)) {
                wjcCore.addClass(host, TreeView._CLDG);
                wjcCore.addClass(node.element, TreeView._CLDG);
                this.lazyLoadFunction(node, this._lazyLoadCallback.bind(node));
            }
        };
        TreeView.prototype._lazyLoadCallback = function (result) {
            var node = this, tree = node.treeView;
            tree._lazyLoadNodeDone(node, result);
        };
        TreeView.prototype._lazyLoadNodeDone = function (node, result) {
            var tv = TreeView;
            wjcCore.removeClass(node.element, tv._CLDG);
            wjcCore.removeClass(this.hostElement, tv._CLDG);
            var item = node.dataItem, level = node.level, arr = wjcCore.asArray(result, true);
            if (arr == null || arr.length == 0) {
                this._itmPath.setValue(item, level, null);
                wjcCore.addClass(node.element, tv._CEMP);
            }
            else if (arr.length) {
                this._itmPath.setValue(item, level, arr);
                var nodeList = document.createElement('div'), nodeElement = node.element;
                wjcCore.addClass(nodeList, tv._CNDL);
                nodeElement.parentElement.insertBefore(nodeList, nodeElement.nextSibling);
                for (var i = 0; i < arr.length; i++) {
                    this._addItem(nodeList, level + 1, arr[i]);
                }
                node.isCollapsed = false;
            }
        };
        TreeView._DATAITEM_KEY = 'wj-Data-Item';
        TreeView._AS_DLY = 600;
        TreeView._AN_DLY = 200;
        TreeView._CND = 'wj-node';
        TreeView._CNDL = 'wj-nodelist';
        TreeView._CEMP = 'wj-state-empty';
        TreeView._CNDT = 'wj-node-text';
        TreeView._CNDC = 'wj-node-check';
        TreeView._CSEL = 'wj-state-selected';
        TreeView._CCLD = 'wj-state-collapsed';
        TreeView._CCLG = 'wj-state-collapsing';
        TreeView._CLDG = 'wj-state-loading';
        TreeView.controlTemplate = '<div wj-part="root"></div>';
        return TreeView;
    }(wjcCore.Control));
    exports.TreeView = TreeView;
    var TreeNode = (function () {
        function TreeNode(treeView, nodeElement) {
            if (wjcCore.hasClass(nodeElement, 'wj-treeview')) {
                treeView = wjcCore.Control.getControl(nodeElement);
                nodeElement = null;
            }
            else {
                TreeNode._assertNode(nodeElement);
            }
            this._t = treeView;
            this._e = nodeElement;
        }
        Object.defineProperty(TreeNode.prototype, "dataItem", {
            get: function () {
                return this._e[TreeView._DATAITEM_KEY];
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeNode.prototype, "element", {
            get: function () {
                return this._e;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeNode.prototype, "treeView", {
            get: function () {
                return this._t;
            },
            enumerable: true,
            configurable: true
        });
        TreeNode.prototype.ensureVisible = function () {
            for (var p = this.parentNode; p; p = p.parentNode) {
                p.isCollapsed = false;
            }
            var host = this._t.hostElement, rco = this.element.getBoundingClientRect(), rcc = host.getBoundingClientRect();
            if (rco.bottom > rcc.bottom) {
                host.scrollTop += rco.bottom - rcc.bottom;
            }
            else if (rco.top < rcc.top) {
                host.scrollTop -= rcc.top - rco.top;
            }
        };
        TreeNode.prototype.equals = function (node) {
            return node != null && node.element == this.element;
        };
        TreeNode.prototype.select = function () {
            var tree = this._t;
            var selNode = tree._selNode;
            if (!this.equals(selNode)) {
                if (selNode) {
                    wjcCore.removeClass(selNode.element, TreeView._CSEL);
                }
                tree._selNode = this;
                wjcCore.addClass(this.element, TreeView._CSEL);
                this.ensureVisible();
                if (tree.containsFocus()) {
                    this.element.focus();
                }
                tree.onSelectedItemChanged();
            }
        };
        Object.defineProperty(TreeNode.prototype, "index", {
            get: function () {
                var index = 0;
                for (var p = this._pse(this.element); p; p = this._pse(p)) {
                    if (TreeNode._isNode(p)) {
                        index++;
                    }
                }
                return index;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeNode.prototype, "parentNode", {
            get: function () {
                var parent = null;
                if (this._e) {
                    var nodeList = this._e.parentElement;
                    TreeNode._assertNodeList(nodeList);
                    parent = this._pse(nodeList);
                }
                return parent ? new TreeNode(this._t, parent) : null;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeNode.prototype, "level", {
            get: function () {
                var level = -1;
                for (var e = this; e; e = e.parentNode) {
                    level++;
                }
                return level;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeNode.prototype, "hasChildren", {
            get: function () {
                return TreeNode._isNode(this._e) && !TreeNode._isEmpty(this._e);
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeNode.prototype, "hasPendingChildren", {
            get: function () {
                return this.isCollapsed && this.hasChildren &&
                    !TreeNode._isNodeList(this.element.nextElementSibling) &&
                    wjcCore.isFunction(this._t.lazyLoadFunction);
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeNode.prototype, "nodes", {
            get: function () {
                return this.hasChildren
                    ? TreeNode._getChildNodes(this._t, this._e.nextSibling)
                    : null;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeNode.prototype, "checkBox", {
            get: function () {
                return this._e.querySelector('input.' + TreeView._CNDC);
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeNode.prototype, "isCollapsed", {
            get: function () {
                return this.hasChildren && wjcCore.hasClass(this._e, TreeView._CCLD);
            },
            set: function (value) {
                if (value != this.isCollapsed) {
                    var tree = this._t, e = new TreeNodeEventArgs(this);
                    if (tree.onIsCollapsedChanging(e)) {
                        this.setCollapsed(wjcCore.asBoolean(value), tree.isAnimated, tree.autoCollapse);
                        tree.onIsCollapsedChanged(e);
                    }
                }
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeNode.prototype, "isChecked", {
            get: function () {
                var cb = this.checkBox;
                return cb && !cb.indeterminate
                    ? cb.checked
                    : null;
            },
            set: function (value) {
                if (value != this.isChecked) {
                    var tree = this._t, e = new TreeNodeEventArgs(this);
                    if (tree.onIsCheckedChanging(e)) {
                        this.setChecked(wjcCore.asBoolean(value), true);
                        tree.onIsCheckedChanged(e);
                    }
                }
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeNode.prototype, "isDisabled", {
            get: function () {
                return this._e && this._e.getAttribute('disabled') != null;
            },
            set: function (value) {
                value = wjcCore.asBoolean(value, true);
                if (value != this.isDisabled) {
                    wjcCore.enable(this._e, !value);
                }
            },
            enumerable: true,
            configurable: true
        });
        TreeNode.prototype.previous = function (visible, enabled) {
            var prev = this._pse(this._e);
            if (!prev && TreeNode._isNodeList(this._e.parentElement)) {
                prev = this._pse(this._e.parentElement);
            }
            if (TreeNode._isNodeList(prev)) {
                while (TreeNode._isNodeList(prev) && prev.childElementCount) {
                    prev = prev.lastChild;
                }
                if (TreeNode._isNodeList(prev)) {
                    prev = this._pse(prev);
                }
            }
            var node = TreeNode._isNode(prev) ? new TreeNode(this._t, prev) : null;
            if (visible && node && !node.element.offsetHeight) {
                node = node.previous(visible, enabled);
            }
            if (enabled && node && node.isDisabled) {
                node = node.previous(visible, enabled);
            }
            return node;
        };
        TreeNode.prototype.next = function (visible, enabled) {
            var next = this._e.nextSibling;
            if (TreeNode._isNodeList(next)) {
                next = next.childElementCount
                    ? next.firstChild
                    : next.nextSibling;
            }
            if (!next) {
                for (var e = this._e.parentElement; !next && TreeNode._isNodeList(e); e = e.parentElement) {
                    next = e.nextSibling;
                }
            }
            var node = TreeNode._isNode(next) ? new TreeNode(this._t, next) : null;
            if (visible && node && !node.element.offsetHeight) {
                node = node.next(visible, enabled);
            }
            if (enabled && node && node.isDisabled) {
                node = node.next(visible, enabled);
            }
            return node;
        };
        TreeNode.prototype.previousSibling = function () {
            var prev = this._pse(this.element);
            if (TreeNode._isNodeList(prev)) {
                prev = this._pse(prev);
            }
            return prev ? new TreeNode(this._t, prev) : null;
        };
        TreeNode.prototype.nextSibling = function () {
            var next = this.element.nextSibling;
            if (TreeNode._isNodeList(next)) {
                next = next.nextSibling;
            }
            return next ? new TreeNode(this._t, next) : null;
        };
        TreeNode.prototype.setCollapsed = function (collapsed, animate, collapseSiblings) {
            var tree = this._t, node = this._e, list = this._e.nextElementSibling, hasList = TreeNode._isNodeList(list);
            wjcCore.setAttribute(node, 'aria-expanded', hasList ? (!collapsed).toString() : null);
            if (collapsed == this.isCollapsed) {
                return;
            }
            if (!collapsed && !hasList && wjcCore.isFunction(tree.lazyLoadFunction)) {
                tree._lazyLoadNode(this);
                return;
            }
            if (animate == null) {
                animate = tree.isAnimated;
            }
            if (collapseSiblings == null) {
                collapseSiblings = tree.autoCollapse;
            }
            if (!animate) {
                wjcCore.toggleClass(node, TreeView._CCLD, collapsed);
            }
            else {
                if (hasList) {
                    var h_1 = list.offsetHeight, s_1 = list.style;
                    if (!collapsed) {
                        wjcCore.toggleClass(node, TreeView._CCLD, false);
                        s_1.height = s_1.opacity = '0';
                        wjcCore.animate(function (pct) {
                            if (pct >= 1) {
                                s_1.height = s_1.opacity = '';
                            }
                            else {
                                s_1.height = (pct * h_1).toFixed(0) + 'px';
                            }
                        }, TreeView._AN_DLY);
                    }
                    else {
                        wjcCore.toggleClass(node, TreeView._CCLG, true);
                        wjcCore.animate(function (pct) {
                            if (pct < 1) {
                                pct = 1 - pct;
                                s_1.height = (pct * h_1).toFixed(0) + 'px';
                            }
                            else {
                                s_1.height = s_1.opacity = '';
                                wjcCore.toggleClass(node, TreeView._CCLD, true);
                                wjcCore.toggleClass(node, TreeView._CCLG, false);
                            }
                        }, TreeView._AN_DLY);
                    }
                }
            }
            if (!collapsed && collapseSiblings) {
                var list_1 = node.parentElement;
                if (TreeNode._isNodeList(list_1)) {
                    for (var i = 0; i < list_1.children.length; i++) {
                        var sibling = list_1.children[i];
                        if (sibling != node && TreeNode._isNode(sibling)) {
                            wjcCore.toggleClass(sibling, TreeView._CCLD, true);
                            sibling.setAttribute('aria-expanded', 'false');
                        }
                    }
                }
            }
        };
        TreeNode.prototype.setChecked = function (checked, updateParent) {
            var cb = this.checkBox;
            cb.checked = checked;
            cb.indeterminate = false;
            if (this.hasChildren) {
                var nodes = this.nodes;
                for (var i = 0; i < nodes.length; i++) {
                    var child = nodes[i];
                    child.setChecked(checked, false);
                }
            }
            if (updateParent) {
                var parent_1 = this.parentNode;
                if (parent_1) {
                    parent_1._updateCheckedState();
                }
            }
        };
        TreeNode.prototype.remove = function () {
            var tree = this._t, parent = this.parentNode, arr = this._getArray(), index = arr.indexOf(this.dataItem);
            if (tree.selectedNode == this) {
                var newSel = this.nextSibling() || this.previousSibling() || this.parentNode;
                if (newSel) {
                    tree.selectedNode = newSel;
                }
            }
            wjcCore.removeChild(this.element);
            if (parent) {
                parent._updateState();
            }
            arr.splice(index, 1);
            this._t = null;
        };
        TreeNode.prototype.addChildNode = function (index, dataItem) {
            var nd = this._t._createNode(dataItem);
            var nodes = this.nodes;
            if (!nodes) {
                nd.move(this, DropPosition.Into);
            }
            else if (index < nodes.length) {
                nd.move(nodes[index], DropPosition.Before);
            }
            else {
                nd.move(nodes[nodes.length - 1], DropPosition.After);
            }
            return nd;
        };
        TreeNode.prototype.refresh = function (dataItem) {
            var arr = this._getArray();
            if (dataItem) {
                arr[this.index] = dataItem;
            }
            dataItem = arr[this.index];
            var newNode = this._t._createNode(dataItem);
            var nodeList = this.hasChildren && !this.hasPendingChildren
                ? this.element.nextSibling
                : null;
            if (nodeList) {
                wjcCore.removeChild(nodeList);
            }
            nodeList = newNode.hasChildren && !newNode.hasPendingChildren
                ? newNode.element.nextSibling
                : null;
            if (nodeList) {
                this.element.parentElement.insertBefore(nodeList, this.element.nextSibling);
            }
            this.element.innerHTML = newNode.element.innerHTML;
            this._updateState();
        };
        TreeNode.prototype.move = function (refNode, position) {
            if (refNode instanceof TreeNode && this._contains(refNode)) {
                return false;
            }
            var parentOld = this.parentNode, arrOld = this._getArray();
            this._moveElements(refNode, position);
            var parentNew = this.parentNode, arrNew = this._getArray();
            if (parentOld) {
                parentOld._updateState();
            }
            if (parentNew) {
                parentNew._updateState();
            }
            var item = this.dataItem, index = arrOld.indexOf(item);
            arrOld.splice(index, 1);
            arrNew.splice(this.index, 0, item);
            if (refNode.treeView) {
                this._t = refNode.treeView;
            }
            return true;
        };
        Object.defineProperty(TreeNode.prototype, "itemsSource", {
            get: function () {
                return this._getArray();
            },
            enumerable: true,
            configurable: true
        });
        TreeNode.prototype._pse = function (e) {
            return e.previousElementSibling;
        };
        TreeNode.prototype._contains = function (node) {
            for (; node; node = node.parentNode) {
                if (node.element == this.element) {
                    return true;
                }
            }
            return false;
        };
        TreeNode.prototype._getArray = function () {
            var tree = this._t, parent = this.parentNode, arr = tree.itemsSource;
            if (parent) {
                var path = tree._itmPath;
                arr = path.getValue(parent.dataItem, this.level);
                if (!arr) {
                    arr = [];
                    path.setValue(parent.dataItem, this.level, arr);
                }
            }
            return arr;
        };
        TreeNode.prototype._moveElements = function (refNode, position) {
            var frag = document.createDocumentFragment(), nodeList = this.hasChildren && !this.hasPendingChildren
                ? this.element.nextSibling
                : null;
            frag.appendChild(this.element);
            if (nodeList) {
                TreeNode._assertNodeList(nodeList);
                frag.appendChild(nodeList);
            }
            if (refNode instanceof TreeView) {
                refNode._root.insertBefore(frag, null);
                return;
            }
            var ref = refNode.element, parent = (ref ? ref.parentElement : refNode.treeView._root);
            TreeNode._assertNodeList(parent);
            var dp = DropPosition;
            switch (position) {
                case dp.Before:
                    parent.insertBefore(frag, ref);
                    break;
                case dp.After:
                    refNode = refNode.nextSibling();
                    ref = refNode ? refNode.element : null;
                    parent.insertBefore(frag, ref);
                    break;
                case dp.Into:
                    if (!refNode.hasChildren || refNode.hasPendingChildren) {
                        nodeList = document.createElement('div');
                        wjcCore.addClass(nodeList, TreeView._CNDL);
                        parent.insertBefore(nodeList, ref.nextSibling);
                    }
                    parent = refNode.element.nextSibling;
                    TreeNode._assertNodeList(parent);
                    parent.insertBefore(frag, null);
                    break;
            }
        };
        TreeNode.prototype._updateState = function () {
            this._updateEmptyState();
            this._updateCheckedState();
        };
        TreeNode.prototype._updateEmptyState = function () {
            var nodeList = this.element.nextSibling, hasChildren = false;
            if (TreeNode._isNodeList(nodeList)) {
                if (nodeList.childElementCount) {
                    hasChildren = true;
                }
                else {
                    wjcCore.removeChild(nodeList);
                }
            }
            wjcCore.toggleClass(this.element, TreeView._CEMP, !hasChildren);
            if (!hasChildren) {
                this.element.removeAttribute('aria-expanded');
            }
        };
        TreeNode.prototype._updateCheckedState = function () {
            var cb = this.checkBox, nodes = this.nodes, checked = 0, unchecked = 0;
            if (cb && nodes) {
                for (var i = 0; i < nodes.length; i++) {
                    var node = nodes[i];
                    switch (node.isChecked) {
                        case true:
                            checked++;
                            break;
                        case false:
                            unchecked++;
                            break;
                    }
                }
                if (checked == nodes.length) {
                    cb.checked = true;
                    cb.indeterminate = false;
                }
                else if (unchecked == nodes.length) {
                    cb.checked = false;
                    cb.indeterminate = false;
                }
                else {
                    cb.checked = false;
                    cb.indeterminate = true;
                }
            }
            var parent = this.parentNode;
            if (parent) {
                parent._updateCheckedState();
            }
        };
        TreeNode._getChildNodes = function (treeView, nodeList) {
            TreeNode._assertNodeList(nodeList);
            var arr = [];
            if (TreeNode._isNodeList(nodeList)) {
                var children = nodeList.children;
                for (var i = 0; i < children.length; i++) {
                    var child = children[i];
                    if (TreeNode._isNode(child)) {
                        arr.push(new TreeNode(treeView, child));
                    }
                }
            }
            return arr;
        };
        TreeNode._isNode = function (e) {
            return e && wjcCore.hasClass(e, TreeView._CND);
        };
        TreeNode._isNodeList = function (e) {
            return e && wjcCore.hasClass(e, TreeView._CNDL);
        };
        TreeNode._isEmpty = function (node) {
            return TreeNode._isNode(node) && wjcCore.hasClass(node, TreeView._CEMP);
        };
        TreeNode._isCollapsed = function (node) {
            return TreeNode._isNode(node) && !TreeNode._isEmpty(node) && wjcCore.hasClass(node, TreeView._CCLD);
        };
        TreeNode._assertNode = function (node) {
            wjcCore.assert(TreeNode._isNode(node), 'node expected');
        };
        TreeNode._assertNodeList = function (nodeList) {
            wjcCore.assert(TreeNode._isNodeList(nodeList), 'nodeList expected');
        };
        return TreeNode;
    }());
    exports.TreeNode = TreeNode;
    var FormatNodeEventArgs = (function (_super) {
        __extends(FormatNodeEventArgs, _super);
        function FormatNodeEventArgs(dataItem, element, level) {
            var _this = _super.call(this) || this;
            _this._data = dataItem;
            _this._e = wjcCore.asType(element, HTMLElement);
            _this._level = level;
            return _this;
        }
        Object.defineProperty(FormatNodeEventArgs.prototype, "dataItem", {
            get: function () {
                return this._data;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(FormatNodeEventArgs.prototype, "element", {
            get: function () {
                return this._e;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(FormatNodeEventArgs.prototype, "level", {
            get: function () {
                return this._level;
            },
            enumerable: true,
            configurable: true
        });
        return FormatNodeEventArgs;
    }(wjcCore.EventArgs));
    exports.FormatNodeEventArgs = FormatNodeEventArgs;
    var TreeNodeEventArgs = (function (_super) {
        __extends(TreeNodeEventArgs, _super);
        function TreeNodeEventArgs(node) {
            var _this = _super.call(this) || this;
            _this._node = node;
            return _this;
        }
        Object.defineProperty(TreeNodeEventArgs.prototype, "node", {
            get: function () {
                return this._node;
            },
            enumerable: true,
            configurable: true
        });
        return TreeNodeEventArgs;
    }(wjcCore.CancelEventArgs));
    exports.TreeNodeEventArgs = TreeNodeEventArgs;
    var TreeNodeDragDropEventArgs = (function (_super) {
        __extends(TreeNodeDragDropEventArgs, _super);
        function TreeNodeDragDropEventArgs(dragSource, dropTarget, position) {
            var _this = _super.call(this) || this;
            _this._src = wjcCore.asType(dragSource, TreeNode);
            _this._tgt = wjcCore.asType(dropTarget, TreeNode);
            _this._pos = position;
            return _this;
        }
        Object.defineProperty(TreeNodeDragDropEventArgs.prototype, "dragSource", {
            get: function () {
                return this._src;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeNodeDragDropEventArgs.prototype, "dropTarget", {
            get: function () {
                return this._tgt;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(TreeNodeDragDropEventArgs.prototype, "position", {
            get: function () {
                return this._pos;
            },
            set: function (value) {
                this._pos = wjcCore.asEnum(value, DropPosition);
            },
            enumerable: true,
            configurable: true
        });
        return TreeNodeDragDropEventArgs;
    }(wjcCore.CancelEventArgs));
    exports.TreeNodeDragDropEventArgs = TreeNodeDragDropEventArgs;
    var DropPosition;
    (function (DropPosition) {
        DropPosition[DropPosition["Before"] = 0] = "Before";
        DropPosition[DropPosition["After"] = 1] = "After";
        DropPosition[DropPosition["Into"] = 2] = "Into";
    })(DropPosition = exports.DropPosition || (exports.DropPosition = {}));
    ;
    var _TreeDragDropManager = (function () {
        function _TreeDragDropManager(treeView) {
            this._tree = wjcCore.asType(treeView, TreeView);
            this._dragstartBnd = this._dragstart.bind(this);
            this._dragoverBnd = this._dragover.bind(this);
            this._dropBnd = this._drop.bind(this);
            this._dragendBnd = this._dragend.bind(this);
            var tree = this._tree, host = tree.hostElement;
            tree.addEventListener(host, 'dragstart', this._dragstartBnd);
            tree.addEventListener(host, 'dragover', this._dragoverBnd);
            tree.addEventListener(host, 'dragleave', this._dragoverBnd);
            tree.addEventListener(host, 'drop', this._dropBnd);
            tree.addEventListener(host, 'dragend', this._dragendBnd);
            tree.addEventListener(host, 'keydown', this._keydown);
        }
        _TreeDragDropManager.prototype.dispose = function () {
            var tree = this._tree, host = tree.hostElement;
            tree.removeEventListener(host, 'dragstart', this._dragstartBnd);
            tree.removeEventListener(host, 'dragover', this._dragoverBnd);
            tree.removeEventListener(host, 'dragleave', this._dragoverBnd);
            tree.removeEventListener(host, 'drop', this._dropBnd);
            tree.removeEventListener(host, 'dragend', this._dragendBnd);
            tree.removeEventListener(host, 'keydown', this._keydown);
            this._showDragMarker();
        };
        _TreeDragDropManager.prototype._dragstart = function (e) {
            if (!e.defaultPrevented) {
                var tree = this._tree, target = wjcCore.closestClass(e.target, TreeView._CND), ddm = _TreeDragDropManager;
                ddm._drgSrc = TreeNode._isNode(target) ? new TreeNode(tree, target) : null;
                if (ddm._drgSrc) {
                    var ee = new TreeNodeEventArgs(ddm._drgSrc);
                    if (!tree.onDragStart(ee)) {
                        ddm._drgSrc = null;
                    }
                }
                if (ddm._drgSrc && e.dataTransfer) {
                    wjcCore._startDrag(e.dataTransfer, 'copyMove');
                    e.stopPropagation();
                }
                else {
                    e.preventDefault();
                }
            }
        };
        _TreeDragDropManager.prototype._dragover = function (e) {
            this._handleDragDrop(e, false);
        };
        _TreeDragDropManager.prototype._drop = function (e) {
            this._handleDragDrop(e, true);
        };
        _TreeDragDropManager.prototype._dragend = function (e) {
            _TreeDragDropManager._drgSrc = null;
            this._showDragMarker();
            this._tree.onDragEnd();
        };
        _TreeDragDropManager.prototype._keydown = function (e) {
            if (!e.defaultPrevented) {
                if (e.keyCode == wjcCore.Key.Escape) {
                    this._dragendBnd(null);
                }
            }
        };
        _TreeDragDropManager.prototype._handleDragDrop = function (e, drop) {
            var tree = this._tree, ddm = _TreeDragDropManager, ee, dp = DropPosition, pos = dp.Into, rc;
            if (!e.defaultPrevented && ddm._drgSrc) {
                var element = document.elementFromPoint(e.clientX, e.clientY), target = wjcCore.closestClass(element, TreeView._CND);
                if (target == null) {
                    var tt = wjcCore.Control.getControl(wjcCore.closest(element, '.wj-treeview'));
                    if (tt instanceof TreeView && tt.totalItemCount == 0) {
                        target = tt.hostElement;
                    }
                }
                if (target == ddm._drgSrc.element) {
                    target = null;
                }
                if (target) {
                    rc = target.getBoundingClientRect();
                    var targetNode = new TreeNode(tree, target), szCheck = targetNode.hasPendingChildren ? rc.height / 2 : rc.height / 3;
                    if (targetNode.element == null) {
                        rc = wjcCore.Rect.fromBoundingRect(rc);
                        rc.inflate(-12, -12);
                        pos = dp.Before;
                    }
                    else if (e.clientY < rc.top + szCheck) {
                        pos = dp.Before;
                    }
                    else if (e.clientY > rc.bottom - szCheck || targetNode.hasPendingChildren) {
                        pos = dp.After;
                        if (targetNode.hasChildren && !targetNode.isCollapsed && !targetNode.hasPendingChildren) {
                            pos = dp.Before;
                            targetNode = targetNode.next(true, false);
                            target = targetNode.element;
                            rc = target.getBoundingClientRect();
                        }
                    }
                    if (ddm._drgSrc._contains(targetNode)) {
                        target = null;
                    }
                    else {
                        ee = new TreeNodeDragDropEventArgs(ddm._drgSrc, targetNode, pos);
                        ee.cancel = ddm._drgSrc.treeView != targetNode.treeView;
                        if (!tree.onDragOver(ee)) {
                            target = null;
                        }
                    }
                }
                if (target) {
                    pos = ee.position;
                    if (pos == dp.Before) {
                        var next = ee.dragSource.next(true, false);
                        if (next && next.element == target) {
                            target = null;
                        }
                    }
                    else if (pos == dp.After) {
                        var prev = ee.dragSource.previous(true, false);
                        if (prev && prev.element == target) {
                            target = null;
                        }
                    }
                }
                if (target && !drop) {
                    e.dataTransfer.dropEffect = 'move';
                    e.preventDefault();
                    e.stopPropagation();
                    this._showDragMarker(rc, pos);
                }
                else {
                    this._showDragMarker();
                }
                if (target && drop) {
                    if (tree.onDrop(ee)) {
                        tree.hostElement.focus();
                        var src = ee.dragSource;
                        src.move(ee.dropTarget, ee.position);
                        src.select();
                    }
                }
            }
        };
        _TreeDragDropManager.prototype._showDragMarker = function (rc, pos) {
            var tree = this._tree, parent = _TreeDragDropManager._dMarker.parentElement;
            if (rc) {
                var rcHost = tree.hostElement.getBoundingClientRect(), top_1 = pos == DropPosition.After ? rc.bottom : rc.top, css = {
                    top: Math.round(top_1 - rcHost.top + tree.hostElement.scrollTop - 2),
                    width: '75%',
                    height: pos == DropPosition.Into ? rc.height : 4,
                    opacity: pos == DropPosition.Into ? '0.15' : ''
                };
                if (tree.rightToLeft) {
                    css.right = Math.round(rcHost.right - rc.right);
                }
                else {
                    css.left = Math.round(rc.left - rcHost.left);
                }
                wjcCore.setCss(_TreeDragDropManager._dMarker, css);
                if (parent != tree._root) {
                    tree._root.appendChild(_TreeDragDropManager._dMarker);
                }
            }
            else {
                if (parent) {
                    parent.removeChild(_TreeDragDropManager._dMarker);
                }
            }
        };
        _TreeDragDropManager._dMarker = wjcCore.createElement('<div class="wj-marker">&nbsp;</div>');
        return _TreeDragDropManager;
    }());
    exports._TreeDragDropManager = _TreeDragDropManager;
    var _BindingArray = (function () {
        function _BindingArray(path) {
            this.path = path;
        }
        Object.defineProperty(_BindingArray.prototype, "path", {
            get: function () {
                return this._path;
            },
            set: function (value) {
                this._path = value;
                if (wjcCore.isString(value)) {
                    this._bindings = [
                        new wjcCore.Binding(value)
                    ];
                }
                else if (wjcCore.isArray(value)) {
                    this._bindings = [];
                    for (var i = 0; i < value.length; i++) {
                        this._bindings.push(new wjcCore.Binding(value[i]));
                    }
                }
                else if (value != null) {
                    wjcCore.assert(false, 'Path should be a string or an array of strings.');
                }
                this._maxLevel = this._bindings ? this._bindings.length - 1 : -1;
            },
            enumerable: true,
            configurable: true
        });
        _BindingArray.prototype.getValue = function (dataItem, level) {
            var index = Math.min(level, this._maxLevel);
            return index > -1 ? this._bindings[index].getValue(dataItem) : null;
        };
        _BindingArray.prototype.setValue = function (dataItem, level, value) {
            var index = Math.min(level, this._maxLevel);
            if (index > -1) {
                this._bindings[index].setValue(dataItem, value);
            }
        };
        return _BindingArray;
    }());
    exports._BindingArray = _BindingArray;
});
//# sourceMappingURL=wijmo.nav.js.map