"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const archiver = require("archiver");
const path = require("path");
const xml = require("xml");
const media_1 = require("../../media");
const numbering_1 = require("../../numbering");
const properties_1 = require("../../properties");
const factory_1 = require("../../styles/factory");
const formatter_1 = require("../formatter");
const TEMPLATE_PATH = path.resolve(__dirname, "../../../template");
class Compiler {
    constructor(document, style, properties = new properties_1.Properties({
            creator: "Un-named",
            revision: "1",
            lastModifiedBy: "Un-named",
        }), numbering = new numbering_1.Numbering(), media = new media_1.Media()) {
        this.document = document;
        this.properties = properties;
        this.numbering = numbering;
        this.media = media;
        this.formatter = new formatter_1.Formatter();
        this.archive = archiver.create("zip", {});
        if (style) {
            this.style = style;
        }
        else {
            const stylesFactory = new factory_1.DefaultStylesFactory();
            this.style = stylesFactory.newInstance();
        }
        this.archive.on("error", (err) => {
            throw err;
        });
    }
    compile(output) {
        return __awaiter(this, void 0, void 0, function* () {
            this.archive.pipe(output);
            this.archive.glob("**", {
                cwd: TEMPLATE_PATH,
            });
            this.archive.glob("**/.rels", {
                cwd: TEMPLATE_PATH,
            });
            const xmlDocument = xml(this.formatter.format(this.document));
            const xmlStyles = xml(this.formatter.format(this.style));
            const xmlProperties = xml(this.formatter.format(this.properties), {
                declaration: {
                    standalone: "yes",
                    encoding: "UTF-8",
                },
            });
            const xmlNumbering = xml(this.formatter.format(this.numbering));
            this.archive.append(xmlDocument, {
                name: "word/document.xml",
            });
            this.archive.append(xmlStyles, {
                name: "word/styles.xml",
            });
            this.archive.append(xmlProperties, {
                name: "docProps/core.xml",
            });
            this.archive.append(xmlNumbering, {
                name: "word/numbering.xml",
            });
            for (const data of this.media.array) {
                this.archive.append(data.stream, {
                    name: `media/${data.fileName}`,
                });
            }
            this.archive.finalize();
            return new Promise((resolve) => {
                output.on("close", () => {
                    resolve();
                });
            });
        });
    }
}
exports.Compiler = Compiler;
//# sourceMappingURL=compiler.js.map