define(["require", "exports", "tslib", "d3-selection", "./index", "../components/Legends/Legends.styles"], function (require, exports, tslib_1, d3_selection_1, index_1, Legends_styles_1) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    exports.cloneLegendsToSVG = exports.toImage = void 0;
    function toImage(chartContainer, legendsToSvgCallback, isRTL, opts) {
        if (isRTL === void 0) { isRTL = false; }
        if (opts === void 0) { opts = {}; }
        return new Promise(function (resolve, reject) {
            if (!chartContainer) {
                return reject(new Error('Chart container is not defined'));
            }
            try {
                var background = typeof opts.background === 'string' ? (0, index_1.resolveCSSVariables)(chartContainer, opts.background) : 'transparent';
                var svg = toSVG(chartContainer, legendsToSvgCallback, isRTL, background);
                var svgData = new XMLSerializer().serializeToString(svg.node);
                var svgDataUrl = 'data:image/svg+xml;base64,' + btoa(unescapePonyfill(encodeURIComponent(svgData)));
                svgToPng(svgDataUrl, {
                    width: opts.width || svg.width,
                    height: opts.height || svg.height,
                    scale: opts.scale,
                })
                    .then(resolve)
                    .catch(reject);
            }
            catch (err) {
                return reject(err);
            }
        });
    }
    exports.toImage = toImage;
    var SVG_STYLE_PROPERTIES = ['display', 'fill', 'fill-opacity', 'opacity', 'stroke', 'stroke-width', 'transform'];
    var SVG_TEXT_STYLE_PROPERTIES = ['font-family', 'font-size', 'font-weight', 'text-anchor'];
    function toSVG(chartContainer, legendsToSvgCallback, isRTL, background) {
        var svg = chartContainer.querySelector('svg');
        if (!svg) {
            throw new Error('SVG not found');
        }
        var clonedSvg = (0, d3_selection_1.select)(svg.cloneNode(true))
            .attr('width', null)
            .attr('height', null)
            .attr('viewBox', null);
        var svgElements = svg.getElementsByTagName('*');
        var clonedSvgElements = clonedSvg.node().getElementsByTagName('*');
        for (var i = 0; i < svgElements.length; i++) {
            if (svgElements[i].tagName.toLowerCase() === 'text') {
                (0, index_1.copyStyle)(tslib_1.__spreadArray(tslib_1.__spreadArray([], SVG_STYLE_PROPERTIES, true), SVG_TEXT_STYLE_PROPERTIES, true), svgElements[i], clonedSvgElements[i]);
            }
            else {
                (0, index_1.copyStyle)(SVG_STYLE_PROPERTIES, svgElements[i], clonedSvgElements[i]);
            }
        }
        var _a = svg.getBoundingClientRect(), svgWidth = _a.width, svgHeight = _a.height;
        var legendGroup = typeof legendsToSvgCallback === 'function'
            ? legendsToSvgCallback(svgWidth, isRTL)
            : { node: null, width: 0, height: 0 };
        var w1 = Math.max(svgWidth, legendGroup.width);
        var h1 = svgHeight + legendGroup.height;
        if (legendGroup.node) {
            (0, d3_selection_1.select)(legendGroup.node).attr('transform', "translate(0, ".concat(svgHeight, ")"));
            clonedSvg.append(function () { return legendGroup.node; });
        }
        clonedSvg
            .insert('rect', ':first-child')
            .attr('x', 0)
            .attr('y', 0)
            .attr('width', w1)
            .attr('height', h1)
            .attr('fill', background);
        clonedSvg
            .attr('width', w1)
            .attr('height', h1)
            .attr('viewBox', "0 0 ".concat(w1, " ").concat(h1))
            .attr('direction', isRTL ? 'rtl' : 'ltr');
        return {
            node: clonedSvg.node(),
            width: w1,
            height: h1,
        };
    }
    var LEGEND_TEXT_STYLE_PROPERTIES_MAP = {
        color: 'fill',
        'font-family': 'font-family',
        'font-size': 'font-size',
        'font-weight': 'font-weight',
    };
    function cloneLegendsToSVG(legends, svgWidth, config, legendContainer) {
        if (legends.length === 0) {
            return {
                node: null,
                width: 0,
                height: 0,
            };
        }
        var selectedLegends = config.selectedLegends, centerLegends = config.centerLegends, textClassName = config.textClassName, isRTL = config.isRTL;
        var legendGroup = (0, d3_selection_1.create)('svg:g');
        var legendX = centerLegends ? 0 : Legends_styles_1.LEGEND_CONTAINER_MARGIN_START;
        var legendY = Legends_styles_1.LEGEND_CONTAINER_MARGIN_TOP;
        var legendLine = [];
        var legendLines = [];
        var legendLineWidths = [];
        var noLegendsSelected = Object.keys(selectedLegends).length === 0;
        var _loop_1 = function (i) {
            var textOffset = Legends_styles_1.LEGEND_PADDING + Legends_styles_1.LEGEND_SHAPE_SIZE + Legends_styles_1.LEGEND_SHAPE_MARGIN_END;
            var legendText = (0, index_1.createMeasurementSpan)(legends[i].title, textClassName, legendContainer);
            var legendWidth = textOffset + legendText.getBoundingClientRect().width + Legends_styles_1.LEGEND_PADDING;
            var legendItem = legendGroup.append('g');
            legendLine.push({ elem: legendItem, width: legendWidth });
            if (legendX + legendWidth > svgWidth && legendLine.length > 1) {
                legendLine.pop();
                legendLines.push(legendLine);
                legendLineWidths.push(legendX);
                legendLine = [{ elem: legendItem, width: legendWidth }];
                legendX = centerLegends ? 0 : Legends_styles_1.LEGEND_CONTAINER_MARGIN_START;
                legendY += Legends_styles_1.LEGEND_HEIGHT;
            }
            var isLegendActive = selectedLegends[legends[i].title] || noLegendsSelected;
            legendItem
                .append('rect')
                .attr('x', legendX + (isRTL ? legendWidth - Legends_styles_1.LEGEND_PADDING - Legends_styles_1.LEGEND_SHAPE_SIZE : Legends_styles_1.LEGEND_PADDING))
                .attr('y', legendY + Legends_styles_1.LEGEND_PADDING)
                .attr('width', Legends_styles_1.LEGEND_SHAPE_SIZE)
                .attr('height', Legends_styles_1.LEGEND_SHAPE_SIZE)
                .style('fill', isLegendActive ? legends[i].color : 'transparent')
                .style('stroke-width', Legends_styles_1.LEGEND_SHAPE_BORDER)
                .style('stroke', legends[i].color);
            legendItem
                .append('text')
                .attr('x', legendX + (isRTL ? legendWidth - textOffset : textOffset))
                .attr('y', legendY + Legends_styles_1.LEGEND_PADDING)
                .attr('dominant-baseline', 'hanging')
                .style('opacity', isLegendActive ? 1 : Legends_styles_1.INACTIVE_LEGEND_TEXT_OPACITY)
                .text(legends[i].title)
                .call(function (selection) { return (0, index_1.copyStyle)(LEGEND_TEXT_STYLE_PROPERTIES_MAP, legendText, selection.node()); });
            legendX += legendWidth;
        };
        for (var i = 0; i < legends.length; i++) {
            _loop_1(i);
        }
        legendLines.push(legendLine);
        legendLineWidths.push(legendX);
        legendY += Legends_styles_1.LEGEND_HEIGHT;
        if (centerLegends) {
            legendLines.forEach(function (ln, idx) {
                var lineOffsetX = Math.max((svgWidth - legendLineWidths[idx]) / 2, 0);
                var remLineWidth = legendLineWidths[idx];
                var itemOffsetX = 0;
                ln.forEach(function (item) {
                    var newOffsetX = lineOffsetX + (isRTL ? remLineWidth - item.width - itemOffsetX : 0);
                    item.elem.attr('transform', "translate(".concat(newOffsetX, ", 0)"));
                    remLineWidth -= item.width;
                    itemOffsetX += item.width;
                });
            });
        }
        else if (isRTL) {
            var w1_1 = Math.max.apply(Math, tslib_1.__spreadArray([svgWidth], legendLineWidths, false));
            legendLines.forEach(function (ln) {
                var remLineWidth = w1_1 - Legends_styles_1.LEGEND_CONTAINER_MARGIN_START;
                var itemOffsetX = Legends_styles_1.LEGEND_CONTAINER_MARGIN_START;
                ln.forEach(function (item) {
                    var newOffsetX = remLineWidth - item.width - itemOffsetX;
                    item.elem.attr('transform', "translate(".concat(newOffsetX, ", 0)"));
                    remLineWidth -= item.width;
                    itemOffsetX += item.width;
                });
            });
        }
        return {
            node: legendGroup.node(),
            width: Math.max.apply(Math, legendLineWidths),
            height: legendY,
        };
    }
    exports.cloneLegendsToSVG = cloneLegendsToSVG;
    function svgToPng(svgDataUrl, opts) {
        if (opts === void 0) { opts = {}; }
        return new Promise(function (resolve, reject) {
            var scale = opts.scale || 1;
            var w0 = opts.width || 300;
            var h0 = opts.height || 150;
            var w1 = scale * w0;
            var h1 = scale * h0;
            var canvas = document.createElement('canvas');
            var img = new Image();
            canvas.width = w1;
            canvas.height = h1;
            img.onload = function () {
                var ctx = canvas.getContext('2d');
                if (!ctx) {
                    return reject(new Error('Canvas context is null'));
                }
                ctx.clearRect(0, 0, w1, h1);
                ctx.drawImage(img, 0, 0, w1, h1);
                var imgData = canvas.toDataURL('image/png');
                resolve(imgData);
            };
            img.onerror = function (err) {
                reject(err);
            };
            img.src = svgDataUrl;
        });
    }
    var hex2 = /^[\da-f]{2}$/i;
    var hex4 = /^[\da-f]{4}$/i;
    /**
     * A ponyfill for the deprecated `unescape` method, taken from the `core-js` library.
     *
     * Source: {@link https://github.com/zloirock/core-js/blob/167136f479d3b8519953f2e4c534ecdd1031d3cf/packages/core-js/modules/es.unescape.js core-js/packages/core-js/modules/es.unescape.js}
     */
    function unescapePonyfill(str) {
        var result = '';
        var length = str.length;
        var index = 0;
        var chr;
        var part;
        while (index < length) {
            chr = str.charAt(index++);
            if (chr === '%') {
                if (str.charAt(index) === 'u') {
                    part = str.slice(index + 1, index + 5);
                    if (hex4.exec(part)) {
                        result += String.fromCharCode(parseInt(part, 16));
                        index += 5;
                        continue;
                    }
                }
                else {
                    part = str.slice(index, index + 2);
                    if (hex2.exec(part)) {
                        result += String.fromCharCode(parseInt(part, 16));
                        index += 2;
                        continue;
                    }
                }
            }
            result += chr;
        }
        return result;
    }
});
//# sourceMappingURL=image-export-utils.js.map