import { ColorXform } from "./color-xform.js";
import { BooleanXform } from "../simple/boolean-xform.js";
import { IntegerXform } from "../simple/integer-xform.js";
import { StringXform } from "../simple/string-xform.js";
import { UnderlineXform } from "./underline-xform.js";
import { BaseXform } from "../base-xform.js";
// Font encapsulates translation from font model to xlsx
class FontXform extends BaseXform {
    constructor(options) {
        super();
        this.options = options || FontXform.OPTIONS;
        // Define properties in render order (Excel's expected order)
        const fontProperties = [
            { tag: "b", prop: "bold", xform: new BooleanXform({ tag: "b", attr: "val" }) },
            { tag: "i", prop: "italic", xform: new BooleanXform({ tag: "i", attr: "val" }) },
            { tag: "u", prop: "underline", xform: new UnderlineXform() },
            { tag: "strike", prop: "strike", xform: new BooleanXform({ tag: "strike", attr: "val" }) },
            {
                tag: "condense",
                prop: "condense",
                xform: new BooleanXform({ tag: "condense", attr: "val" })
            },
            { tag: "extend", prop: "extend", xform: new BooleanXform({ tag: "extend", attr: "val" }) },
            { tag: "outline", prop: "outline", xform: new BooleanXform({ tag: "outline", attr: "val" }) },
            { tag: "shadow", prop: "shadow", xform: new BooleanXform({ tag: "shadow", attr: "val" }) },
            { tag: "sz", prop: "size", xform: new IntegerXform({ tag: "sz", attr: "val" }) },
            { tag: "color", prop: "color", xform: new ColorXform() },
            {
                tag: this.options.fontNameTag,
                prop: "name",
                xform: new StringXform({ tag: this.options.fontNameTag, attr: "val" })
            },
            { tag: "family", prop: "family", xform: new IntegerXform({ tag: "family", attr: "val" }) },
            { tag: "scheme", prop: "scheme", xform: new StringXform({ tag: "scheme", attr: "val" }) },
            { tag: "charset", prop: "charset", xform: new IntegerXform({ tag: "charset", attr: "val" }) },
            {
                tag: "vertAlign",
                prop: "vertAlign",
                xform: new StringXform({ tag: "vertAlign", attr: "val" })
            }
        ];
        // Build map and renderOrder from single source of truth
        this.map = Object.fromEntries(fontProperties.map(p => [p.tag, { prop: p.prop, xform: p.xform }]));
        this.renderOrder = fontProperties.map(p => p.tag);
    }
    get tag() {
        return this.options.tagName;
    }
    render(xmlStream, model) {
        const { map, renderOrder } = this;
        xmlStream.openNode(this.options.tagName);
        renderOrder.forEach(tag => {
            map[tag].xform.render(xmlStream, model[map[tag].prop]);
        });
        xmlStream.closeNode();
    }
    parseOpen(node) {
        if (this.parser) {
            this.parser.parseOpen(node);
            return true;
        }
        if (this.map[node.name]) {
            this.parser = this.map[node.name].xform;
            return this.parser.parseOpen(node);
        }
        switch (node.name) {
            case this.options.tagName:
                this.model = {};
                return true;
            default:
                return false;
        }
    }
    parseText(text) {
        if (this.parser) {
            this.parser.parseText(text);
        }
    }
    parseClose(name) {
        if (this.parser && !this.parser.parseClose(name)) {
            const item = this.map[name];
            if (this.parser.model) {
                this.model[item.prop] = this.parser.model;
            }
            this.parser = undefined;
            return true;
        }
        switch (name) {
            case this.options.tagName:
                return false;
            default:
                return true;
        }
    }
}
FontXform.OPTIONS = {
    tagName: "font",
    fontNameTag: "name"
};
export { FontXform };
