import { CdkCellDef, CdkHeaderCellDef, CdkFooterCellDef, CdkColumnDef, CdkHeaderCell, CdkFooterCell, CdkCell, CdkHeaderRowDef, CdkFooterRowDef, CdkRowDef, CdkHeaderRow, CDK_ROW_TEMPLATE, CdkFooterRow, CdkRow, CdkTable, CDK_TABLE_TEMPLATE, CdkTableModule, DataSource } from '@angular/cdk/table';
import { DOCUMENT, CommonModule } from '@angular/common';
import { Directive, EventEmitter, Input, ElementRef, Component, ChangeDetectionStrategy, ViewEncapsulation, NgZone, IterableDiffers, ChangeDetectorRef, Attribute, Optional, Inject, ContentChildren, Output, NgModule } from '@angular/core';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { Subject, defer, merge, BehaviorSubject, Subscription, combineLatest } from 'rxjs';
import { take, switchMap, startWith, takeUntil, filter, map } from 'rxjs/operators';
import { Directionality } from '@angular/cdk/bidi';
import { SelectionModel } from '@angular/cdk/collections';
import { Platform } from '@angular/cdk/platform';

var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var NtCellDefDirective_1, NtHeaderCellDefDirective_1, NtFooterCellDefDirective_1, NtColumnDirective_1;
var NtColumnSort;
(function (NtColumnSort) {
    NtColumnSort["ASC"] = "asc";
    NtColumnSort["DESC"] = "desc";
    NtColumnSort["NONE"] = "";
})(NtColumnSort || (NtColumnSort = {}));
class NtColumnSortChange {
    constructor(isUserInput = false, column, sort) {
        this.isUserInput = isUserInput;
        this.column = column;
        this.sort = sort;
    }
}
let NtCellDefDirective = NtCellDefDirective_1 = class NtCellDefDirective extends CdkCellDef {
};
NtCellDefDirective = NtCellDefDirective_1 = __decorate([
    Directive({
        selector: '[ntCellDef]',
        providers: [{ provide: CdkCellDef, useExisting: NtCellDefDirective_1 }]
    })
], NtCellDefDirective);
let NtHeaderCellDefDirective = NtHeaderCellDefDirective_1 = class NtHeaderCellDefDirective extends CdkHeaderCellDef {
};
NtHeaderCellDefDirective = NtHeaderCellDefDirective_1 = __decorate([
    Directive({
        selector: '[ntHeaderCellDef]',
        providers: [{ provide: CdkHeaderCellDef, useExisting: NtHeaderCellDefDirective_1 }]
    })
], NtHeaderCellDefDirective);
let NtFooterCellDefDirective = NtFooterCellDefDirective_1 = class NtFooterCellDefDirective extends CdkFooterCellDef {
};
NtFooterCellDefDirective = NtFooterCellDefDirective_1 = __decorate([
    Directive({
        selector: '[ntFooterCellDef]',
        providers: [{ provide: CdkFooterCellDef, useExisting: NtFooterCellDefDirective_1 }]
    })
], NtFooterCellDefDirective);
let NtColumnDirective = NtColumnDirective_1 = class NtColumnDirective extends CdkColumnDef {
    constructor() {
        super(...arguments);
        this._sortable = false;
        this.sort = NtColumnSort.NONE;
        this._sortChange = new EventEmitter();
    }
    set ntColumn(value) { this.name = value; }
    set sortable(value) { this._sortable = coerceBooleanProperty(value); }
    get sortable() { return this._sortable; }
    sorting(isUserInput = false) {
        if (this.sortable) {
            switch (this.sort) {
                case NtColumnSort.ASC:
                    this.sort = NtColumnSort.DESC;
                    break;
                case NtColumnSort.DESC:
                    this.sort = NtColumnSort.NONE;
                    break;
                default:
                    this.sort = NtColumnSort.ASC;
                    break;
            }
            this._sortChange.emit(new NtColumnSortChange(isUserInput, this.name, this.sort));
        }
    }
};
__decorate([
    Input('nt-column')
], NtColumnDirective.prototype, "ntColumn", null);
__decorate([
    Input()
], NtColumnDirective.prototype, "name", void 0);
__decorate([
    Input()
], NtColumnDirective.prototype, "sticky", void 0);
__decorate([
    Input()
], NtColumnDirective.prototype, "stickyEnd", void 0);
__decorate([
    Input()
], NtColumnDirective.prototype, "sortable", null);
NtColumnDirective = NtColumnDirective_1 = __decorate([
    Directive({
        selector: 'nt-column, [nt-column]',
        providers: [{ provide: CdkColumnDef, useExisting: NtColumnDirective_1 }],
    })
], NtColumnDirective);
let NtHeaderCellDirective = class NtHeaderCellDirective extends CdkHeaderCell {
    constructor(columnDef, elementRef) {
        super(columnDef, elementRef);
        this.columnDef = columnDef;
        elementRef.nativeElement.classList.add(`nt-column-${columnDef.cssClassFriendlyName}`);
    }
};
NtHeaderCellDirective.ctorParameters = () => [
    { type: NtColumnDirective },
    { type: ElementRef }
];
NtHeaderCellDirective = __decorate([
    Directive({
        selector: 'nt-header-cell, th[nt-header-cell]',
        host: {
            'class': 'nt-header-cell',
            '[class.nt-column-sortable]': 'columnDef.sortable',
            '[class.asc]': 'columnDef.sort === "asc"',
            '[class.desc]': 'columnDef.sort === "desc"',
            '(click)': 'columnDef.sorting(true)',
            'role': 'columnheader',
        },
    })
], NtHeaderCellDirective);
let NtFooterCellDirective = class NtFooterCellDirective extends CdkFooterCell {
    constructor(columnDef, elementRef) {
        super(columnDef, elementRef);
        elementRef.nativeElement.classList.add(`nt-column-${columnDef.cssClassFriendlyName}`);
    }
};
NtFooterCellDirective.ctorParameters = () => [
    { type: NtColumnDirective },
    { type: ElementRef }
];
NtFooterCellDirective = __decorate([
    Directive({
        selector: 'nt-footer-cell, td[nt-footer-cell]',
        host: {
            'class': 'nt-footer-cell',
            'role': 'gridcell',
        },
    })
], NtFooterCellDirective);
let NtCellDirective = class NtCellDirective extends CdkCell {
    constructor(columnDef, elementRef) {
        super(columnDef, elementRef);
        elementRef.nativeElement.classList.add(`nt-column-${columnDef.cssClassFriendlyName}`);
    }
};
NtCellDirective.ctorParameters = () => [
    { type: NtColumnDirective },
    { type: ElementRef }
];
NtCellDirective = __decorate([
    Directive({
        selector: 'nt-cell, td[nt-cell]',
        host: {
            'class': 'nt-cell',
            'role': 'gridcell',
        },
    })
], NtCellDirective);

