import { genNumberType, Rect } from "./../../vrender";

import { Bounds, merge } from "@visactor/vutils";

import { getCellHoverColor } from "../../state/hover/is-cell-hover";

import { clearChartInstanceListByColumnDirection, clearChartInstanceListByRowDirection, generateChartInstanceListByColumnDirection, generateChartInstanceListByRowDirection } from "./active-cell-chart-list";

import { getAxisConfigInPivotChart } from "../../layout/chart-helper/get-axis-config";

export const CHART_NUMBER_TYPE = genNumberType();

export class Chart extends Rect {
    constructor(isShareChartSpec, params) {
        if (super(params), this.type = "chart", this.activeChartInstanceHoverOnMark = null, 
        this.justShowMarkTooltip = void 0, this.justShowMarkTooltipTimer = Date.now(), this.delayRunDimensionHoverTimer = void 0, 
        this.numberType = CHART_NUMBER_TYPE, this.isShareChartSpec = isShareChartSpec, params.chartInstance) this.chartInstance = params.chartInstance; else {
            const chartInstance = this.chartInstance = new params.ClassType(params.spec, merge({}, this.attribute.tableChartOption, {
                renderCanvas: params.canvas,
                mode: "node" === this.attribute.mode ? "node" : "desktop-browser",
                modeParams: this.attribute.modeParams,
                canvasControled: !1,
                viewBox: {
                    x1: 0,
                    x2: 0,
                    y1: 0,
                    y2: 0
                },
                dpr: params.dpr,
                interactive: !1,
                animation: !1,
                autoFit: !1
            }));
            chartInstance.renderSync(), chartInstance.getStage().enableDirtyBounds(), params.chartInstance = this.chartInstance = chartInstance;
        }
    }
    activate(table) {
        var _a, _b, _c, _d, _e;
        if (this.activeChartInstance) return;
        const {col: col, row: row} = this.parent, hoverColor = getCellHoverColor(this.parent, table), {x1: x1, y1: y1, x2: x2, y2: y2} = this.getViewBox(), clipBound = getTableBounds(col, row, table).intersect({
            x1: x1 - table.scrollLeft,
            x2: x2 - table.scrollLeft,
            y1: y1 - table.scrollTop,
            y2: y2 - table.scrollTop
        });
        null === (_a = this.activeChartInstance) || void 0 === _a || _a.release(), this.attribute.ClassType.globalConfig.uniqueTooltip = !1, 
        this.activeChartInstance = new this.attribute.ClassType(this.attribute.spec, merge({}, this.attribute.tableChartOption, {
            renderCanvas: this.attribute.canvas,
            mode: "desktop-browser",
            canvasControled: !1,
            viewBox: {
                x1: 0,
                x2: x2 - x1,
                y1: 0,
                y2: y2 - y1
            },
            dpr: table.internalProps.pixelRatio,
            animation: !1,
            interactive: !0,
            autoFit: !1,
            beforeRender: chartStage => {
                const stage = this.stage, ctx = chartStage.window.getContext(), stageMatrix = stage.window.getViewBoxTransform(), viewBox = stage.window.getViewBox();
                ctx.inuse = !0, ctx.clearMatrix(), ctx.setTransform(stageMatrix.a, stageMatrix.b, stageMatrix.c, stageMatrix.d, stageMatrix.e, stageMatrix.f, !0), 
                ctx.translate(viewBox.x1, viewBox.y1), ctx.setTransformForCurrent(!0), ctx.beginPath(), 
                ctx.rect(clipBound.x1, clipBound.y1, clipBound.x2 - clipBound.x1, clipBound.y2 - clipBound.y1), 
                ctx.clip(), ctx.clearMatrix(), table.options.canvas && !chartStage.needRender && (chartStage.pauseRender(), 
                table.scenegraph.stage.dirtyBounds.union(this.globalAABBBounds), table.scenegraph.updateNextFrame());
            },
            afterRender(stage) {
                stage.window.getContext().inuse = !1, stage.needRender = !1, chartStage.resumeRender();
            },
            renderHooks: {
                afterClearRect(drawParams) {
                    const {context: context, layer: layer, viewBox: viewBox} = drawParams;
                    layer.main && drawParams.clear && hoverColor && (context.beginPath(), context.fillStyle = hoverColor, 
                    context.rect(viewBox.x1, viewBox.y1, viewBox.x2 - viewBox.x1, viewBox.y2 - viewBox.y1), 
                    context.fill());
                }
            },
            componentShowContent: table.options.chartDimensionLinkage && "scatter" !== this.attribute.spec.type ? {
                tooltip: {
                    dimension: !1,
                    mark: !0
                },
                crosshair: !1
            } : void 0
        }));
        const chartStage = this.activeChartInstance.getStage(), matrix = this.globalTransMatrix.clone(), stageMatrix = this.stage.window.getViewBoxTransform();
        matrix.multiply(stageMatrix.a, stageMatrix.b, stageMatrix.c, stageMatrix.d, stageMatrix.e, stageMatrix.f), 
        chartStage.window.setViewBoxTransform && chartStage.window.setViewBoxTransform(matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f), 
        this.activeChartInstance.renderSync(), null === (_c = null === (_b = table.internalProps.layoutMap) || void 0 === _b ? void 0 : _b.updateDataStateToActiveChartInstance) || void 0 === _c || _c.call(_b, this.activeChartInstance), 
        this.activeChartInstance.on("click", (params => {
            var _a;
            !1 === (null === (_a = this.attribute.spec.select) || void 0 === _a ? void 0 : _a.enable) ? table.scenegraph.updateChartState(null) : Chart.temp && table.scenegraph.updateChartState(null == params ? void 0 : params.datum);
        })), this.activeChartInstance.on("brushEnd", (params => {
            var _a;
            table.scenegraph.updateChartState(null === (_a = null == params ? void 0 : params.value) || void 0 === _a ? void 0 : _a.inBrushData), 
            Chart.temp = 0, setTimeout((() => {
                Chart.temp = 1;
            }), 0);
        })), table.options.chartDimensionLinkage && this.activeChartInstance.on("dimensionHover", (params => {
            var _a, _b;
            const dimensionInfo = null == params ? void 0 : params.dimensionInfo[0], canvasXY = null === (_a = null == params ? void 0 : params.event) || void 0 === _a ? void 0 : _a.canvas, viewport = null === (_b = null == params ? void 0 : params.event) || void 0 === _b ? void 0 : _b.viewport;
            if (viewport) {
                const xValue = dimensionInfo.data[0].series.positionToDataX(viewport.x), yValue = dimensionInfo.data[0].series.positionToDataY(viewport.y);
                if ("scatter" === this.attribute.spec.type) {
                    generateChartInstanceListByColumnDirection(col, xValue, void 0, canvasXY, table, !1, !0), 
                    generateChartInstanceListByRowDirection(row, void 0, yValue, canvasXY, table, !1, !0);
                    getAxisConfigInPivotChart(table.rowHeaderLevelCount - 1, row, table.internalProps.layoutMap).labelHoverOnAxis && table.scenegraph.getCell(table.rowHeaderLevelCount - 1, row).firstChild.showLabelHoverOnAxis(canvasXY.y - table.getCellRelativeRect(col, row).top, yValue);
                    getAxisConfigInPivotChart(col, table.rowCount - table.bottomFrozenRowCount, table.internalProps.layoutMap).labelHoverOnAxis && table.scenegraph.getCell(col, table.rowCount - table.bottomFrozenRowCount).firstChild.showLabelHoverOnAxis(canvasXY.x - table.getCellRelativeRect(col, row).left, xValue);
                } else {
                    let justShowMarkTooltip = !0;
                    const preMark = this.activeChartInstanceHoverOnMark, prev_justShowMarkTooltip = this.justShowMarkTooltip;
                    params.mark && params.datum && !Array.isArray(params.datum) ? (this.activeChartInstanceHoverOnMark = params.mark, 
                    justShowMarkTooltip = !0) : (this.activeChartInstanceHoverOnMark = null, justShowMarkTooltip = !1), 
                    this.justShowMarkTooltip = justShowMarkTooltip;
                    let delayRunDimensionHover = !1;
                    if (!1 !== prev_justShowMarkTooltip && !1 === justShowMarkTooltip ? (this.justShowMarkTooltipTimer = Date.now(), 
                    delayRunDimensionHover = !0) : !1 === prev_justShowMarkTooltip && !1 === justShowMarkTooltip ? delayRunDimensionHover = Date.now() - this.justShowMarkTooltipTimer < 100 : (!1 === prev_justShowMarkTooltip && !0 === justShowMarkTooltip || !0 === prev_justShowMarkTooltip && !0 === justShowMarkTooltip) && (delayRunDimensionHover = !1, 
                    clearTimeout(this.delayRunDimensionHoverTimer), this.delayRunDimensionHoverTimer = void 0), 
                    "enter" === params.action || "move" === params.action || preMark !== this.activeChartInstanceHoverOnMark) {
                        const dimensionValue = dimensionInfo.value, indicatorsAsCol = table.options.indicatorsAsCol;
                        if (delayRunDimensionHover ? (clearTimeout(this.delayRunDimensionHoverTimer), this.delayRunDimensionHoverTimer = setTimeout((() => {
                            indicatorsAsCol ? generateChartInstanceListByRowDirection(row, dimensionValue, null, canvasXY, table, justShowMarkTooltip, !1) : generateChartInstanceListByColumnDirection(col, dimensionValue, null, canvasXY, table, justShowMarkTooltip, !1);
                        }), 100)) : indicatorsAsCol ? generateChartInstanceListByRowDirection(row, dimensionValue, null, canvasXY, table, justShowMarkTooltip, !1) : generateChartInstanceListByColumnDirection(col, dimensionValue, null, canvasXY, table, justShowMarkTooltip, !1), 
                        indicatorsAsCol) {
                            const series = dimensionInfo.data[0].series, width = "histogram" === this.attribute.spec.type || "line" === series.type || "area" === series.type ? 0 : series.getYAxisHelper().getBandwidth(0);
                            let y = series.valueToPositionY(dimensionValue);
                            const axisConfig = getAxisConfigInPivotChart(table.rowHeaderLevelCount - 1, row, table.internalProps.layoutMap);
                            let hoverOnLabelValue = yValue;
                            if ("histogram" === this.attribute.spec.type) {
                                const {series: series, datum: datum} = dimensionInfo.data[0];
                                if (datum.length > 0) {
                                    const rangeStartValue = datum[0][series.fieldY[0]], rangeEndValue = datum[0][series.fieldY2];
                                    hoverOnLabelValue = rangeStartValue + " ~ " + rangeEndValue, y = (series.valueToPositionY(rangeStartValue) + series.valueToPositionY(rangeEndValue)) / 2;
                                }
                            }
                            axisConfig.labelHoverOnAxis && table.scenegraph.getCell(table.rowHeaderLevelCount - 1, row).firstChild.showLabelHoverOnAxis(y + ("line" === series.type || "area" === series.type ? 0 : width / 2), hoverOnLabelValue);
                        } else {
                            const series = dimensionInfo.data[0].series, width = "histogram" === this.attribute.spec.type || "line" === series.type || "area" === series.type ? 0 : series.getXAxisHelper().getBandwidth(0);
                            let x = series.valueToPositionX(dimensionValue);
                            const axisConfig = getAxisConfigInPivotChart(col, table.rowCount - table.bottomFrozenRowCount, table.internalProps.layoutMap);
                            let hoverOnLabelValue = dimensionValue;
                            if ("histogram" === this.attribute.spec.type) {
                                const {series: series, datum: datum} = dimensionInfo.data[0];
                                if (datum.length > 0) {
                                    const rangeStartValue = datum[0][series.fieldX[0]], rangeEndValue = datum[0][series.fieldX2];
                                    hoverOnLabelValue = rangeStartValue + " ~ " + rangeEndValue, x = (series.valueToPositionX(rangeStartValue) + series.valueToPositionX(rangeEndValue)) / 2;
                                }
                            }
                            axisConfig.labelHoverOnAxis && table.scenegraph.getCell(col, table.rowCount - table.bottomFrozenRowCount).firstChild.showLabelHoverOnAxis(x + width / 2, hoverOnLabelValue);
                        }
                    }
                }
            }
        })), null === (_e = (_d = table)._bindChartEvent) || void 0 === _e || _e.call(_d, this.activeChartInstance);
    }
    deactivate(table, {releaseChartInstance: releaseChartInstance = !0, releaseColumnChartInstance: releaseColumnChartInstance = !0, releaseRowChartInstance: releaseRowChartInstance = !0} = {}) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
        if (this.activeChartInstanceHoverOnMark = null, this.justShowMarkTooltip = void 0, 
        this.justShowMarkTooltipTimer = Date.now(), clearTimeout(this.delayRunDimensionHoverTimer), 
        this.delayRunDimensionHoverTimer = void 0, releaseChartInstance) {
            null === (_a = this.activeChartInstance) || void 0 === _a || _a.updateViewBox({
                x1: -1e3,
                x2: -800,
                y1: -1e3,
                y2: -800
            }, !1, !1), null === (_b = this.activeChartInstance) || void 0 === _b || _b.release(), 
            this.activeChartInstance = null;
            const {col: col, row: row} = this.parent;
            table.internalProps.layoutMap.isAxisCell(table.rowHeaderLevelCount - 1, row) && (null === (_d = null === (_c = table.scenegraph.getCell(table.rowHeaderLevelCount - 1, row).firstChild) || void 0 === _c ? void 0 : _c.hideLabelHoverOnAxis) || void 0 === _d || _d.call(_c)), 
            table.internalProps.layoutMap.isAxisCell(col, table.rowCount - table.bottomFrozenRowCount) && (null === (_f = null === (_e = table.scenegraph.getCell(col, table.rowCount - table.bottomFrozenRowCount).firstChild) || void 0 === _e ? void 0 : _e.hideLabelHoverOnAxis) || void 0 === _f || _f.call(_e));
        } else {
            const {col: col, row: row} = this.parent;
            releaseColumnChartInstance && table.internalProps.layoutMap.isAxisCell(col, table.rowCount - table.bottomFrozenRowCount) && (null === (_h = null === (_g = table.scenegraph.getCell(col, table.rowCount - table.bottomFrozenRowCount).firstChild) || void 0 === _g ? void 0 : _g.hideLabelHoverOnAxis) || void 0 === _h || _h.call(_g)), 
            releaseRowChartInstance && table.internalProps.layoutMap.isAxisCell(table.rowHeaderLevelCount - 1, row) && (null === (_k = null === (_j = table.scenegraph.getCell(table.rowHeaderLevelCount - 1, row).firstChild) || void 0 === _j ? void 0 : _j.hideLabelHoverOnAxis) || void 0 === _k || _k.call(_j));
        }
        releaseColumnChartInstance && clearChartInstanceListByColumnDirection(this.parent.col, "scatter" === this.attribute.spec.type ? this.parent.row : void 0, table), 
        releaseRowChartInstance && clearChartInstanceListByRowDirection(this.parent.row, "scatter" === this.attribute.spec.type ? this.parent.col : void 0, table);
    }
    updateData(data) {
        this.attribute.data = data;
    }
    getViewBox() {
        var _a, _b, _c, _d, _e, _f, _g, _h;
        const cellGroup = this.parent, padding = this.attribute.cellPadding, table = this.stage.table, {x1: x1, y1: y1, x2: x2, y2: y2} = cellGroup.globalAABBBounds;
        return {
            x1: Math.ceil(x1 + padding[3] + table.scrollLeft + (null !== (_b = null === (_a = table.options.viewBox) || void 0 === _a ? void 0 : _a.x1) && void 0 !== _b ? _b : 0)),
            x2: Math.ceil(x1 + cellGroup.attribute.width - padding[1] + table.scrollLeft + (null !== (_d = null === (_c = table.options.viewBox) || void 0 === _c ? void 0 : _c.x1) && void 0 !== _d ? _d : 0)),
            y1: Math.ceil(y1 + padding[0] + table.scrollTop + (null !== (_f = null === (_e = table.options.viewBox) || void 0 === _e ? void 0 : _e.y1) && void 0 !== _f ? _f : 0)),
            y2: Math.ceil(y1 + cellGroup.attribute.height - padding[2] + table.scrollTop + (null !== (_h = null === (_g = table.options.viewBox) || void 0 === _g ? void 0 : _g.y1) && void 0 !== _h ? _h : 0))
        };
    }
}

