var fi_currentValue;
function fi_calcEqual(strequal, vnstyle = true) {
    if (vnstyle == true) {
        strequal = strequal.replaceAll(".", "");
        strequal = strequal.replaceAll(",", ".");
    }
    strequal = strequal.trim();
    if (strequal.length < 1) return strequal;
    if (strequal.substr(0, 1) == "=") {
        strequal = strequal.substr(1);
        strequal = strequal.trim();
        var parser = new Parser();
        strequal = parser.parse(strequal).evaluate();
    }

    return strequal;
}
function fi_doFormatCalc(input, vnstyle = true) {
    var value = input.value;
    value = fi_calcEqual(value, vnstyle);
    value = value.toString();
    input.value = fi_formatNumber(value.replaceAll(fi_getCommaSeparator(), '.'));
    input.onchange();
}
function fi_doFormat(input) {
    if (event.keyCode == 13) {
        return fi_doFormatCalc(input);
    }
    var valueBefore = input.value;
    //dang cong thuc - bo qua
    if (valueBefore.substr(0, 1) == "=") {
        fi_currentValue = "";
        return;
    }

    var cursorPosition = fi_getCaretPosition(input);
    var lengthBefore = input.value.length;
    var specialCharsBefore = fi_getSpecialCharsOnSides(input.value);
    var number = fi_removeThousandSeparators(input.value);

    //15-05-2024
    var negative = "";
    if (number.indexOf("-") >= 0) {
        negative = "-";
        number = number.replace("-", "");
        if (number.length < 1) return;
    }

    if (input.value == '') {
        fi_currentValue = "";
        return;
    }
    var fval = fi_formatNumber(number.replace(fi_getCommaSeparator(), '.'));

    //15-05-2024
    fval = fval.toLocaleLowerCase();
    if (fval == 'nan') {
        fi_currentValue = "";
        fval = '';
        input.value = fval;
        return;
    }
    input.value = negative + fval;

    // if deleting the comma, delete it correctly
    if (fi_currentValue == input.value && fi_currentValue == valueBefore.substr(0, cursorPosition) + fi_getThousandSeparator() + valueBefore.substr(cursorPosition)) {
        input.value = fi_formatNumber(fi_removeThousandSeparators(valueBefore.substr(0, cursorPosition - 1) + valueBefore.substr(cursorPosition)));
        cursorPosition--;
    }

    // if entering comma for separation, leave it in there (as well support .000)
    var commaSeparator = fi_getCommaSeparator();
    if (valueBefore.endsWith(commaSeparator) || valueBefore.endsWith(commaSeparator + '0') || valueBefore.endsWith(commaSeparator + '00') || valueBefore.endsWith(commaSeparator + '000')) {
        input.value = input.value + valueBefore.substring(valueBefore.indexOf(commaSeparator));
    }

    // move cursor correctly if thousand separator got added or removed
    var specialCharsAfter = fi_getSpecialCharsOnSides(input.value);
    if (specialCharsBefore[0] < specialCharsAfter[0]) {
        cursorPosition += specialCharsAfter[0] - specialCharsBefore[0];
    } else if (specialCharsBefore[0] > specialCharsAfter[0]) {
        cursorPosition -= specialCharsBefore[0] - specialCharsAfter[0];
    }
    fi_setCaretPosition(input, cursorPosition);

    fi_currentValue = input.value;
}

function fi_getSpecialCharsOnSides(x, cursorPosition) {
    var specialCharsLeft = x.substring(0, cursorPosition).replace(/[0-9]/g, '').length;
    var specialCharsRight = x.substring(cursorPosition).replace(/[0-9]/g, '').length;
    return [specialCharsLeft, specialCharsRight]
}

function fi_formatNumber(x) {
    return fi_getNumberFormat().format(x);
}

function fi_removeThousandSeparators(x) {
    return x.toString().replace(new RegExp(fi_escapeRegExp(fi_getThousandSeparator()), 'g'), "");
}

function fi_getThousandSeparator() {
    return fi_getNumberFormat().format('1000').replace(/[0-9]/g, '')[0];
}

function fi_getCommaSeparator() {
    return fi_getNumberFormat().format('0.01').replace(/[0-9]/g, '')[0];
}

function fi_getNumberFormat() {
    return new Intl.NumberFormat(['ban', 'id']);
}

/* From: http://stackoverflow.com/a/6969486/496992 */
function fi_escapeRegExp(str) {
    return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
}

/*
** Returns the caret (cursor) position of the specified text field.
** Return value range is 0-oField.value.length.
** From: http://stackoverflow.com/a/2897229/496992
*/
function fi_getCaretPosition(oField) {
    // Initialize
    var iCaretPos = 0;

    // IE Support
    if (document.selection) {

        // Set focus on the element
        oField.focus();

        // To get cursor position, get empty selection range
        var oSel = document.selection.createRange();

        // Move selection start to 0 position
        oSel.moveStart('character', -oField.value.length);

        // The caret position is selection length
        iCaretPos = oSel.text.length;
    }

    // Firefox support
    else if (oField.selectionStart || oField.selectionStart == '0')
        iCaretPos = oField.selectionStart;

    // Return results
    return iCaretPos;
}

/* From: http://stackoverflow.com/a/512542/496992 */
function fi_setCaretPosition(elem, caretPos) {
    if (elem != null) {
        if (elem.createTextRange) {
            var range = elem.createTextRange();
            range.move('character', caretPos);
            range.select();
        }
        else {
            if (elem.selectionStart) {
                elem.focus();
                elem.setSelectionRange(caretPos, caretPos);
            }
            else
                elem.focus();
        }
    }
}