import * as tslib_1 from "tslib";
import { Component, Input, Output, EventEmitter, ViewEncapsulation, ChangeDetectionStrategy, forwardRef, ChangeDetectorRef, ElementRef, Renderer2, TemplateRef } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { TransferService } from '../transfer/transfer.service';
/*
 * Provider Expression that allows component to register as a ControlValueAccessor.
 * This allows it to support [(ngModel)].
 * @docs-private
 */
var TABLE_TRANSFER_VALUE_ACCESSOR = {
    provide: NG_VALUE_ACCESSOR,
    useExisting: forwardRef(function () { return TableTransferComponent; }),
    multi: true
};
var TableTransferComponent = /** @class */ (function () {
    function TableTransferComponent(_cd, el, _render, service) {
        this._cd = _cd;
        this.el = el;
        this._render = _render;
        this.service = service;
        /** get selected value event */
        this.getValue = new EventEmitter();
        /** search event */
        this.searchValue = new EventEmitter();
        /** tree node expand event */
        this.onExpandNode = new EventEmitter();
        /** tree node expand event */
        this.onExtendData = new EventEmitter();
        /**
         * selected list data
         * @default []
         */
        this.selectedData = [];
        /**
         * Whether the transfer is disabled
         * @default false
         */
        this.disabled = false;
        /**
         * Whether the transfer is can all-trans
         * @default false
         */
        this.allSelectLink = true;
        /**
         * Whether the transfer is can all-delete
         * @default false
         */
        this.allDeleteLink = true;
        /**
         * Whether the transfer is have candidate data search-box
         * @default false
         */
        this.candidateSearch = true;
        /**
         * Whether the transfer is have selected data search-box
         * @default false
         */
        this.selectedSearch = true;
        /**
         * candidate data list title
         */
        this.candidateTitle = '备选列表';
        /**
         * selected data list title
         */
        this.selectedTitle = '已选列表';
        /**
         * name length limit value
         */
        this.nameLenLimit = 6;
        /**
         * 右侧提示文案
         */
        this.rightNotice = '请从左侧选择内容';
        /**
         * 空数据字符串
         */
        this.emptyMessage = '暂无数据';
        /**
         * return method make object formatter to array
         * @docs-private
         */
        this._datasource = [];
        /**
         * return method make object formatter to array
         * @docs-private
         */
        this._allDatasource = [];
        /**
         * return method make object formatter to array
         * @docs-private
         */
        this.selectedDatasource = [];
        /**
         * return method make object formatter to array
         * @docs-private
         */
        this._selectedDatasource = [];
        /**
         * selected options's id as list
         * @docs-private
         */
        this.value = [];
        /**
         * return method make object formatter to array
         * @docs-private
         */
        this.objectKeys = Object.keys;
    }
    Object.defineProperty(TableTransferComponent.prototype, "candidateData", {
        get: function () {
            return this._datasource;
        },
        /**
         * candidate list data
         * @default []
         */
        set: function (val) {
            var value = val || [];
            this._datasource = value;
            this._allDatasource = value.slice();
        },
        enumerable: true,
        configurable: true
    });
    TableTransferComponent.prototype.ngOnChanges = function (changes) {
        var candidate = changes['candidateData'];
        var selected = changes['selectedData'];
        var candidateVal = candidate && candidate.currentValue;
        var selectedVal = selected && selected.currentValue;
        if ((selected && selectedVal && selectedVal.length)
            || (candidate && candidateVal && candidateVal.length)) {
            var datasourceLen = 0;
            var selectedLen_1 = 0;
            var ids_1 = selectedVal ? selectedVal : this.selectedData;
            var datasource = candidateVal ? candidateVal : this._datasource;
            // 根据已选id数组，从备选当中过滤出已选的数据，同时计算已选length
            if (datasource && datasource.length) {
                this.selectedDatasource = this.copy(datasource).filter(function (v) {
                    // 有二级节点
                    if (v.children) {
                        v.children = v.children.filter(function (child) {
                            return ids_1.includes(child.id);
                        });
                        selectedLen_1 += v.children.length;
                        return v.children.length;
                    }
                    else {
                        var exist = ids_1.includes(v.id);
                        if (exist) {
                            selectedLen_1 += 1;
                        }
                        return exist;
                    }
                });
                this.copySelectedData();
                // 计算备选length
                datasourceLen = this.leftCountChange(datasource);
                // 更新备选数据为选中状态
                datasource.forEach(function (v) {
                    // 有二级节点
                    if (v.children) {
                        v.children.forEach(function (child) {
                            child.selected = ids_1.includes(child.id);
                        });
                    }
                    else {
                        v.selected = ids_1.includes(v.id);
                    }
                });
                this.noticeCountChange(datasourceLen, selectedLen_1);
            }
        }
    };
    /**
     * linsten model change
     * @docs-private
     */
    TableTransferComponent.prototype.onModelChange = function () {
        var datasourceLen = this.leftCountChange();
        var selectedLen = this.rightCountChange();
        this.noticeCountChange(datasourceLen, selectedLen);
    };
    /**
     * 更新已选值，并将备选及已选数组length push给basic transfer
     */
    TableTransferComponent.prototype.noticeCountChange = function (datasourceLen, selectedLen) {
        if (this._onModelChange) {
            this._onModelChange(this.selectedData);
        }
        this.service.sendMsg({ candidateCount: datasourceLen, selectedCount: selectedLen });
    };
    /**
     * 计算备选数据length
     * @param data 备选数据，默认为全量备选数据
     */
    TableTransferComponent.prototype.leftCountChange = function (data) {
        if (data === void 0) { data = this._allDatasource; }
        var datasourceLen = 0;
        data.forEach(function (v) {
            if (v.children) {
                datasourceLen += v.children.length;
                return;
            }
            datasourceLen += 1;
        });
        return datasourceLen;
    };
    /**
     * 计算已选数据length
     */
    TableTransferComponent.prototype.rightCountChange = function () {
        var selectedLen = 0;
        var selectedData = [];
        this._selectedDatasource.forEach(function (v) {
            if (v.children) {
                selectedLen += v.children.length;
                v.children.forEach(function (child) {
                    selectedData.push(child.id);
                });
                return;
            }
            selectedData.push(v.id);
            selectedLen += 1;
        });
        this.selectedData = selectedData;
        return selectedLen;
    };
    /**
     * selected row
     * @param element selected row
     * @docs-private
     */
    TableTransferComponent.prototype.onSelect = function (element) {
        if (this.disabled || element.selected || element.disabled) {
            return;
        }
        var exists = this.selectedDatasource.some(function (item) { return item.id === element.id; });
        if (!exists) {
            this.selectedDatasource = this.selectedDatasource.concat([element]);
            this._selectedDatasource = this._selectedDatasource.concat([element]);
            element.selected = true;
            this._allDatasource.forEach(function (item) {
                item.selected = item.id === element.id ? true : item.selected;
            });
            this.getValue.emit(this.selectedDatasource);
            this.noticeCountChange(null, this.rightCountChange());
        }
    };
    /**
     * select child node
     * @param node current node
     */
    TableTransferComponent.prototype.onSelectChildNode = function (parent, element) {
        if (this.disabled || element.selected || element.disabled) {
            return;
        }
        // 判断当前选中节点在已选中是否有parent节点
        var exsit = this.selectedDatasource.filter(function (data) { return data.name === parent; });
        if (exsit.length) {
            this.selectedDatasource.forEach(function (v) {
                if (v.name === parent) {
                    v.children = v.children.concat(element);
                }
            });
        }
        else {
            this.selectedDatasource = this.selectedDatasource.concat({
                name: parent,
                children: [element]
            });
        }
        element.selected = true;
        this._allDatasource.forEach(function (item) {
            if (item.children) {
                item.children.forEach(function (child) {
                    child.selected = child.id === element.id ? true : child.selected;
                });
            }
        });
        this.copySelectedData();
        this.getValue.emit(this.selectedDatasource);
        this.noticeCountChange(null, this.rightCountChange());
    };
    /**
     * remove row
     * @param element remove row
     * @docs-private
     */
    TableTransferComponent.prototype.onRemove = function (element) {
        var _this = this;
        if (this.disabled) {
            return;
        }
        var selected = ['selectedDatasource', '_selectedDatasource'];
        var candidate = [this._datasource, this._allDatasource];
        var dataItem = this._datasource.find(function (v) { return v.id === element.id; });
        if (dataItem) {
            dataItem.selected = false;
        }
        selected.forEach(function (data) {
            _this[data] = _this[data].filter(function (item) { return item.id !== element.id; });
        });
        candidate.forEach(function (data) {
            data.forEach(function (item) {
                if (item.id === element.id) {
                    item.selected = false;
                }
            });
        });
        this.getValue.emit(this.selectedDatasource);
        this.noticeCountChange(null, this.rightCountChange());
    };
    /**
     * 删除选中的子节点
     * @param parent 父节点
     * @param element 子节点
     */
    TableTransferComponent.prototype.onRemoveChildNode = function (parent, element) {
        var _this = this;
        if (this.disabled) {
            return;
        }
        var candidate = [this._datasource, this._allDatasource];
        var selected = ['selectedDatasource', '_selectedDatasource'];
        selected.forEach(function (data) {
            _this[data] = _this.copy(_this[data]).filter(function (item) {
                if (item.name === parent) {
                    item.children = item.children.filter(function (child) { return child.id !== element.id; });
                }
                return item.children.length;
            });
        });
        candidate.forEach(function (data) {
            data.forEach(function (item) {
                if (item.name === parent) {
                    item.children.forEach(function (child) {
                        if (child.id === element.id) {
                            child.selected = false;
                        }
                    });
                }
            });
        });
        this.getValue.emit(this.selectedDatasource);
        this.noticeCountChange(null, this.rightCountChange());
    };
    TableTransferComponent.prototype.copy = function (data) {
        return JSON.parse(JSON.stringify(data));
    };
    /**
     * trans all or not trans all item
     * @param e trans option
     * @docs-private
     */
    TableTransferComponent.prototype.transAll = function (e) {
        if (this.disabled) {
            return;
        }
        var chkVal = e.chkVal;
        this.dataIterator(this._datasource, chkVal ? true : false);
        this.dataIterator(this._allDatasource, chkVal ? true : false);
        // 已选数据需要过滤掉备选中disabled的数据
        this.selectedDatasource = chkVal
            ? this.copy(this._allDatasource).filter(function (v) {
                if (v.children) {
                    v.children = v.children.filter(function (child) {
                        return !child.disabled;
                    });
                    return v.children.length;
                }
                return !v.disabled;
            })
            : [];
        this.copySelectedData();
        this.getValue.emit(this.selectedDatasource);
        this.noticeCountChange(null, this.rightCountChange());
    };
    /**
     * 数据遍历器
     * @param origin 待遍历的数据
     * @param bool
     */
    TableTransferComponent.prototype.dataIterator = function (origin, bool) {
        origin.forEach(function (v) {
            if (v.children) {
                v.children.forEach(function (child) {
                    if (!child.disabled) {
                        child.selected = bool;
                    }
                });
                return;
            }
            v.selected = bool;
        });
    };
    /**
     * fitler candidate or selected list by key word
     * @param e search key word
     * @docs-private
     */
    TableTransferComponent.prototype.searchByKeyWord = function (e) {
        var searchText = e.event;
        var mode = e.mode;
        var key = new RegExp(searchText.trim(), 'i');
        if (mode === 'candidate') {
            this._datasource = this.copy(this._allDatasource).filter(function (v) {
                if (v.children) {
                    v.children = v.children.filter(function (child) {
                        return child.name && child.name.match(key);
                    });
                    return v.children.length;
                }
                return v.name && v.name.match(key);
            });
        }
        else {
            this.selectedDatasource = this.copy(this._selectedDatasource).filter(function (v) {
                if (v.children) {
                    v.children = v.children.filter(function (child) {
                        return child.name && child.name.match(key);
                    });
                    return v.children.length;
                }
                return v.name && v.name.match(key);
            });
        }
    };
    /**
     * shallow copy selectedDatasource
     * @docs-private
     */
    TableTransferComponent.prototype.copySelectedData = function () {
        this._selectedDatasource = this.selectedDatasource.slice();
    };
    /**
     * throw out extend data event
     * @docs-private
     */
    TableTransferComponent.prototype.extendData = function () {
        if (this.disabled) {
            return;
        }
        this.onExtendData.emit();
    };
    /**
     * judge text length whether is over long or not
     * @docs-private
     */
    TableTransferComponent.prototype.judgeOverLong = function (event) {
        return event.length >= this.nameLenLimit ? true : false;
    };
    /**
     * toggle parent node, expand or shrink
     */
    TableTransferComponent.prototype.onToggle = function (item) {
        item.shrink = !item.shrink;
    };
    /**
     * Registers a callback that will be triggered when the value has changed.
     * Implemented as part of ControlValueAccessor.
     * @param fn On change callback function.
     */
    TableTransferComponent.prototype.registerOnChange = function (fn) {
        this._onModelChange = fn;
    };
    /**
     * Registers a callback that will be triggered when the control has been touched.
     * Implemented as part of ControlValueAccessor.
     * @param fn On touch callback function.
     */
    TableTransferComponent.prototype.registerOnTouched = function (fn) {
        this._onTouch = fn;
    };
    /**
     * set table-transfer model value
     * @docs-private
     */
    TableTransferComponent.prototype.writeValue = function (value) {
        var _this = this;
        // this.value = value;
        if (value != null) {
            this.selectedData = value;
            this.selectedDatasource = this._datasource
                .filter(function (v) { return _this.selectedData.includes(v.id); });
        }
        // this._cd.markForCheck();
    };
    /**
     * Toggles the disabled state of the component. Implemented as part of ControlValueAccessor.
     * @param isDisabled Whether the component should be disabled.
     */
    TableTransferComponent.prototype.setDisabledState = function (isDisabled) {
        this.disabled = isDisabled;
    };
    tslib_1.__decorate([
        Output(),
        tslib_1.__metadata("design:type", EventEmitter)
    ], TableTransferComponent.prototype, "getValue", void 0);
    tslib_1.__decorate([
        Output(),
        tslib_1.__metadata("design:type", EventEmitter)
    ], TableTransferComponent.prototype, "searchValue", void 0);
    tslib_1.__decorate([
        Output(),
        tslib_1.__metadata("design:type", EventEmitter)
    ], TableTransferComponent.prototype, "onExpandNode", void 0);
    tslib_1.__decorate([
        Output(),
        tslib_1.__metadata("design:type", EventEmitter)
    ], TableTransferComponent.prototype, "onExtendData", void 0);
    tslib_1.__decorate([
        Input(),
        tslib_1.__metadata("design:type", Object),
        tslib_1.__metadata("design:paramtypes", [Object])
    ], TableTransferComponent.prototype, "candidateData", null);
    tslib_1.__decorate([
        Input(),
        tslib_1.__metadata("design:type", Array)
    ], TableTransferComponent.prototype, "selectedData", void 0);
    tslib_1.__decorate([
        Input(),
        tslib_1.__metadata("design:type", Object)
    ], TableTransferComponent.prototype, "tableConfig", void 0);
    tslib_1.__decorate([
        Input(),
        tslib_1.__metadata("design:type", Boolean)
    ], TableTransferComponent.prototype, "disabled", void 0);
    tslib_1.__decorate([
        Input(),
        tslib_1.__metadata("design:type", String)
    ], TableTransferComponent.prototype, "customClass", void 0);
    tslib_1.__decorate([
        Input(),
        tslib_1.__metadata("design:type", Boolean)
    ], TableTransferComponent.prototype, "allSelectLink", void 0);
    tslib_1.__decorate([
        Input(),
        tslib_1.__metadata("design:type", Boolean)
    ], TableTransferComponent.prototype, "allDeleteLink", void 0);
    tslib_1.__decorate([
        Input(),
        tslib_1.__metadata("design:type", Boolean)
    ], TableTransferComponent.prototype, "candidateSearch", void 0);
    tslib_1.__decorate([
        Input(),
        tslib_1.__metadata("design:type", Boolean)
    ], TableTransferComponent.prototype, "selectedSearch", void 0);
    tslib_1.__decorate([
        Input(),
        tslib_1.__metadata("design:type", String)
    ], TableTransferComponent.prototype, "candidateTitle", void 0);
    tslib_1.__decorate([
        Input(),
        tslib_1.__metadata("design:type", String)
    ], TableTransferComponent.prototype, "selectedTitle", void 0);
    tslib_1.__decorate([
        Input(),
        tslib_1.__metadata("design:type", Object)
    ], TableTransferComponent.prototype, "addLink", void 0);
    tslib_1.__decorate([
        Input(),
        tslib_1.__metadata("design:type", Number)
    ], TableTransferComponent.prototype, "nameLenLimit", void 0);
    tslib_1.__decorate([
        Input(),
        tslib_1.__metadata("design:type", TemplateRef)
    ], TableTransferComponent.prototype, "optionTplLeft", void 0);
    tslib_1.__decorate([
        Input(),
        tslib_1.__metadata("design:type", TemplateRef)
    ], TableTransferComponent.prototype, "optionTplRight", void 0);
    tslib_1.__decorate([
        Input(),
        tslib_1.__metadata("design:type", String)
    ], TableTransferComponent.prototype, "rightNotice", void 0);
    tslib_1.__decorate([
        Input(),
        tslib_1.__metadata("design:type", TemplateRef)
    ], TableTransferComponent.prototype, "emptyTpl", void 0);
    tslib_1.__decorate([
        Input(),
        tslib_1.__metadata("design:type", String)
    ], TableTransferComponent.prototype, "emptyMessage", void 0);
    TableTransferComponent = tslib_1.__decorate([
        Component({
            selector: 'nb-table-transfer',
            template: "<nb-transfer (searchValue)=\"searchByKeyWord($event)\" (onTransAll)=\"transAll($event)\" (onExtendData)=\"extendData()\" [ngClass]=\"'customClass-' + customClass\" [allSelectLink]=\"allSelectLink\" [allDeleteLink]=\"allDeleteLink\" [candidateSearch]=\"candidateSearch\" [selectedSearch]=\"selectedSearch\" [candidateTitle]=\"candidateTitle\" [selectedTitle]=\"selectedTitle\" [addLink]=\"addLink\" [disabled]=\"disabled\"><nb-transfer-candidate><div class=\"origin-table-fixhead\"><table nb-table theme=\"small\"><thead nb-thead><tr nb-row><th *ngFor=\"let head of tableConfig.headData\" width=\"{{head.width}}\" field=\"\"><span class=\"field-title\">{{ head.name }}</span></th></tr></thead></table></div><div class=\"origin-table-body\"><table nb-table #nbTable theme=\"small\" [datasource]=\"candidateData\"><colgroup><ng-container *ngFor=\"let col of tableConfig.colWidth\"><col [ngStyle]=\"{'width': col + 'px'}\"></ng-container><col></colgroup><tbody nb-tbody *ngIf=\"candidateData.length\"><ng-container *ngFor=\"let data of candidateData\"><ng-container *ngIf=\"!data.children\"><tr nb-row [class.nb-table-row-selected]=\"data.selected\" [class.nb-table-row-disabled]=\"data.disabled || disabled\" (click)=\"onSelect(data)\"><ng-template [ngTemplateOutlet]=\"leftBodyTpl\" [ngTemplateOutletContext]=\"{$implicit: data}\"></ng-template></tr></ng-container><ng-container *ngIf=\"data.children\"><tr nb-row class=\"nb-table-row-parent\" [class.nb-table-row-selected]=\"data.selected\" [class.nb-table-row-disabled]=\"data.disabled || disabled\" (click)=\"onToggle(data)\"><td nb-td [colSpan]=\"tableConfig.headData.length + 1\"><div #toggleDivs class=\"icon-wrapper\"><i class=\"iconfont\" [class.icon-right]=\"data.shrink\" [class.icon-down]=\"!data.shrink\"></i> {{ data.name }}</div></td></tr><ng-container *ngIf=\"!data.shrink\"><tr *ngFor=\"let item of data.children\" nb-row [class.nb-table-row-selected]=\"item.selected\" [class.nb-table-row-disabled]=\"item.disabled || disabled\" (click)=\"onSelectChildNode(data.name, item)\"><ng-template [ngTemplateOutlet]=\"leftBodyTpl\" [ngTemplateOutletContext]=\"{$implicit: item}\"></ng-template></tr></ng-container></ng-container></ng-container></tbody><tbody nb-tbody *ngIf=\"!candidateData.length\"><tr nb-row class=\"nb-table-row-empty\"><td nb-td colspan=\"3\"><ng-container *ngIf=\"emptyTpl else defaultEmpty\"><ng-container *ngTemplateOutlet=\"emptyTpl;context: {$implicit: emptyMessage}\"></ng-container></ng-container><ng-template #defaultEmpty>{{ emptyMessage }}</ng-template></td></tr></tbody></table></div></nb-transfer-candidate><nb-transfer-selected><div *ngIf=\"selectedDatasource.length\" class=\"selected-list-content\"><ng-container *ngFor=\"let item of selectedDatasource\"><ng-container *ngIf=\"!item.children\"><div class=\"selected-item clearfix\" (click)=\"onRemove(item)\" [class.nb-table-row-disabled]=\"disabled\"><ng-template [ngTemplateOutlet]=\"rightBodyTpl\" [ngTemplateOutletContext]=\"{$implicit: item}\"></ng-template></div></ng-container><ng-container *ngIf=\"item.children\"><div class=\"selected-item clearfix\" (click)=\"onToggle(item)\"><div #toggleDivs class=\"icon-wrapper\"><i class=\"iconfont\" [class.icon-right]=\"item.shrink\" [class.icon-down]=\"!item.shrink\"></i> {{ item.name }}</div></div><ng-container *ngIf=\"!item.shrink\"><ng-container *ngFor=\"let child of item.children\"><div class=\"selected-item clearfix\" (click)=\"onRemoveChildNode(item.name, child)\" [class.nb-table-row-disabled]=\"disabled\"><div class=\"selected-children-item\"><ng-template [ngTemplateOutlet]=\"rightBodyTpl\" [ngTemplateOutletContext]=\"{$implicit: child}\"></ng-template></div></div></ng-container></ng-container></ng-container></ng-container></div><div *ngIf=\"!selectedDatasource.length\" class=\"nb-transfer-no-data\">{{ rightNotice }}</div></nb-transfer-selected></nb-transfer><ng-template #leftBodyTpl let-row><ng-container *ngFor=\"let key of objectKeys(row)\"><td *ngIf=\"!tableConfig.hideCol.includes(key) && key!=='selected'\" nb-td><div *ngIf=\"key!=='name'\" class=\"nb-td-{{key}}\">{{ row[key] }}</div><div *ngIf=\"key==='name' && row.description && !optionTplLeft\" class=\"nb-td-{{key}}\" nbTooltip=\"{{row.description}}\" nbTooltipClass=\"customize-classname\" placement=\"bottom-left\" hasArrow>{{ row[key] }}</div><div *ngIf=\"key==='name' && row.description && optionTplLeft\" class=\"nb-td-{{key}}\" nbTooltip=\"{{row.description}}\" nbTooltipClass=\"customize-classname\" placement=\"bottom-left\" hasArrow><ng-container *ngTemplateOutlet=\"optionTplLeft;context: {$implicit: row}\"></ng-container></div><div *ngIf=\"key==='name' && !row.description && !optionTplLeft\" class=\"nb-td-{{key}}\">{{ row[key] }}</div><div *ngIf=\"key==='name' && !row.description && optionTplLeft\" class=\"nb-td-{{key}}\"><ng-container *ngTemplateOutlet=\"optionTplLeft;context: {$implicit: row}\"></ng-container></div></td></ng-container><td nb-td><i class=\"iconfont icon-arrow-right\"></i> <i class=\"iconfont icon-check\"></i></td></ng-template><ng-template #rightBodyTpl let-item><div *ngIf=\"!optionTplRight\" class=\"group-name\">{{ item.name }}</div><div *ngIf=\"optionTplRight\"><ng-container *ngTemplateOutlet=\"optionTplRight;context: {$implicit: item}\"></ng-container></div><i class=\"iconfont icon-close\"></i></ng-template>",
            encapsulation: ViewEncapsulation.None,
            changeDetection: ChangeDetectionStrategy.OnPush,
            preserveWhitespaces: false,
            providers: [TABLE_TRANSFER_VALUE_ACCESSOR, TransferService],
            host: {
                'class': 'nb-widget nb-table-transfer'
            },
            exportAs: 'nbTableTransfer'
        }),
        tslib_1.__metadata("design:paramtypes", [ChangeDetectorRef,
            ElementRef,
            Renderer2,
            TransferService])
    ], TableTransferComponent);
    return TableTransferComponent;
}());
export { TableTransferComponent };
//# sourceMappingURL=table-transfer.js.map