var __decorate$1 = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
let NtTableResizable = class NtTableResizable {
    constructor() { }
};
NtTableResizable = __decorate$1([
    Directive({
        selector: 'table[ntTableResizable], nt-table[ntTableResizable]'
    })
], NtTableResizable);

var __decorate$2 = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var NtHeaderRowDefDirective_1, NtFooterRowDefDirective_1, NtRowDefDirective_1, NtHeaderRowComponent_1, NtFooterRowComponent_1, NtRowComponent_1;
let NtHeaderRowDefDirective = NtHeaderRowDefDirective_1 = class NtHeaderRowDefDirective extends CdkHeaderRowDef {
};
NtHeaderRowDefDirective = NtHeaderRowDefDirective_1 = __decorate$2([
    Directive({
        selector: '[ntHeaderRowDef]',
        providers: [{ provide: CdkHeaderRowDef, useExisting: NtHeaderRowDefDirective_1 }],
        inputs: ['columns: ntHeaderRowDef', 'sticky: ntHeaderRowDefSticky'],
    })
], NtHeaderRowDefDirective);
let NtFooterRowDefDirective = NtFooterRowDefDirective_1 = class NtFooterRowDefDirective extends CdkFooterRowDef {
};
NtFooterRowDefDirective = NtFooterRowDefDirective_1 = __decorate$2([
    Directive({
        selector: '[ntFooterRowDef]',
        providers: [{ provide: CdkFooterRowDef, useExisting: NtFooterRowDefDirective_1 }],
        inputs: ['columns: ntFooterRowDef', 'sticky: ntFooterRowDefSticky'],
    })
], NtFooterRowDefDirective);
let NtRowDefDirective = NtRowDefDirective_1 = class NtRowDefDirective extends CdkRowDef {
};
NtRowDefDirective = NtRowDefDirective_1 = __decorate$2([
    Directive({
        selector: '[ntRowDef]',
        providers: [{ provide: CdkRowDef, useExisting: NtRowDefDirective_1 }],
        inputs: ['columns: ntRowDefColumns', 'when: ntRowDefWhen'],
    })
], NtRowDefDirective);
let NtHeaderRowComponent = NtHeaderRowComponent_1 = class NtHeaderRowComponent extends CdkHeaderRow {
};
NtHeaderRowComponent = NtHeaderRowComponent_1 = __decorate$2([
    Component({
        selector: 'nt-header-row, tr[nt-header-row]',
        template: CDK_ROW_TEMPLATE,
        host: {
            'class': 'nt-header-row',
            'role': 'row',
        },
        changeDetection: ChangeDetectionStrategy.OnPush,
        encapsulation: ViewEncapsulation.None,
        exportAs: 'ntHeaderRow',
        providers: [{ provide: CdkHeaderRow, useExisting: NtHeaderRowComponent_1 }]
    })
], NtHeaderRowComponent);
let NtFooterRowComponent = NtFooterRowComponent_1 = class NtFooterRowComponent extends CdkFooterRow {
};
NtFooterRowComponent = NtFooterRowComponent_1 = __decorate$2([
    Component({
        selector: 'nt-footer-row, tr[nt-footer-row]',
        template: CDK_ROW_TEMPLATE,
        host: {
            'class': 'nt-footer-row',
            'role': 'row',
        },
        changeDetection: ChangeDetectionStrategy.OnPush,
        encapsulation: ViewEncapsulation.None,
        exportAs: 'ntFooterRow',
        providers: [{ provide: CdkFooterRow, useExisting: NtFooterRowComponent_1 }]
    })
], NtFooterRowComponent);
let NtRowComponent = NtRowComponent_1 = class NtRowComponent extends CdkRow {
};
NtRowComponent = NtRowComponent_1 = __decorate$2([
    Component({
        selector: 'nt-row, tr[nt-row]',
        template: CDK_ROW_TEMPLATE,
        host: {
            'class': 'nt-row',
            'role': 'row',
        },
        changeDetection: ChangeDetectionStrategy.OnPush,
        encapsulation: ViewEncapsulation.None,
        exportAs: 'ntRow',
        providers: [{ provide: CdkRow, useExisting: NtRowComponent_1 }]
    })
], NtRowComponent);

