"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.VmlDrawingXform = void 0;
const xml_stream_1 = require("../../../utils/xml-stream.js");
const base_xform_1 = require("../base-xform.js");
const vml_shape_xform_1 = require("../comment/vml-shape-xform.js");
const form_control_1 = require("../../../form-control.js");
class VmlDrawingXform extends base_xform_1.BaseXform {
    constructor() {
        super();
        this.map = {
            "v:shape": new vml_shape_xform_1.VmlShapeXform()
        };
        this.model = { comments: [], formControls: [] };
    }
    get tag() {
        return "xml";
    }
    /**
     * Render VML drawing containing both notes and form controls
     */
    render(xmlStream, model) {
        const renderModel = model || this.model;
        const hasComments = renderModel.comments && renderModel.comments.length > 0;
        const hasFormControls = renderModel.formControls && renderModel.formControls.length > 0;
        xmlStream.openXml(xml_stream_1.XmlStream.StdDocAttributes);
        xmlStream.openNode(this.tag, VmlDrawingXform.DRAWING_ATTRIBUTES);
        // Shape layout - shared by both notes and form controls
        xmlStream.openNode("o:shapelayout", { "v:ext": "edit" });
        xmlStream.leafNode("o:idmap", { "v:ext": "edit", data: 1 });
        xmlStream.closeNode();
        // Shapetype 202 for notes/comments
        if (hasComments) {
            xmlStream.openNode("v:shapetype", {
                id: "_x0000_t202",
                coordsize: "21600,21600",
                "o:spt": 202,
                path: "m,l,21600r21600,l21600,xe"
            });
            xmlStream.leafNode("v:stroke", { joinstyle: "miter" });
            xmlStream.leafNode("v:path", { gradientshapeok: "t", "o:connecttype": "rect" });
            xmlStream.closeNode();
        }
        // Shapetype 201 for form control checkboxes
        if (hasFormControls) {
            xmlStream.openNode("v:shapetype", {
                id: "_x0000_t201",
                coordsize: "21600,21600",
                "o:spt": "201",
                path: "m,l,21600r21600,l21600,xe"
            });
            xmlStream.leafNode("v:stroke", { joinstyle: "miter" });
            xmlStream.leafNode("v:path", {
                shadowok: "f",
                "o:extrusionok": "f",
                strokeok: "f",
                fillok: "f",
                "o:connecttype": "rect"
            });
            xmlStream.leafNode("o:lock", { "v:ext": "edit", shapetype: "t" });
            xmlStream.closeNode();
        }
        // Render comment shapes
        if (hasComments) {
            const comments = renderModel.comments;
            for (let i = 0; i < comments.length; i++) {
                this.map["v:shape"].render(xmlStream, comments[i], i);
            }
        }
        // Render form control shapes
        if (hasFormControls) {
            for (const control of renderModel.formControls) {
                this._renderCheckboxShape(xmlStream, control);
            }
        }
        xmlStream.closeNode();
    }
    /**
     * Render a checkbox form control shape
     */
    _renderCheckboxShape(xmlStream, control) {
        const shapeAttrs = {
            id: `_x0000_s${control.shapeId}`,
            type: "#_x0000_t201",
            style: form_control_1.FormCheckbox.getVmlStyle(control),
            "o:insetmode": "auto",
            fillcolor: "buttonFace [67]",
            strokecolor: "windowText [64]",
            "o:preferrelative": "t",
            filled: "f",
            stroked: "f"
        };
        xmlStream.openNode("v:shape", shapeAttrs);
        // Fill element
        xmlStream.leafNode("v:fill", { "o:detectmouseclick": "t" });
        // Lock element
        xmlStream.leafNode("o:lock", { "v:ext": "edit", text: "t" });
        // Textbox for label
        if (control.text) {
            xmlStream.openNode("v:textbox", {
                style: "mso-direction-alt:auto",
                "o:singleclick": "t"
            });
            xmlStream.openNode("div", { style: "text-align:left" });
            xmlStream.openNode("font", { face: "Tahoma", size: "160", color: "auto" });
            xmlStream.writeText(control.text);
            xmlStream.closeNode(); // font
            xmlStream.closeNode(); // div
            xmlStream.closeNode(); // v:textbox
        }
        // ClientData - the core of the checkbox control
        xmlStream.openNode("x:ClientData", { ObjectType: "Checkbox" });
        // Match Excel's VML patterns (similar to Note ClientData): include positioning and cell address.
        // Omitting these can cause Excel to repair the sheet by dropping all legacy controls.
        xmlStream.leafNode("x:MoveWithCells");
        xmlStream.leafNode("x:SizeWithCells");
        // Anchor position
        xmlStream.openNode("x:Anchor");
        xmlStream.writeText(form_control_1.FormCheckbox.getVmlAnchor(control));
        xmlStream.closeNode();
        // Protection / text locking
        xmlStream.leafNode("x:Locked", undefined, "False");
        xmlStream.leafNode("x:LockText", undefined, "True");
        // Print settings
        xmlStream.leafNode("x:PrintObject", undefined, control.print ? "True" : "False");
        xmlStream.leafNode("x:AutoFill", undefined, "False");
        xmlStream.leafNode("x:AutoLine", undefined, "False");
        xmlStream.leafNode("x:TextHAlign", undefined, "Left");
        xmlStream.leafNode("x:TextVAlign", undefined, "Center");
        // Linked cell
        if (control.link) {
            xmlStream.leafNode("x:FmlaLink", undefined, control.link);
        }
        // 3D appearance
        if (control.noThreeD) {
            xmlStream.leafNode("x:NoThreeD");
        }
        // Checked state (0 = unchecked, 1 = checked, 2 = mixed)
        xmlStream.leafNode("x:Checked", undefined, String(form_control_1.FormCheckbox.getVmlCheckedValue(control)));
        // Cell address (0-based row/column)
        xmlStream.leafNode("x:Row", undefined, String(control.tl.row));
        xmlStream.leafNode("x:Column", undefined, String(control.tl.col));
        xmlStream.closeNode(); // x:ClientData
        xmlStream.closeNode(); // v:shape
    }
    // Parsing - delegate to VmlShapeXform for notes
    parseOpen(node) {
        if (this.parser) {
            this.parser.parseOpen(node);
            return true;
        }
        switch (node.name) {
            case this.tag:
                this.reset();
                this.model = {
                    comments: [],
                    formControls: []
                };
                break;
            default:
                this.parser = this.map[node.name];
                if (this.parser) {
                    this.parser.parseOpen(node);
                }
                break;
        }
        return true;
    }
    parseText(text) {
        if (this.parser) {
            this.parser.parseText(text);
        }
    }
    parseClose(name) {
        if (this.parser) {
            if (!this.parser.parseClose(name)) {
                this.model.comments.push(this.parser.model);
                this.parser = undefined;
            }
            return true;
        }
        switch (name) {
            case this.tag:
                return false;
            default:
                return true;
        }
    }
}
exports.VmlDrawingXform = VmlDrawingXform;
VmlDrawingXform.DRAWING_ATTRIBUTES = {
    "xmlns:v": "urn:schemas-microsoft-com:vml",
    "xmlns:o": "urn:schemas-microsoft-com:office:office",
    "xmlns:x": "urn:schemas-microsoft-com:office:excel"
};
