"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getNativeTextPosition = exports.getMultilineTextHeight = exports.getTextHeightToBaseline = exports.getFirstLineHeightToBaseline = exports.getNativeTextSize = exports.convertToNativeLineSpacing = exports.wrapNativeText = void 0;
var NativeObject_1 = require("../Charting/Visuals/Helpers/NativeObject");
var AnchorPoint_1 = require("../types/AnchorPoint");
/**
 * Wrap a string by adding newline characters, splitting on spaces and wrapping to a maximum size
 */
var wrapNativeText = function (text, maxWidth, font, textBounds) {
    if (maxWidth === 0)
        return text;
    if (!text) {
        return "";
    }
    var lines = [];
    var words = text.split(" ");
    // calculate size of each word
    var first = words[0].trim();
    var allWords = first + " " + first + "\n" + words.map(function (w) { return w.trim(); }).join("\n");
    font.CalculateStringBounds(allWords !== null && allWords !== void 0 ? allWords : "", textBounds, 0);
    var line = "";
    var lineWidth = 0;
    var lineBounds0 = textBounds.GetLineBounds(0);
    var lineBounds1 = textBounds.GetLineBounds(1);
    var spaceWidth = lineBounds0.m_fWidth - 2 * lineBounds1.m_fWidth;
    lineBounds0.delete();
    lineBounds1.delete();
    for (var i = 0; i < words.length; i++) {
        var word = words[i];
        var lineBounds = textBounds.GetLineBounds(i + 1);
        var wordWidth = lineBounds.m_fWidth;
        lineBounds.delete();
        var newLine = line + (line !== "" ? " " : "") + word;
        lineWidth += (line !== "" ? spaceWidth : 0) + wordWidth;
        if (lineWidth > maxWidth) {
            if (line === "") {
                lines.push(word);
                lineWidth = 0;
            }
            else {
                lines.push(line);
                line = word;
                lineWidth = wordWidth;
            }
        }
        else {
            line = newLine;
        }
        if (line.endsWith("\n")) {
            lineWidth = 0;
        }
    }
    lines.push(line);
    return lines.join("\n");
};
exports.wrapNativeText = wrapNativeText;
var convertToNativeLineSpacing = function (maxLineHeight, lineSpacing) {
    // Extra spacing is needed to make nice default spacing for native text axis and chart titles
    var extraSpacingInPixels = 2;
    return Math.round(maxLineHeight * (lineSpacing - 1)) + extraSpacingInPixels;
};
exports.convertToNativeLineSpacing = convertToNativeLineSpacing;
var getNativeTextSize = function (text, nativeFont, textStyle, webAssemblyContext, rotation) {
    if (rotation === void 0) { rotation = 0; }
    var textBounds = (0, NativeObject_1.getTextBounds)(webAssemblyContext);
    nativeFont.CalculateStringBounds(text, textBounds, 0);
    var maxLineHeight = 0;
    for (var i = 0; i < textBounds.GetLinesCount(); i++) {
        var lineBounds_1 = textBounds.GetLineBounds(i);
        var lineHeight = lineBounds_1.m_fHeight;
        if (maxLineHeight < lineHeight) {
            maxLineHeight = lineHeight;
        }
        lineBounds_1.delete();
    }
    var nativeLineSpacing = (0, exports.convertToNativeLineSpacing)(maxLineHeight, textStyle.lineSpacing);
    var textHeight = Math.round(textBounds.m_fHeight +
        (textBounds.GetLinesCount() - 1) * nativeLineSpacing +
        textStyle.padding.top +
        textStyle.padding.bottom);
    var textWidth = Math.round(textBounds.m_fWidth + textStyle.padding.left + textStyle.padding.right);
    var lineBounds = textBounds.GetLineBounds(0);
    var firstLineAscent = (0, exports.getFirstLineHeightToBaseline)(lineBounds);
    lineBounds.delete();
    var rotationRad = ((rotation % 360) * Math.PI) / 180;
    var sin = Math.sin(rotationRad);
    var cos = Math.cos(rotationRad);
    // if (rotation % 180 === 0) {
    //     sin = 0;
    //     cos = 1;
    // } else if (rotation % 90 === 0) {
    //     sin = 1;
    //     cos = 0;
    // }
    var newTextureWidth = Math.round(textWidth * Math.abs(cos) + textHeight * Math.abs(sin));
    var newTextureHeight = Math.round(textWidth * Math.abs(sin) + textHeight * Math.abs(cos));
    var deltaX = 0;
    var deltaY = 0;
    if (rotation >= 0 && rotation < 90) {
        deltaX = (textHeight - textStyle.padding.top - firstLineAscent) * sin + textStyle.padding.left * cos;
        deltaY = textStyle.padding.left * sin + (textStyle.padding.top + firstLineAscent) * cos;
    }
    else if (rotation >= 90 && rotation <= 180) {
        deltaX = newTextureWidth - (textStyle.padding.top + firstLineAscent) * sin + textStyle.padding.left * cos;
        deltaY = -(textHeight - textStyle.padding.top - firstLineAscent) * cos + textStyle.padding.left * sin;
    }
    else if (rotation > 180 && rotation <= 270) {
        deltaX =
            newTextureWidth -
                (textStyle.padding.top + firstLineAscent - textHeight) * sin +
                textStyle.padding.left * cos;
        deltaY = newTextureHeight + (textStyle.padding.top + firstLineAscent) * cos + textStyle.padding.left * sin;
    }
    else if (rotation > 270 && rotation < 360) {
        deltaX = -(textStyle.padding.top + firstLineAscent) * sin + textStyle.padding.left * cos;
        deltaY =
            newTextureHeight -
                (textHeight - firstLineAscent - textStyle.padding.top) * cos +
                textStyle.padding.left * sin;
    }
    return {
        textHeight: newTextureHeight,
        textWidth: newTextureWidth,
        nativeLineSpacing: nativeLineSpacing,
        deltaX: deltaX,
        deltaY: deltaY
    };
};
exports.getNativeTextSize = getNativeTextSize;
/**
 * Calculates the height of the first line from top to baseline
 * @param textBounds
 * @returns
 */
