"use strict";
/**
 * @file 扩展 codemirror
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.FormulaPlugin = exports.editorFactory = void 0;
var helper_1 = require("../../utils/helper");
function editorFactory(dom, cm, props) {
    registerLaunguageMode(cm);
    return cm(dom, {
        value: props.value || '',
        autofocus: true,
        mode: props.evalMode ? 'text/formula' : 'text/formula-template'
    });
}
exports.editorFactory = editorFactory;
var FormulaPlugin = /** @class */ (function () {
    function FormulaPlugin(editor, cm, getProps) {
        this.editor = editor;
        this.cm = cm;
        this.getProps = getProps;
        // editor.on('change', this.autoMarkText);
        this.autoMarkText();
    }
    FormulaPlugin.prototype.autoMarkText = function () {
        var _a = this.getProps(), functions = _a.functions, variables = _a.variables, value = _a.value;
        if (value) {
            // todo functions 也需要自动替换
            this.autoMark(variables);
        }
    };
    FormulaPlugin.prototype.insertContent = function (value, type) {
        var from = this.editor.getCursor();
        if (type === 'variable') {
            this.editor.replaceSelection(value.key);
            var to = this.editor.getCursor();
            this.markText(from, to, value.name, 'cm-field');
        }
        else if (type === 'func') {
            // todo 支持 snippet，目前是不支持的
            this.editor.replaceSelection(value + "()");
            var to = this.editor.getCursor();
            this.markText(from, {
                line: to.line,
                ch: to.ch - 2
            }, value, 'cm-func');
            this.editor.setCursor({
                line: to.line,
                ch: to.ch - 1
            });
        }
        else if (typeof value === 'string') {
            this.editor.replaceSelection(value);
        }
        this.editor.focus();
    };
    FormulaPlugin.prototype.markText = function (from, to, label, className) {
        if (className === void 0) { className = 'cm-func'; }
        var text = document.createElement('span');
        text.className = className;
        text.innerText = label;
        this.editor.markText(from, to, {
            atomic: true,
            replacedWith: text
        });
    };
    FormulaPlugin.prototype.autoMark = function (variables) {
        var _this = this;
        if (!Array.isArray(variables) || !variables.length) {
            return;
        }
        var varMap = {};
        (0, helper_1.eachTree)(variables, function (item) { return item.value && (varMap[item.value] = item.label); });
        var vars = Object.keys(varMap).sort(function (a, b) { return b.length - a.length; });
        var editor = this.editor;
        var lines = editor.lineCount();
        var _loop_1 = function (line) {
            var content = editor.getLine(line);
            // 标记方法调用
            content.replace(/([A-Z]+)\s*\(/g, function (_, func, pos) {
                _this.markText({
                    line: line,
                    ch: pos
                }, {
                    line: line,
                    ch: pos + func.length
                }, func, 'cm-func');
                return _;
            });
            // 标记变量
            vars.forEach(function (v) {
                var from = 0;
                var idx = -1;
                while (~(idx = content.indexOf(v, from))) {
                    _this.markText({
                        line: line,
                        ch: idx
                    }, {
                        line: line,
                        ch: idx + v.length
                    }, varMap[v], 'cm-field');
                    from = idx + v.length;
                }
            });
        };
        for (var line = 0; line < lines; line++) {
            _loop_1(line);
        }
    };
    FormulaPlugin.prototype.dispose = function () { };
    FormulaPlugin.prototype.validate = function () { };
    return FormulaPlugin;
}());
exports.FormulaPlugin = FormulaPlugin;
var modeRegisted = false;
function registerLaunguageMode(cm) {
    if (modeRegisted) {
        return;
    }
    modeRegisted = true;
    // 对应 evalMode
    cm.defineMode('formula', function (config, parserConfig) {
        var formula = cm.getMode(config, 'javascript');
        if (!parserConfig || !parserConfig.base)
            return formula;
        return cm.multiplexingMode(cm.getMode(config, parserConfig.base), {
            open: '${',
            close: '}',
            mode: formula
        });
    });
    cm.defineMIME('text/formula', { name: 'formula' });
    cm.defineMIME('text/formula-template', { name: 'formula', base: 'htmlmixed' });
}
//# sourceMappingURL=./components/formula/plugin.js.map
