"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CLASS_DEFAULT_HEIGHT = exports.CLASS_DEFAULT_WIDTH = void 0;
const classnames_1 = require("../../../../../client/classnames");
const complexity_1 = require("../../../../../client/complexity");
const element_1 = require("../../../../../client/element");
const parentElement_1 = require("../../../../../client/platform/web/parentElement");
const spec_1 = require("../../../../../client/spec");
const geometry_1 = require("../../../../../client/util/geometry");
const getUnitPinPosition_1 = require("../../../../../client/util/geometry/unit/getUnitPinPosition");
const LINK_DISTANCE_1 = require("../../../../../constant/LINK_DISTANCE");
const PIN_RADIUS_1 = require("../../../../../constant/PIN_RADIUS");
const lineWrap_1 = require("../../../../../spec/lineWrap");
const f_1 = require("../../../../f/object/Keys/f");
const Component_1 = require("../../../component/Icon/Component");
const Component_2 = require("../../svg/Circle/Component");
const Component_3 = require("../../svg/Group/Component");
const Component_4 = require("../../svg/Line/Component");
const Component_5 = require("../../svg/Rect/Component");
const Component_6 = require("../../svg/SVG/Component");
const Component_7 = require("../../svg/Text/Component");
const OPENING = 120;
exports.CLASS_DEFAULT_WIDTH = 90;
exports.CLASS_DEFAULT_HEIGHT = 90;
class ClassDatum extends element_1.Element {
    constructor($props, $system) {
        super($props, $system);
        this._refresh_style = () => {
            const style = this._style();
            this._svg.setProp('style', style);
        };
        this._refresh_view_box = () => {
            const { width, height } = this._size();
            this._svg.setProp('viewBox', `-1 -1 ${width + 2} ${height + 2}`);
        };
        this._r = () => {
            const { classes } = this.$system;
            const { specs, id } = this.$props;
            const r = (0, complexity_1.getSpecRadius)(specs, classes, id) - 1.5;
            return r;
        };
        this._size = () => {
            const r = this._r();
            const width = 2 * r;
            const height = 2 * r;
            return { width, height };
        };
        this._style = () => {
            const { style } = this.$props;
            const { width, height } = this._size();
            return {
                width: `${width}px`,
                height: `${height}px`,
                color: 'currentColor',
                pointerEvents: 'none',
                overflow: 'visible',
                ...style,
            };
        };
        this._render = (id) => {
            const { specs = this.$system.specs } = this.$props;
            const spec = specs[id];
            const { name = '' } = spec;
            const children = [];
            const { inputs = {}, outputs = {} } = spec;
            const { width, height } = this._size();
            const core_r = this._r();
            const r = PIN_RADIUS_1.PIN_RADIUS - 3;
            const is_component = (0, spec_1.isComponentId)(specs, id);
            const cX = width / 2;
            const cY = height / 2;
            let input_pin_ids = (0, f_1.keys)(inputs).filter((pinId) => {
                const input = inputs[pinId];
                const { defaultIgnored } = input;
                if (defaultIgnored) {
                    return false;
                }
                return true;
            });
            const output_pin_ids = (0, f_1.keys)(outputs).filter((pinId) => {
                const output = outputs[pinId];
                const { defaultIgnored } = output;
                if (defaultIgnored) {
                    return false;
                }
                return true;
            });
            const pin_count = {
                input: input_pin_ids.length,
                output: output_pin_ids.length,
            };
            const push_pin = (type, i) => {
                const count = pin_count[type];
                const { x, y } = (0, getUnitPinPosition_1.getUnitPinPosition)(i, count, type, r, cX, cY, core_r, OPENING, LINK_DISTANCE_1.LINK_DISTANCE / 9);
                const u = (0, geometry_1.unitVector)(x, y, cX, cY);
                const nu = { x: -u.x, y: -u.y };
                const pin = new Component_2.default({
                    className: (0, classnames_1.classnames)('unit-class-pin', `unit-class-${type}`),
                    x,
                    y,
                    r,
                    style: {
                        strokeWidth: '1px',
                        stroke: 'currentColor',
                        fill: type === 'output' ? 'currentColor' : 'none',
                    },
                }, this.$system);
                children.push(pin);
                const { x: x1, y: y1 } = (0, geometry_1.pointInCircle)(x, y, r, u);
                const { x: x2, y: y2 } = !is_component
                    ? (0, geometry_1.pointInCircle)(cX, cY, core_r, nu)
                    : (0, geometry_1.pointInRectangle)(cX, cY, 2 * core_r, 2 * core_r, nu);
                const pin_link = new Component_4.default({
                    className: (0, classnames_1.classnames)('unit-interface-link', `unit-interface-link-${type}`),
                    x1,
                    y1,
                    x2,
                    y2,
                    style: {
                        strokeWidth: '1px',
                        stroke: 'currentColor',
                    },
                }, this.$system);
                children.push(pin_link);
                this._svg.setProp('viewBox', `-1 -1 ${width + 2} ${height + 2}`);
            };
            input_pin_ids.forEach((_, index) => {
                push_pin('input', index);
            });
            // const icon = (spec.metadata && spec.metadata.icon) || 'question'
            const icon = (spec.metadata && spec.metadata.icon) || null;
            let core_shape;
            if (is_component) {
                core_shape = new Component_5.default({
                    className: 'unit-class-core-shape',
                    x: cX - core_r,
                    y: cY - core_r,
                    width: 2 * core_r,
                    height: 2 * core_r,
                    style: {
                        fill: 'none',
                        stroke: 'currentColor',
                        strokeWidth: '1px',
                    },
                }, this.$system);
            }
            else {
                core_shape = new Component_2.default({
                    className: 'unit-class-core-shape',
                    x: cX,
                    y: cY,
                    r: core_r,
                    style: {
                        fill: 'none',
                        stroke: 'currentColor',
                        strokeWidth: '1px',
                    },
                }, this.$system);
            }
            const core_icon = new Component_1.default({
                className: 'unit-class-core-icon',
                icon,
                x: cX - core_r / 2,
                y: cY - core_r / 2,
                width: core_r,
                height: core_r,
                style: {
                    color: 'currentColor',
                },
            }, this.$system);
            const core = new Component_3.default({
                className: 'unit-class-core',
            }, this.$system);
            core.appendChild(core_shape);
            core.appendChild(core_icon);
            children.push(core);
            output_pin_ids.forEach((_, index) => {
                push_pin('output', index);
            });
            const core_name_g = new Component_3.default({}, this.$system);
            const lines = (0, lineWrap_1.lineWrap)(name);
            for (let i = 0; i < lines.length; i++) {
                const value = lines[i];
                const core_name_line = new Component_7.default({
                    value,
                    dx: `${width / 2}`,
                    dy: `${height / 2 + core_r + 12 + i * 9}`,
                    style: {
                        fontSize: '9px',
                    },
                    textAnchor: 'middle',
                }, this.$system);
                core_name_g.appendChild(core_name_line);
            }
            children.push(core_name_g);
            this._svg_g.setChildren(children);
        };
        const { id, attr, className } = $props;
        const { width, height } = this._size();
        const svg = new Component_6.default({
            className: (0, classnames_1.classnames)('unit-class', className),
            attr: {
                width: `${width}`,
                height: `${height}`,
                ...attr,
            },
            style: this._style(),
            viewBox: `-1 -1 ${width + 2} ${height + 2}`,
        }, this.$system);
        this._svg = svg;
        const svg_g = new Component_3.default({
            className: (0, classnames_1.classnames)('unit-class-g', className),
            style: {},
        }, this.$system);
        this._svg_g = svg_g;
        this._svg.registerParentRoot(svg_g);
        if (id) {
            this._render(id);
        }
        const $element = (0, parentElement_1.parentElement)($system);
        this.$element = $element;
        this.$slot['default'] = svg;
        this.setSubComponents({
            svg,
            svg_g,
        });
        this.registerRoot(svg);
    }
    onPropChanged(prop, current) {
        if (prop === 'id') {
            this._render(current);
            this._refresh_style();
            this._refresh_view_box();
        }
        else if (prop === 'style') {
            this._svg.setProp('style', this._style());
        }
        else if (prop === 'attr') {
            this._svg.setProp('attr', current);
        }
    }
}
exports.default = ClassDatum;
//# sourceMappingURL=Component.js.map