var __decorate$3 = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
let NtTableComponent = class NtTableComponent extends CdkTable {
    constructor(_ngZone, _differs, _changeDetectorRef, _elementRef, role, _dir, _document, _platform) {
        super(_differs, _changeDetectorRef, _elementRef, role, _dir, _document, _platform);
        this._ngZone = _ngZone;
        this._differs = _differs;
        this._changeDetectorRef = _changeDetectorRef;
        this._elementRef = _elementRef;
        this._dir = _dir;
        this._selectionModel = new SelectionModel(true, undefined, false);
        this._multiSortable = false;
        this._selectable = false;
        this._destroy = new Subject();
        this.columSortChanges = defer(() => {
            if (this._contentColumns) {
                return merge(...this._contentColumns.map(column => column._sortChange));
            }
            return this._ngZone.onStable
                .asObservable()
                .pipe(take(1), switchMap(() => this.columSortChanges));
        });
        this.selectedChange = new EventEmitter();
        this.sortChange = new EventEmitter();
    }
    set selectable(value) { this._selectable = coerceBooleanProperty(value); }
    get selectable() { return this._selectable; }
    get isAllSelected() { return false; }
    get selected() { return this._selectionModel.selected; }
    ngAfterContentInit() {
        this._contentColumns.changes.pipe(startWith(null), takeUntil(this._destroy)).subscribe(() => {
            this._resetOptions();
            this._changeDetectorRef.markForCheck();
        });
    }
    selectAll() {
        if (!this.isAllSelected) {
        }
        else {
            this._selectionModel.clear();
        }
        this.selectedChange.emit(this._selectionModel.selected);
    }
    select(item) {
        const wasSelected = this.checkSelected(item);
        if (wasSelected) {
            this._selectionModel.deselect(item);
        }
        else {
            this._selectionModel.select(item);
        }
        this.selectedChange.emit(this._selectionModel.selected);
    }
    ngOnChanges(change) {
        if (change && change.dataSource && !change.dataSource.firstChange) {
            this._selectionModel.clear();
        }
    }
    checkSelected(item) {
        return this._selectionModel.isSelected(item);
    }
    _clearSort(filter) {
        this._contentColumns
            .filter(column => column.name !== (filter ? filter.column : ''))
            .forEach(column => column.sort = NtColumnSort.NONE);
        this._changeDetectorRef.markForCheck();
    }
    _resetOptions() {
        const changedOrDestroyed = merge(this._contentColumns.changes, this._destroy);
        this.columSortChanges
            .pipe(takeUntil(changedOrDestroyed), filter(event => event.isUserInput))
            .subscribe(event => {
            if (!this._multiSortable) {
                this._clearSort(event);
            }
            this.sortChange.emit(event);
        });
        merge(...this._contentColumns.map(column => column._sortChange))
            .pipe(takeUntil(changedOrDestroyed))
            .subscribe(() => {
            this._changeDetectorRef.markForCheck();
        });
    }
    ngOnDestroy() {
        this._destroy.next();
        this._destroy.complete();
        super.ngOnDestroy();
    }
};
NtTableComponent.ctorParameters = () => [
    { type: NgZone },
    { type: IterableDiffers },
    { type: ChangeDetectorRef },
    { type: ElementRef },
    { type: String, decorators: [{ type: Attribute, args: ['role',] }] },
    { type: Directionality, decorators: [{ type: Optional }] },
    { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] },
    { type: Platform }
];
__decorate$3([
    Input()
], NtTableComponent.prototype, "selectable", null);
__decorate$3([
    ContentChildren(NtColumnDirective)
], NtTableComponent.prototype, "_contentColumns", void 0);
__decorate$3([
    Output()
], NtTableComponent.prototype, "selectedChange", void 0);
__decorate$3([
    Output()
], NtTableComponent.prototype, "sortChange", void 0);
NtTableComponent = __decorate$3([
    Component({
        selector: 'nt-table, table[nt-table]',
        template: CDK_TABLE_TEMPLATE,
        encapsulation: ViewEncapsulation.None,
        changeDetection: ChangeDetectionStrategy.OnPush,
        host: {
            'class': 'nt-table'
        }
    }),
    __param(4, Attribute('role')),
    __param(5, Optional()),
    __param(6, Inject(DOCUMENT))
], NtTableComponent);

