/**
 * DevExtreme (cjs/ui/number_box/number_box.caret.js)
 * Version: 23.2.6 (build 24140-0112)
 * Build date: Sun May 19 2024
 *
 * Copyright (c) 2012 - 2024 Developer Express Inc. ALL RIGHTS RESERVED
 * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/
 */
"use strict";
exports.getCaretBoundaries = exports.getCaretAfterFormat = void 0;
exports.getCaretInBoundaries = getCaretInBoundaries;
exports.isCaretInBoundaries = exports.getCaretWithOffset = exports.getCaretOffset = void 0;
var _math = require("../../core/utils/math");
var _common = require("../../core/utils/common");
var _number = _interopRequireDefault(require("../../localization/number"));
var _utils = require("./utils");

function _interopRequireDefault(obj) {
    return obj && obj.__esModule ? obj : {
        default: obj
    }
}
const getCaretBoundaries = function(text, format) {
    if ("string" === typeof format) {
        const signParts = format.split(";");
        const sign = _number.default.getSign(text, format);
        signParts[1] = signParts[1] || "-" + signParts[0];
        format = signParts[sign < 0 ? 1 : 0];
        const mockEscapedStubs = str => str.replace(/'([^']*)'/g, str => str.split("").map(() => " ").join("").substr(2));
        format = mockEscapedStubs(format);
        const prefixStubLength = /^[^#0.,]*/.exec(format)[0].length;
        const postfixStubLength = /[^#0.,]*$/.exec(format)[0].length;
        return {
            start: prefixStubLength,
            end: text.length - postfixStubLength
        }
    } else {
        return {
            start: 0,
            end: text.length
        }
    }
};
exports.getCaretBoundaries = getCaretBoundaries;
const _getDigitCountBeforeIndex = function(index, text) {
    const decimalSeparator = _number.default.getDecimalSeparator();
    const regExp = new RegExp("[^0-9" + (0, _common.escapeRegExp)(decimalSeparator) + "]", "g");
    const textBeforePosition = text.slice(0, index);
    return textBeforePosition.replace(regExp, "").length
};
const _reverseText = function(text) {
    return text.split("").reverse().join("")
};
const _getDigitPositionByIndex = function(digitIndex, text) {
    if (!digitIndex) {
        return -1
    }
    const regExp = /[0-9]/g;
    let counter = 1;
    let index = null;
    let result = regExp.exec(text);
    while (result) {
        index = result.index;
        if (counter >= digitIndex) {
            return index
        }
        counter++;
        result = regExp.exec(text)
    }
    return null === index ? text.length : index
};
const _trimNonNumericCharsFromEnd = function(text) {
    return text.replace(/[^0-9e]+$/, "")
};
const getCaretWithOffset = function(caret, offset) {
    if (void 0 === caret.start) {
        caret = {
            start: caret,
            end: caret
        }
    }
    return {
        start: caret.start + offset,
        end: caret.end + offset
    }
};
exports.getCaretWithOffset = getCaretWithOffset;
const getCaretAfterFormat = function(text, formatted, caret, format) {
    caret = getCaretWithOffset(caret, 0);
    const point = _number.default.getDecimalSeparator();
    const isSeparatorBasedText = isSeparatorBasedString(text);
    const realSeparatorOccurrenceIndex = (0, _utils.getRealSeparatorIndex)(format).occurrence;
    const pointPosition = isSeparatorBasedText ? 0 : (0, _utils.getNthOccurrence)(text, point, realSeparatorOccurrenceIndex);
    const newPointPosition = (0, _utils.getNthOccurrence)(formatted, point, realSeparatorOccurrenceIndex);
    const textParts = (0, _utils.splitByIndex)(text, pointPosition);
    const formattedParts = (0, _utils.splitByIndex)(formatted, newPointPosition);
    const isCaretOnFloat = -1 !== pointPosition && caret.start > pointPosition;
    if (isCaretOnFloat) {
        const relativeIndex = caret.start - pointPosition - 1;
        const digitsBefore = _getDigitCountBeforeIndex(relativeIndex, textParts[1]);
        const newPosition = formattedParts[1] ? newPointPosition + 1 + _getDigitPositionByIndex(digitsBefore, formattedParts[1]) + 1 : formatted.length;
        return getCaretInBoundaries(newPosition, formatted, format)
    } else {
        const formattedIntPart = _trimNonNumericCharsFromEnd(formattedParts[0]);
        const positionFromEnd = textParts[0].length - caret.start;
        const digitsFromEnd = _getDigitCountBeforeIndex(positionFromEnd, _reverseText(textParts[0]));
        const newPositionFromEnd = _getDigitPositionByIndex(digitsFromEnd, _reverseText(formattedIntPart));
        const newPositionFromBegin = formattedIntPart.length - (newPositionFromEnd + 1);
        return getCaretInBoundaries(newPositionFromBegin, formatted, format)
    }
};
exports.getCaretAfterFormat = getCaretAfterFormat;

function isSeparatorBasedString(text) {
    return 1 === text.length && !!text.match(/^[,.][0-9]*$/g)
}
const isCaretInBoundaries = function(caret, text, format) {
    caret = getCaretWithOffset(caret, 0);
    const boundaries = getCaretInBoundaries(caret, text, format);
    return caret.start >= boundaries.start && caret.end <= boundaries.end
};
exports.isCaretInBoundaries = isCaretInBoundaries;

function getCaretInBoundaries(caret, text, format) {
    caret = getCaretWithOffset(caret, 0);
    const boundaries = getCaretBoundaries(text, format);
    const adjustedCaret = {
        start: (0, _math.fitIntoRange)(caret.start, boundaries.start, boundaries.end),
        end: (0, _math.fitIntoRange)(caret.end, boundaries.start, boundaries.end)
    };
    return adjustedCaret
}
const getCaretOffset = function(previousText, newText, format) {
    const previousBoundaries = getCaretBoundaries(previousText, format);
    const newBoundaries = getCaretBoundaries(newText, format);
    return newBoundaries.start - previousBoundaries.start
};
exports.getCaretOffset = getCaretOffset;
