"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.DataGrid = void 0;
var tslib_1 = require("tslib");
require("../../styles");
var React = require("react");
var rxjs_1 = require("rxjs");
var operators_1 = require("rxjs/operators");
var factory_1 = require("../../factory");
var render = require("../../render");
var common_1 = require("../common");
var libs_Handsontable_1 = require("../../common/libs.Handsontable");
var settings_1 = require("../settings");
var DataGrid_Overlay_1 = require("./DataGrid.Overlay");
var CSS = common_1.constants.CSS;
var DataGrid = (function (_super) {
    tslib_1.__extends(DataGrid, _super);
    function DataGrid() {
        var _this = _super !== null && _super.apply(this, arguments) || this;
        _this.state = {};
        _this.unmounted$ = new rxjs_1.Subject();
        _this.state$ = new rxjs_1.Subject();
        _this.elRef = function (ref) { return (_this.el = ref); };
        return _this;
    }
    DataGrid.prototype.componentDidMount = function () {
        var _this = this;
        var grid = (this.grid = this.props.grid);
        this.unmounted$.subscribe(function () { return grid.dispose(); });
        this.state$.pipe(operators_1.takeUntil(this.unmounted$)).subscribe(function (e) { return _this.setState(e); });
        var settings = settings_1.getSettings({ grid: grid });
        var Table = this.props.Handsontable || libs_Handsontable_1.Handsontable;
        var table = (this.table = new Table(this.el, settings));
        grid.initialize({ table: table });
        var factory = (this.factory = new factory_1.FactoryManager({ grid: grid, factory: this.props.factory }));
        render.registerAll(Table, grid, factory);
        var refs = {
            grid: grid,
            editorEvents$: new rxjs_1.Subject(),
            factory: this.factory,
        };
        table.__gridRefs = refs;
        var events$ = grid.events$, keyboard$ = grid.keyboard$;
        var editor$ = refs.editorEvents$.pipe(operators_1.takeUntil(this.unmounted$));
        var bubble$ = this.props.events$;
        if (bubble$) {
            events$.subscribe(function (e) { return bubble$.next(e); });
        }
        editor$.subscribe(function (e) { return _this.grid.fire(e); });
        events$
            .pipe(operators_1.filter(function (e) { return e.type === 'GRID/redraw'; }), operators_1.debounceTime(0))
            .subscribe(function () { return _this.redraw(); });
        keyboard$
            .pipe(operators_1.filter(function (e) { return e.metaKey && e.key === 'a'; }), operators_1.filter(function (e) { return _this.props.canSelectAll !== true; }), operators_1.filter(function (e) { return !grid.isEditing; }))
            .subscribe(function (e) { return e.cancel(); });
        this.updateSize();
        common_1.events.resize$.pipe(operators_1.takeUntil(this.unmounted$)).subscribe(function () { return _this.redraw(); });
        var hot = module.hot;
        if (hot) {
            hot.dispose(function () { return _this.dispose(); });
        }
        common_1.events.focus$
            .pipe(operators_1.takeUntil(this.unmounted$), operators_1.debounceTime(0), operators_1.filter(function (e) { return e.to !== document.body; }), operators_1.filter(function (e) { return !common_1.containsFocus(_this); }))
            .subscribe(function (e) { return _this.grid.deselect(); });
        this.init();
    };
    DataGrid.prototype.init = function () {
        return tslib_1.__awaiter(this, void 0, void 0, function () {
            var _a, initial, grid, selection, cell, ranges, cells;
            return tslib_1.__generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        if (this.isDisposed) {
                            return [2];
                        }
                        _a = this.props.initial, initial = _a === void 0 ? {} : _a;
                        grid = this.grid;
                        if (initial.selection) {
                            selection = typeof initial.selection === 'string' ? { cell: initial.selection } : initial.selection;
                            cell = selection.cell, ranges = selection.ranges;
                            grid.select({ cell: cell, ranges: ranges });
                        }
                        return [4, grid.calc.update()];
                    case 1:
                        _b.sent();
                        cells = grid.data.cells;
                        grid.changeCells(cells, { init: true, silent: true });
                        grid.mergeCells({ cells: cells, init: true });
                        grid.fire({ type: 'GRID/ready', payload: { grid: grid } });
                        this.forceUpdate();
                        return [2];
                }
            });
        });
    };
    DataGrid.prototype.componentWillUnmount = function () {
        this.dispose();
    };
    DataGrid.prototype.dispose = function () {
        this.unmounted$.next();
        this.unmounted$.complete();
    };
    Object.defineProperty(DataGrid.prototype, "isDisposed", {
        get: function () {
            return this.unmounted$.isStopped || this.grid.isDisposed;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(DataGrid.prototype, "isReady", {
        get: function () {
            return this.grid ? this.grid.isReady : false;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(DataGrid.prototype, "events$", {
        get: function () {
            return this.grid.events$;
        },
        enumerable: false,
        configurable: true
    });
    DataGrid.prototype.focus = function (isFocused) {
        if (common_1.defaultValue(isFocused, true)) {
            this.grid.focus();
        }
        else {
            this.grid.blur();
        }
        return this;
    };
    DataGrid.prototype.redraw = function () {
        this.updateSize();
        if (this.table) {
            this.table.render();
        }
        return this;
    };
    DataGrid.prototype.updateSize = function () {
        var el = this.el;
        if (!el || this.isDisposed) {
            return;
        }
        var width = el.offsetWidth, height = el.offsetHeight;
        var size = { width: width, height: height };
        this.state$.next({ size: size });
        return this;
    };
    DataGrid.prototype.render = function () {
        var factory = this.props.factory;
        var grid = this.grid;
        var styles = {
            base: common_1.css({
                position: 'relative',
                overflow: 'hidden',
            }),
            grid: common_1.css({
                Absolute: 0,
                userSelect: 'none',
                visibility: this.isReady ? 'visible' : 'hidden',
            }),
        };
        return (React.createElement("div", tslib_1.__assign({}, common_1.css(styles.base, this.props.style)),
            React.createElement("div", tslib_1.__assign({ ref: this.elRef, className: CSS.CLASS.GRID.BASE }, styles.grid)),
            grid && React.createElement(DataGrid_Overlay_1.DataGridOverlay, { grid: grid, factory: factory })));
    };
    return DataGrid;
}(React.PureComponent));
exports.DataGrid = DataGrid;