var __decorate$4 = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
const EXPORTS_DECLARATIONS = [
    NtTableComponent,
    NtTableResizable,
    NtCellDefDirective,
    NtCellDirective,
    NtColumnDirective,
    NtFooterCellDefDirective,
    NtFooterCellDirective,
    NtHeaderCellDefDirective,
    NtHeaderCellDirective,
    NtFooterRowComponent,
    NtFooterRowDefDirective,
    NtHeaderRowComponent,
    NtHeaderRowDefDirective,
    NtRowComponent,
    NtRowDefDirective
];
let NtTableModule = class NtTableModule {
};
NtTableModule = __decorate$4([
    NgModule({
        imports: [CommonModule, CdkTableModule],
        exports: EXPORTS_DECLARATIONS,
        declarations: EXPORTS_DECLARATIONS
    })
], NtTableModule);

class NtTableDataSource extends DataSource {
    constructor(initialData = []) {
        super();
        this._renderData = new BehaviorSubject([]);
        this._filter = new BehaviorSubject('');
        this._renderChangesSubscription = Subscription.EMPTY;
        this.filterPredicate = (data, filter) => {
            const accumulator = (currentTerm, key) => currentTerm + data[key];
            const dataStr = Object.keys(data).reduce(accumulator, '').toLowerCase();
            const transformedFilter = filter.trim().toLowerCase();
            return dataStr.indexOf(transformedFilter) !== -1;
        };
        this._data = new BehaviorSubject(initialData);
        this._updateChangeSubscription();
    }
    get data() { return this._data.value; }
    set data(data) { this._data.next(data); }
    get filter() { return this._filter.value; }
    set filter(filter) { this._filter.next(filter); }
    _updateChangeSubscription() {
        const dataStream = this._data;
        const filteredData = combineLatest(dataStream, this._filter)
            .pipe(map(([data]) => this._filterData(data)));
        this._renderChangesSubscription.unsubscribe();
        this._renderChangesSubscription = filteredData.subscribe(data => this._renderData.next(data));
    }
    _filterData(data) {
        this.filteredData =
            !this.filter ? data : data.filter(obj => this.filterPredicate(obj, this.filter));
        return this.filteredData;
    }
    connect() { return this._renderData; }
    disconnect() { }
}

export { NtCellDefDirective, NtCellDirective, NtColumnDirective, NtColumnSort, NtColumnSortChange, NtFooterCellDefDirective, NtFooterCellDirective, NtFooterRowComponent, NtFooterRowDefDirective, NtHeaderCellDefDirective, NtHeaderCellDirective, NtHeaderRowComponent, NtHeaderRowDefDirective, NtRowComponent, NtRowDefDirective, NtTableComponent, NtTableDataSource, NtTableModule, NtTableResizable };
//# sourceMappingURL=table.js.map
