var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
import { boards } from '../data/boards.json';
import { components } from '../data/components.json';
var boardClasses = {};
boards.forEach(function (board) {
    boardClasses[board.name] = board;
});
var componentClasses = {};
components.forEach(function (component) {
    var baseClass = component.extends && componentClasses[component.extends];
    var componentClass = __assign({}, baseClass, component, { baseClass: baseClass, getCode: function (section) {
            var code = (component.code && component.code[section]) || [];
            return baseClass ? baseClass.getCode(section).concat(code) : code;
        }, isInstanceOf: function (name) {
            if (name === component.name) {
                return true;
            }
            else if (baseClass) {
                return baseClass.isInstanceOf(name);
            }
            else {
                return false;
            }
        } });
    componentClasses[component.name] = componentClass;
});
export function resolveBoardClass(name) {
    return boardClasses[name];
}
export function resolveComponentClass(name) {
    return componentClasses[name];
}
export function getCompatibleComponents(boardClass) {
    var boardConnectorTypes = new Set();
    var _a = boardClass.ports, ports = _a === void 0 ? [] : _a;
    ports.forEach(function (_a) {
        var _b = _a.connectorTypes, connectorTypes = _b === void 0 ? [] : _b;
        connectorTypes.forEach(function (type) { return boardConnectorTypes.add(type); });
    });
    return Object.values(componentClasses).filter(function (_a) {
        var _b = _a.connectors, connectors = _b === void 0 ? [] : _b;
        return connectors.find(function (_a) {
            var type = _a.type;
            return boardConnectorTypes.has(type);
        });
    });
}
export function getCompatiblePorts(board, connectorType) {
    var boardClass = resolveBoardClass(board.className);
    var _a = boardClass.ports, ports = _a === void 0 ? [] : _a;
    return ports.filter(function (_a) {
        var _b = _a.connectorTypes, connectorTypes = _b === void 0 ? [] : _b;
        return connectorTypes.includes(connectorType);
    });
}
export function getConnectorPosition(component, connectorName) {
    var componentX = component.x, componentY = component.y, className = component.className;
    var componentClass = resolveComponentClass(className);
    var image = componentClass.image, connectors = componentClass.connectors;
    var connector = connectors.find(function (c) { return c.name === connectorName; });
    if (connector) {
        var connectorX = image.width * connector.x;
        var connectorY = image.height * connector.y;
        return {
            x: componentX + connectorX,
            y: componentY + connectorY,
        };
    }
    else {
        return { x: 0, y: 0 };
    }
}
export function getPortPosition(board, portName) {
    var boardClass = resolveBoardClass(board.className);
    var image = boardClass.image, ports = boardClass.ports;
    var port = ports.find(function (p) { return p.name === portName; });
    if (port) {
        return {
            x: image.width * (port.x - 0.5),
            y: image.height * (port.y - 0.5),
        };
    }
    else {
        return { x: 0, y: 0 };
    }
}
export function generateInstanceName(componentClass, components) {
    if (components === void 0) { components = []; }
    var baseName = componentClass.instanceName || componentClass.name;
    var index = 1;
    var name = baseName;
    while (components.find(function (c) { return c.name === name; })) {
        index++;
        name = baseName + "_" + index;
    }
    return name;
}
//# sourceMappingURL=hardware.js.map