import { dateStatsBuilder } from '../internal';
import { isDateColumn, isDatesColumn } from '../model';
import { cssClass } from '../styles';
import { ERenderMode } from './interfaces';
import { renderMissingDOM } from './missing';
import { colorOf } from './utils';
import { histogramUpdate, histogramTemplate, mappingHintTemplate, mappingHintUpdate, filteredHistTemplate, initFilter } from './histogram';
import InputDateDialog from '../ui/dialogs/InputDateDialog';
import { shiftFilterDateDay } from '../model/internalDate';
/** @internal */
var DateHistogramCellRenderer = /** @class */ (function () {
    function DateHistogramCellRenderer() {
        this.title = 'Histogram';
    }
    DateHistogramCellRenderer.prototype.canRender = function (col, mode) {
        return (isDateColumn(col) && mode !== ERenderMode.CELL) || (isDatesColumn(col) && mode === ERenderMode.CELL);
    };
    DateHistogramCellRenderer.prototype.create = function (col, _context) {
        var _a = getHistDOMRenderer(col), template = _a.template, render = _a.render;
        return {
            template: template + "</div>",
            update: function (n, row) {
                if (renderMissingDOM(n, col, row)) {
                    return;
                }
                var b = dateStatsBuilder();
                for (var _i = 0, _a = col.getDates(row); _i < _a.length; _i++) {
                    var n_1 = _a[_i];
                    b.push(n_1);
                }
                var hist = b.build();
                render(n, hist);
            }
        };
    };
    DateHistogramCellRenderer.prototype.createGroup = function (col, context) {
        var _a = getHistDOMRenderer(col), template = _a.template, render = _a.render;
        return {
            template: template + "</div>",
            update: function (n, group) {
                return context.tasks.groupDateStats(col, group).then(function (r) {
                    if (typeof r === 'symbol') {
                        return;
                    }
                    var group = r.group;
                    render(n, group);
                });
            }
        };
    };
    DateHistogramCellRenderer.prototype.createSummary = function (col, context, interactive) {
        var r = getHistDOMRenderer(col);
        return interactive ? interactiveSummary(col, context, r.template, r.render) : staticSummary(col, context, false, r.template, r.render);
    };
    return DateHistogramCellRenderer;
}());
export default DateHistogramCellRenderer;
function staticSummary(col, context, interactive, template, render) {
    template += mappingHintTemplate(['', '']);
    return {
        template: template + "</div>",
        update: function (node) {
            return context.tasks.summaryDateStats(col).then(function (r) {
                if (typeof r === 'symbol') {
                    return;
                }
                var summary = r.summary, data = r.data;
                node.classList.toggle(cssClass('missing'), !summary);
                if (!summary) {
                    return;
                }
                var formatter = col.getFormatter();
                mappingHintUpdate(node, [formatter(summary.min), formatter(summary.max)]);
                render(node, summary, interactive ? data : undefined);
            });
        }
    };
}
function interactiveSummary(col, context, template, render) {
    var filter = col.getFilter();
    var dummyDomain = [isFinite(filter.min) ? filter.min : 0, isFinite(filter.max) ? filter.max : 100];
    template += filteredHistTemplate(createFilterContext(col, context, dummyDomain), createFilterInfo(col, dummyDomain));
    var fContext;
    var updateFilter;
    return {
        template: template + "</div>",
        update: function (node) {
            return context.tasks.summaryDateStats(col).then(function (r) {
                if (typeof r === 'symbol') {
                    return;
                }
                var summary = r.summary, data = r.data;
                if (!updateFilter) {
                    fContext = createFilterContext(col, context, [data.min ? data.min.getTime() : Date.now(), data.max ? data.max.getTime() : Date.now()]);
                    updateFilter = initFilter(node, fContext);
                }
                updateFilter(data ? data.missing : (summary ? summary.missing : 0), createFilterInfo(col, fContext.domain));
                node.classList.add(cssClass('histogram-i'));
                node.classList.toggle(cssClass('missing'), !summary);
                if (!summary) {
                    return;
                }
                render(node, summary, data);
            });
        }
    };
}
function getHistDOMRenderer(col) {
    var guessedBins = 10;
    var formatter = col.getFormatter();
    var color = colorOf(col);
    var render = function (n, stats, unfiltered) {
        return histogramUpdate(n, stats, unfiltered || null, formatter, function () { return color; });
    };
    return {
        template: histogramTemplate(guessedBins),
        render: render,
        guessedBins: guessedBins
    };
}
function createFilterInfo(col, domain) {
    var filter = col.getFilter();
    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, 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 isNaN(v) ? '' : col.getFormatter()(new Date(v)); },
        setFilter: function (filterMissing, minValue, maxValue) { return col.setFilter({
            filterMissing: filterMissing,
            min: Math.abs(minValue - domain[0]) < 0.001 ? NaN : shiftFilterDateDay(minValue, 'min'),
            max: Math.abs(maxValue - domain[1]) < 0.001 ? NaN : shiftFilterDateDay(maxValue, 'max')
        }); },
        edit: function (value, attachment, type) {
            return new Promise(function (resolve) {
                var dialogCtx = {
                    attachment: attachment,
                    manager: context.dialogManager,
                    level: 1,
                    idPrefix: context.idPrefix
                };
                var dialog = new InputDateDialog(dialogCtx, function (d) { return resolve(d == null ? NaN : shiftFilterDateDay(d.getTime(), type)); }, { value: isNaN(value) ? null : new Date(value) });
                dialog.open();
            });
        }
    };
}
//# sourceMappingURL=DateHistogramCellRenderer.js.map