"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.domToUnit = domToUnit;
exports.domToBundle = domToBundle;
const id_1 = require("../../client/id");
const rawExtractStyle_1 = require("../../client/rawExtractStyle");
const fromUnitBundle_1 = require("../../spec/fromUnitBundle");
const component_1 = require("../../spec/reducers/component");
const spec_1 = require("../../spec/reducers/spec");
const util_1 = require("../../spec/util");
const _ids_1 = require("../../system/_ids");
const clone_1 = require("../clone");
const element_1 = require("../element");
const object_1 = require("../object");
const tagToId_1 = require("../tagToId");
function domToUnit(system, type, text, size) {
    const { specs, classes } = system;
    const bundle = domToBundle(system, type, text, size);
    const Class = (0, fromUnitBundle_1.fromUnitBundle)(bundle, specs, classes);
    return Class;
}
function domToBundle(system, type, text, size) {
    const { specs, api: { window: { DOMParser }, }, getSpec, newSpec, } = system;
    const parser = new DOMParser();
    const isSvg = type === 'image/svg+xml';
    const dom = parser.parseFromString(text, type);
    const html = dom.documentElement;
    let body;
    for (const child of html.childNodes) {
        if (child.nodeName === 'BODY') {
            body = child;
            break;
        }
    }
    const tree = (0, element_1.elementToJson)(body);
    const { width, height } = size;
    let name = 'untitled';
    const template_spec = {
        name,
        render: true,
        units: {},
        component: { defaultWidth: width, defaultHeight: height },
    };
    let total = 0;
    const addChild = (node, parent_id) => {
        total++;
        const fallbackSpecId = isSvg ? _ids_1.ID_SVG : _ids_1.ID_DIV;
        const node_spec_id = tagToId_1.TAG_TO_SPEC_ID[node.name] ?? fallbackSpecId;
        const node_unit_id = (0, util_1.newUnitId)(specs, template_spec, node_spec_id);
        const node_spec = getSpec(node_spec_id);
        const attr = (0, clone_1.clone)(node.attr);
        const parseProp = (prop, value) => {
            if (prop === 'style') {
                return (0, rawExtractStyle_1.cssTextToObj)(value);
            }
            return value;
        };
        const SURFACE_PROPS = [
            'src',
            'style',
            'd',
            'x',
            'y',
            'width',
            'height',
            'x0',
            'y0',
            'x1',
            'y1',
            'rx',
            'ry',
            'viewBox',
            'href',
            'fill',
            'stop-color',
            'value',
        ];
        const input = {};
        for (const name of SURFACE_PROPS) {
            const pinId = (0, id_1.snakeToCamel)(name);
            if (attr[name] && node_spec.inputs?.[pinId]) {
                input[pinId] = {
                    constant: true,
                    ignored: false,
                    data: {
                        ref: [],
                        data: parseProp(name, attr[name]),
                    },
                };
            }
            delete attr[name];
        }
        if (node_spec.inputs?.['attr'] && !(0, object_1.isEmptyObject)(attr)) {
            input.attr = {
                constant: true,
                ignored: false,
                data: { ref: [], data: attr },
            };
        }
        (0, spec_1.addUnit)({
            unitId: node_unit_id,
            unit: {
                id: node_spec_id,
                input,
            },
        }, template_spec);
        (0, component_1.setSubComponent)({ unitId: node_unit_id, subComponent: {} }, template_spec.component);
        if (parent_id) {
            (0, component_1.appendSubComponentChild)({
                parentId: parent_id,
                childId: node_unit_id,
                slotName: 'default',
            }, template_spec.component);
        }
        else {
            (0, component_1.appendRoot)({ childId: node_unit_id }, template_spec.component);
        }
        for (const child of node.children) {
            addChild(child, node_unit_id);
        }
    };
    let bundle;
    for (const child of tree.children) {
        addChild(child, null);
    }
    const new_spec = newSpec((0, util_1.emptySpec)(template_spec));
    if (total === 1) {
        const unit = new_spec.units[(0, object_1.getObjSingleKey)(new_spec.units)];
        unit.metadata = {
            component: {
                width,
                height,
            },
        };
        bundle = {
            unit,
        };
    }
    else {
        bundle = {
            unit: {
                id: new_spec.id,
                metadata: {
                    component: {
                        width,
                        height,
                    },
                },
            },
            specs: {
                [new_spec.id]: new_spec,
            },
        };
    }
    return bundle;
}
//# sourceMappingURL=domToUnit.js.map