function getTableBounds(col, row, table) {
    var _a, _b, _c, _d, _e, _f, _g, _h;
    const {layoutMap: layoutMap} = table.internalProps, bodyBound = new Bounds, tableBound = table.scenegraph.tableGroup.globalAABBBounds;
    return bodyBound.x1 = tableBound.x1, bodyBound.x2 = tableBound.x2, bodyBound.y1 = tableBound.y1, 
    bodyBound.y2 = tableBound.y2, layoutMap.isLeftBottomCorner(col, row) || layoutMap.isRightTopCorner(col, row) || layoutMap.isLeftTopCorner(col, row) || layoutMap.isRightBottomCorner(col, row) || (layoutMap.isFrozenColumn(col, row) ? (bodyBound.y1 = tableBound.y1 + table.getFrozenRowsHeight(), 
    bodyBound.y2 = tableBound.y2 - table.getBottomFrozenRowsHeight()) : layoutMap.isFrozenRow(col, row) ? (bodyBound.x1 = tableBound.x1 + table.getFrozenColsWidth(), 
    bodyBound.x2 = tableBound.x2 - table.getRightFrozenColsWidth()) : layoutMap.isRightFrozenColumn(col, row) ? (bodyBound.y1 = tableBound.y1 + table.getFrozenRowsHeight(), 
    bodyBound.y2 = tableBound.y2 - table.getBottomFrozenRowsHeight()) : layoutMap.isBottomFrozenRow(col, row) ? (bodyBound.x1 = tableBound.x1 + table.getFrozenColsWidth(), 
    bodyBound.x2 = tableBound.x2 - table.getRightFrozenColsWidth()) : layoutMap.isFrozenColumn(col, row) || layoutMap.isRightFrozenColumn(col, row) || (bodyBound.x1 = tableBound.x1 + table.getFrozenColsWidth(), 
    bodyBound.x2 = tableBound.x2 - table.getRightFrozenColsWidth(), bodyBound.y1 = tableBound.y1 + table.getFrozenRowsHeight(), 
    bodyBound.y2 = tableBound.y2 - table.getBottomFrozenRowsHeight())), bodyBound.x1 = bodyBound.x1 + (null !== (_b = null === (_a = table.options.viewBox) || void 0 === _a ? void 0 : _a.x1) && void 0 !== _b ? _b : 0), 
    bodyBound.x2 = bodyBound.x2 + (null !== (_d = null === (_c = table.options.viewBox) || void 0 === _c ? void 0 : _c.x1) && void 0 !== _d ? _d : 0), 
    bodyBound.y1 = bodyBound.y1 + (null !== (_f = null === (_e = table.options.viewBox) || void 0 === _e ? void 0 : _e.y1) && void 0 !== _f ? _f : 0), 
    bodyBound.y2 = bodyBound.y2 + (null !== (_h = null === (_g = table.options.viewBox) || void 0 === _g ? void 0 : _g.y1) && void 0 !== _h ? _h : 0), 
    bodyBound;
}

Chart.temp = 1;
//# sourceMappingURL=chart.js.map
