import { normalizedStatsBuilder, round, getNumberOfBins } from '../internal';
import { isNumberColumn, isNumbersColumn, isMapAbleColumn } from '../model';
import InputNumberDialog from '../ui/dialogs/InputNumberDialog';
import { colorOf } from './impose';
import { ERenderMode } from './interfaces';
import { renderMissingDOM } from './missing';
import { cssClass } from '../styles';
import { histogramUpdate, histogramTemplate, mappingHintTemplate, mappingHintUpdate, filteredHistTemplate, initFilter } from './histogram';
/** @internal */
var HistogramCellRenderer = /** @class */ (function () {
    function HistogramCellRenderer() {
        this.title = 'Histogram';
    }
    HistogramCellRenderer.prototype.canRender = function (col, mode) {
        return (isNumberColumn(col) && mode !== ERenderMode.CELL) || (isNumbersColumn(col) && mode === ERenderMode.CELL);
    };
    HistogramCellRenderer.prototype.create = function (col, _context, imposer) {
        var _a = getHistDOMRenderer(col, imposer), template = _a.template, render = _a.render, guessedBins = _a.guessedBins;
        return {
            template: template + "</div>",
            update: function (n, row) {
                if (renderMissingDOM(n, col, row)) {
                    return;
                }
                var b = normalizedStatsBuilder(guessedBins);
                for (var _i = 0, _a = col.getNumbers(row); _i < _a.length; _i++) {
                    var n_1 = _a[_i];
                    b.push(n_1);
                }
                var hist = b.build();
                render(n, hist);
            }
        };
    };
    HistogramCellRenderer.prototype.createGroup = function (col, context, imposer) {
        var _a = getHistDOMRenderer(col, imposer), template = _a.template, render = _a.render;
        return {
            template: template + "</div>",
            update: function (n, group) {
                return context.tasks.groupNumberStats(col, group).then(function (r) {
                    if (typeof r === 'symbol') {
                        return;
                    }
                    var summary = r.summary, group = r.group;
                    render(n, group, summary);
                });
            }
        };
    };
    HistogramCellRenderer.prototype.createSummary = function (col, context, interactive, imposer) {
        var r = getHistDOMRenderer(col, imposer);
        var staticHist = !interactive || !isMapAbleColumn(col);
        return staticHist ? staticSummary(col, context, r.template, r.render) : interactiveSummary(col, context, r.template, r.render);
    };
    return HistogramCellRenderer;
}());
export default HistogramCellRenderer;
function staticSummary(col, context, template, render) {
    if (isMapAbleColumn(col)) {
        template += mappingHintTemplate(col.getRange());
    }
    return {
        template: template + "</div>",
        update: function (node) {
            if (isMapAbleColumn(col)) {
                mappingHintUpdate(node, col.getRange());
            }
            return context.tasks.summaryNumberStats(col).then(function (r) {
                if (typeof r === 'symbol') {
                    return;
                }
                var summary = r.summary;
                node.classList.toggle(cssClass('missing'), !summary);
                if (!summary) {
                    return;
                }
                render(node, summary);
            });
        }
    };
}
function interactiveSummary(col, context, template, render) {
    var fContext = createFilterContext(col, context);
    template += filteredHistTemplate(fContext, createFilterInfo(col));
    var updateFilter;
    return {
        template: template + "</div>",
        update: function (node) {
            if (!updateFilter) {
                updateFilter = initFilter(node, fContext);
            }
            return context.tasks.summaryNumberStats(col).then(function (r) {
                if (typeof r === 'symbol') {
                    return;
                }
                var summary = r.summary, data = r.data;
                updateFilter(data ? data.missing : (summary ? summary.missing : 0), createFilterInfo(col));
                node.classList.add(cssClass('histogram-i'));
                node.classList.toggle(cssClass('missing'), !summary);
                if (!summary) {
                    return;
                }
                render(node, summary, data);
            });
        }
    };
}
/** @internal */
export function getHistDOMRenderer(col, imposer) {
    var ranking = col.findMyRanker();
    var guessedBins = ranking ? getNumberOfBins(ranking.getOrderLength()) : 10;
    var formatter = col.getNumberFormat();
    var render = function (n, stats, unfiltered) {
        return histogramUpdate(n, stats, unfiltered || null, formatter, function (bin) { return colorOf(col, null, imposer, (bin.x1 + bin.x0) / 2); });
    };
    return {
        template: histogramTemplate(guessedBins),
        render: render,
        guessedBins: guessedBins
    };
}
function createFilterInfo(col) {
    var filter = col.getFilter();
    var domain = col.getMapping().domain;
    var filterMin = isFinite(filter.min) ? filter.min : domain[0];
    var filterMax = isFinite(filter.max) ? filter.max : domain[1];
    return {
        filterMissing: filter.filterMissing,
        filterMin: filterMin,
        filterMax: filterMax
    };
}
function createFilterContext(col, context) {
    var domain = col.getMapping().domain;
    var percent = function (v) { return Math.round(100 * (v - domain[0]) / (domain[1] - domain[0])); };
    var unpercent = function (v) { return ((v / 100) * (domain[1] - domain[0]) + domain[0]); };
    return {
        percent: percent,
        unpercent: unpercent,
        domain: domain,
        format: function (v) { return round(v, 2).toString(); },
        setFilter: function (filterMissing, minValue, maxValue) { return col.setFilter({
            filterMissing: filterMissing,
            min: Math.abs(minValue - domain[0]) < 0.001 ? NaN : minValue,
            max: Math.abs(maxValue - domain[1]) < 0.001 ? NaN : maxValue
        }); },
        edit: function (value, attachment) {
            return new Promise(function (resolve) {
                var dialogCtx = {
                    attachment: attachment,
                    manager: context.dialogManager,
                    level: 1,
                    idPrefix: context.idPrefix
                };
                var dialog = new InputNumberDialog(dialogCtx, resolve, {
                    value: value, min: domain[0], max: domain[1]
                });
                dialog.open();
            });
        }
    };
}
//# sourceMappingURL=HistogramCellRenderer.js.map