Source: package/connector/connector.js

import { Vector3, Quaternion } from '../../../node_modules/three/build/three.module.js';
import { BuildableComponent } from '../component/buildable_component.js';
import { Reporter } from '../../reporter/reporter.js';
import { checkPropTypes } from '../../lib.js';
import { ConnectorType } from "./connector_type.js";
import { ThemeGroup } from "../theme/theme_group.js";
import { Block } from "../block/block.js";
import { Project } from '../../project.js';

/** Connector */
class Connector extends BuildableComponent {

    /**
     * @param {Reporter} reporter
     * @param {Object} settings
     * @param {UUID} [settings.id]
     * @param {string} [settings.name]
     * @param {ThemeGroup} [settings.themeGroup]
     * @param {ConnectorType} settings.type
     * @param {Vector3} [settings.position]
     * @param {Quaternion} [settings.quaternion]
     */

    constructor(reporter, settings) {

        if ( settings.position === undefined) {
            settings.position = new Vector3();
        }

        if ( settings.quaternion === undefined) {
            settings.quaternion = new Quaternion();
        }

        super(reporter, settings);

        this.mate = {};

        checkPropTypes(
            settings,
            {
                type: ConnectorType,
                position: Vector3,
                quaternion: Quaternion,
            },
            {
                themeGroup: ThemeGroup
                // pkg: Package,
            }
        );
    }


    static _exportName = {
        singular: 'connector',
        plural: 'connectors'
    };

    /** @type {ExportLevel} */

    static _exportLevel = 'inline';


    /** @type {Object} */

    get mateMap() {
        if ( this._tree ) {
            return this._tree.mateMap[ this.settings.type ];
        }
        else {
            return {};
        }
    }


    /**
     * Reference to the parent block
     * @type {Block}
     */

    _block;

    get block() {
        return this._block;
    }

    set block(blk) {
        
        if (this._block) {
            throw new Error('Reference block setter called for a subsequent time.')
        }

        console.assert(blk instanceof Block);
        
        this._block = blk;
    }


    /** @type {ConnectorTypeMates} */

    mate;


    /**
     * @method
     */

    _updatePotentialMateList() {
        if (!this._tree) {
            console.warn('Can not update mate list, no tree');
        } else if(! this._tree.connectorTypeMateMap) {
            console.warn(`Can not update mate list, no connectorTypeMateMap in ${this._tree.label}`);
        }
        else {
            this.mate = this._tree.connectorTypeMateMap.get( this.settings.type );
        }
    }



    _onTreeSet() {        
        const component = this;
        this._updatePotentialMateList();
        this._tree.on('mate-map-update', () => {
            component._updatePotentialMateList.bind(component)()
        }, this.id );
    }


    _onTreeUnset() {
        this.mate = {};
        this._tree.removeListener('mate-map-update', this.id );
    }



    /**
     * Collect material categories of this type from the package
     * @protected
     */

    async _build(part, quality, dependencies) {

        switch (part) {

            case 'UI':
                if (this._settings.thumbnail) {
                    this._setContent('UI', quality, this._settings.thumbnail.content.main[quality]);
                }
                else {
                    this._setContent('UI', quality, Project.defaultImages.missing.cloneNode(true));
                }
                break;

            case 'main':

                // exporting transform matrix might be easier (def faster)

                const content = {
                    id: this._settings.id,
                    name: this._settings.name,
                    themeGroup: this._settings.themeGroup,
                    type: this._settings.type,
                    position: this._settings.position,
                    quaternion: this._settings.quaternion,
                    // rotation: this._settings.rotation
                };

                // for (let setQuality of Component.qualities) {

                //     this._setContent('main', setQuality, content);

                // }

                this._setContent('main', quality, content);

                break;

            default:

                this._setContent(part, quality, null);
                
                break;
        }

        return this;
    }
}

export { Connector };