const scratch_array = [];

export class VisibilityComputer {
    constructor() {

        /**
         *
         * @type {CameraView}
         */
        this.__view = null;

        /**
         *
         * @type {RenderLayer}
         * @private
         */
        this.__activeLayer = null;

        /**
         *
         * @type {IncrementalDeltaSet<THREE.Object3D>}
         * @private
         */
        this.__output = null;
    }

    /**
     *
     * @param {CameraView} view
     */
    set view(view) {
        this.__view = view;
    }

    /**
     * @private
     * @param {RenderLayer} layer
     */
    __processLayer(layer) {
        if (!layer.state.visible) {
            //whole layer is hidden

            // layer.visibleSet.clear();
            return;
        }

        this.__activeLayer = layer;

        if (layer.managed) {

            this.__output.pushOther(layer.visibleSet);

            return;
        }

        const added_objects = layer.buildVisibleSet(scratch_array, 0, this.__view);

        for (let i = 0; i < added_objects; i++) {
            const object3d = scratch_array[i];

            //object passed all filters, add it to visible set
            this.__output.push(object3d);

            this.__activeLayer.visibleSet.push(object3d);
        }
    }


    /**
     * @param {IncrementalDeltaSet<Object3D>} v
     */
    set output(v) {
        this.__output = v;
    }

    /**
     *
     * @param {RenderLayerManager} renderLayers
     */
    build(renderLayers) {
        renderLayers.traverse(this.__processLayer, this);
    }
}