var getFirstLineHeightToBaseline = function (lineBounds) {
    return lineBounds.m_fHeight + lineBounds.m_fOffsetY;
};
exports.getFirstLineHeightToBaseline = getFirstLineHeightToBaseline;
/**
 * For single line text return height to baseline. For multiline text returns total height
 */
var getTextHeightToBaseline = function (textBounds) {
    var cnt = textBounds.GetLinesCount();
    if (cnt < 1) {
        return 0;
    }
    else if (cnt === 1) {
        var lineBounds = textBounds.GetLineBounds(0);
        var height = (0, exports.getFirstLineHeightToBaseline)(lineBounds);
        lineBounds.delete();
        return height;
    }
    return (0, exports.getMultilineTextHeight)(textBounds);
};
exports.getTextHeightToBaseline = getTextHeightToBaseline;
/**
 * Calculates multiline text height from the top to the last line baseline
 */
var getMultilineTextHeight = function (textBounds) {
    var linesCount = textBounds.GetLinesCount();
    if (linesCount < 1) {
        return 0;
    }
    else if (linesCount === 1) {
        return textBounds.m_fHeight;
    }
    else {
        var res = textBounds.m_fHeight;
        for (var i = 0; i < linesCount - 1; i++) {
            var lineBounds = textBounds.GetLineBounds(i);
            res += lineBounds.m_fOffsetY;
            lineBounds.delete();
        }
        return res;
    }
};
exports.getMultilineTextHeight = getMultilineTextHeight;
/**
 *
 * @param x Text position X coordinate
 * @param y Text position Y coordinate
 * @param horizontalAnchorPoint Horizontal alignment
 * @param verticalAnchorPoint Vertical alignment
 * @param textBounds Text bounds
 * @param padding The padding
 * @returns x and y position where to draw text for SCRTFont.DrawStringAdvanced() method
 */
var getNativeTextPosition = function (x, y, horizontalAnchorPoint, verticalAnchorPoint, textBounds, padding) {
    var x1$ = x;
    var y1$ = y;
    if (horizontalAnchorPoint === AnchorPoint_1.EHorizontalAnchorPoint.Center) {
        x1$ -= textBounds.m_fWidth / 2 + (padding.right - padding.left) / 2;
    }
    else if (horizontalAnchorPoint === AnchorPoint_1.EHorizontalAnchorPoint.Right) {
        x1$ -= textBounds.m_fWidth + padding.right;
    }
    else {
        x1$ += padding.left;
    }
    var isMultiline = textBounds.GetLinesCount() > 1;
    var lineBounds = textBounds.GetLineBounds(0);
    if (!isMultiline) {
        if (verticalAnchorPoint === AnchorPoint_1.EVerticalAnchorPoint.Center) {
            y1$ += (0, exports.getFirstLineHeightToBaseline)(lineBounds) / 2 + (padding.top - padding.bottom) / 2;
        }
        else if (verticalAnchorPoint === AnchorPoint_1.EVerticalAnchorPoint.Top) {
            y1$ += (0, exports.getFirstLineHeightToBaseline)(lineBounds) + padding.top;
        }
        else {
            y1$ -= padding.bottom;
        }
    }
    else {
        if (verticalAnchorPoint === AnchorPoint_1.EVerticalAnchorPoint.Center) {
            y1$ +=
                (0, exports.getFirstLineHeightToBaseline)(lineBounds) -
                    (0, exports.getMultilineTextHeight)(textBounds) / 2 +
                    (padding.top - padding.bottom) / 2;
        }
        else if (verticalAnchorPoint === AnchorPoint_1.EVerticalAnchorPoint.Top) {
            y1$ += (0, exports.getFirstLineHeightToBaseline)(lineBounds) + padding.top;
        }
        else {
            y1$ += (0, exports.getFirstLineHeightToBaseline)(lineBounds) - (0, exports.getMultilineTextHeight)(textBounds);
            y1$ -= padding.bottom;
        }
    }
    lineBounds.delete();
    return { x: x1$, y: y1$ };
};
exports.getNativeTextPosition = getNativeTextPosition;
