"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var __values = (this && this.__values) || function(o) {
    var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
    if (m) return m.call(o);
    if (o && typeof o.length === "number") return {
        next: function () {
            if (o && i >= o.length) o = void 0;
            return { value: o && o[i++], done: !o };
        }
    };
    throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.TagsFactory = exports.AllTags = exports.NoTags = exports.AbstractTags = exports.TagInfo = exports.Label = void 0;
var TexParser_js_1 = __importDefault(require("./TexParser.js"));
var Label = (function () {
    function Label(tag, id) {
        if (tag === void 0) { tag = '???'; }
        if (id === void 0) { id = ''; }
        this.tag = tag;
        this.id = id;
    }
    return Label;
}());
exports.Label = Label;
var TagInfo = (function () {
    function TagInfo(env, taggable, defaultTags, tag, tagId, tagFormat, noTag, labelId) {
        if (env === void 0) { env = ''; }
        if (taggable === void 0) { taggable = false; }
        if (defaultTags === void 0) { defaultTags = false; }
        if (tag === void 0) { tag = null; }
        if (tagId === void 0) { tagId = ''; }
        if (tagFormat === void 0) { tagFormat = ''; }
        if (noTag === void 0) { noTag = false; }
        if (labelId === void 0) { labelId = ''; }
        this.env = env;
        this.taggable = taggable;
        this.defaultTags = defaultTags;
        this.tag = tag;
        this.tagId = tagId;
        this.tagFormat = tagFormat;
        this.noTag = noTag;
        this.labelId = labelId;
    }
    return TagInfo;
}());
exports.TagInfo = TagInfo;
var AbstractTags = (function () {
    function AbstractTags() {
        this.counter = 0;
        this.allCounter = 0;
        this.configuration = null;
        this.ids = {};
        this.allIds = {};
        this.labels = {};
        this.allLabels = {};
        this.redo = false;
        this.refUpdate = false;
        this.currentTag = new TagInfo();
        this.history = [];
        this.stack = [];
        this.enTag = function (node, tag) {
            var nf = this.configuration.nodeFactory;
            var cell = nf.create('node', 'mtd', [node]);
            var row = nf.create('node', 'mlabeledtr', [tag, cell]);
            var table = nf.create('node', 'mtable', [row], {
                side: this.configuration.options['tagSide'],
                minlabelspacing: this.configuration.options['tagIndent'],
                displaystyle: true
            });
            return table;
        };
    }
    AbstractTags.prototype.start = function (env, taggable, defaultTags) {
        if (this.currentTag) {
            this.stack.push(this.currentTag);
        }
        this.currentTag = new TagInfo(env, taggable, defaultTags);
    };
    Object.defineProperty(AbstractTags.prototype, "env", {
        get: function () {
            return this.currentTag.env;
        },
        enumerable: false,
        configurable: true
    });
    AbstractTags.prototype.end = function () {
        this.history.push(this.currentTag);
        this.currentTag = this.stack.pop();
    };
    AbstractTags.prototype.tag = function (tag, noFormat) {
        this.currentTag.tag = tag;
        this.currentTag.tagFormat = noFormat ? tag : this.formatTag(tag);
        this.currentTag.noTag = false;
    };
    AbstractTags.prototype.notag = function () {
        this.tag('', true);
        this.currentTag.noTag = true;
    };
    Object.defineProperty(AbstractTags.prototype, "noTag", {
        get: function () {
            return this.currentTag.noTag;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(AbstractTags.prototype, "label", {
        get: function () {
            return this.currentTag.labelId;
        },
        set: function (label) {
            this.currentTag.labelId = label;
        },
        enumerable: false,
        configurable: true
    });
    AbstractTags.prototype.formatUrl = function (id, base) {
        return base + '#' + encodeURIComponent(id);
    };
    AbstractTags.prototype.formatTag = function (tag) {
        return '(' + tag + ')';
    };
    AbstractTags.prototype.formatId = function (id) {
        return 'mjx-eqn:' + id.replace(/\s/g, '_');
    };
    AbstractTags.prototype.formatNumber = function (n) {
        return n.toString();
    };
    AbstractTags.prototype.autoTag = function () {
        if (this.currentTag.tag == null) {
            this.counter++;
            this.tag(this.formatNumber(this.counter), false);
        }
    };
    AbstractTags.prototype.clearTag = function () {
        this.label = '';
        this.tag(null, true);
        this.currentTag.tagId = '';
    };
    AbstractTags.prototype.getTag = function (force) {
        if (force === void 0) { force = false; }
        if (force) {
            this.autoTag();
            return this.makeTag();
        }
        var ct = this.currentTag;
        if (ct.taggable && !ct.noTag) {
            if (ct.defaultTags) {
                this.autoTag();
            }
            if (ct.tag) {
                return this.makeTag();
            }
        }
        return null;
    };
    AbstractTags.prototype.resetTag = function () {
        this.history = [];
        this.redo = false;
        this.refUpdate = false;
        this.clearTag();
    };
    AbstractTags.prototype.reset = function (offset) {
        if (offset === void 0) { offset = 0; }
        this.resetTag();
        this.counter = this.allCounter = offset;
        this.allLabels = {};
        this.allIds = {};
    };
    AbstractTags.prototype.startEquation = function (math) {
        this.history = [];
        this.stack = [];
        this.clearTag();
        this.currentTag = new TagInfo('', undefined, undefined);
        this.labels = {};
        this.ids = {};
        this.counter = this.allCounter;
        this.redo = false;
        var recompile = math.inputData.recompile;
        if (recompile) {
            this.refUpdate = true;
            this.counter = recompile.counter;
        }
    };
    AbstractTags.prototype.finishEquation = function (math) {
        if (this.redo) {
            math.inputData.recompile = {
                state: math.state(),
                counter: this.allCounter
            };
        }
        if (!this.refUpdate) {
            this.allCounter = this.counter;
        }
        Object.assign(this.allIds, this.ids);
        Object.assign(this.allLabels, this.labels);
    };
    AbstractTags.prototype.finalize = function (node, env) {
        if (!env.display || this.currentTag.env ||
            this.currentTag.tag == null) {
            return node;
        }
        var tag = this.makeTag();
        var table = this.enTag(node, tag);
        return table;
    };
    AbstractTags.prototype.makeId = function () {
        this.currentTag.tagId = this.formatId(this.configuration.options['useLabelIds'] ?
            (this.label || this.currentTag.tag) : this.currentTag.tag);
    };
    AbstractTags.prototype.makeTag = function () {
        this.makeId();
        if (this.label) {
            this.labels[this.label] = new Label(this.currentTag.tag, this.currentTag.tagId);
        }
        var mml = new TexParser_js_1.default('\\text{' + this.currentTag.tagFormat + '}', {}, this.configuration).mml();
        return this.configuration.nodeFactory.create('node', 'mtd', [mml], { id: this.currentTag.tagId });
    };
    return AbstractTags;
}());
exports.AbstractTags = AbstractTags;
var NoTags = (function (_super) {
    __extends(NoTags, _super);
    function NoTags() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    NoTags.prototype.autoTag = function () { };
    NoTags.prototype.getTag = function () {
        return !this.currentTag.tag ? null : _super.prototype.getTag.call(this);
    };
    return NoTags;
}(AbstractTags));
exports.NoTags = NoTags;
var AllTags = (function (_super) {
    __extends(AllTags, _super);
    function AllTags() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    AllTags.prototype.finalize = function (node, env) {
        if (!env.display || this.history.find(function (x) { return x.taggable; })) {
            return node;
        }
        var tag = this.getTag(true);
        return this.enTag(node, tag);
    };
    return AllTags;
}(AbstractTags));
exports.AllTags = AllTags;
var TagsFactory;
(function (TagsFactory) {
    var tagsMapping = new Map([
        ['none', NoTags],
        ['all', AllTags]
    ]);
    var defaultTags = 'none';
    TagsFactory.OPTIONS = {
        tags: defaultTags,
        tagSide: 'right',
        tagIndent: '0.8em',
        useLabelIds: true,
        ignoreDuplicateLabels: false
    };
    TagsFactory.add = function (name, constr) {
        tagsMapping.set(name, constr);
    };
    TagsFactory.addTags = function (tags) {
        var e_1, _a;
        try {
            for (var _b = __values(Object.keys(tags)), _c = _b.next(); !_c.done; _c = _b.next()) {
                var key = _c.value;
                TagsFactory.add(key, tags[key]);
            }
        }
        catch (e_1_1) { e_1 = { error: e_1_1 }; }
        finally {
            try {
                if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
            }
            finally { if (e_1) throw e_1.error; }
        }
    };
    TagsFactory.create = function (name) {
        var constr = tagsMapping.get(name) || tagsMapping.get(defaultTags);
        if (!constr) {
            throw Error('Unknown tags class');
        }
        return new constr();
    };
    TagsFactory.setDefault = function (name) {
        defaultTags = name;
    };
    TagsFactory.getDefault = function () {
        return TagsFactory.create(defaultTags);
    };
})(TagsFactory = exports.TagsFactory || (exports.TagsFactory = {}));
//# sourceMappingURL=Tags.js.map