import '../../../../../globals.js';
// Copyright 2024, University of Colorado Boulder
/**
 * TODO: doc
 *
 * @author Jonathan Olson <jonathan.olson@colorado.edu>
 */
import { optionize3 } from '../../../../../phet-core/js/optionize.js';
import { alpenglow, BufferArraySlot, CompositeModule, getVariableLengthArrayType, LinearEdgeType, MainTwoPassCoarseModule, MainTwoPassFineModule, MainTwoPassInitializeAddressesModule, TwoPassFineRenderableFaceType, U32AtomicType, U32Type } from '../../../imports.js';
export const TWO_PASS_MODULE_DEFAULTS = {
    mainTwoPassCoarseModuleOptions: {},
    mainTwoPassFineModuleOptions: {},
    mainTwoPassInitializeAddressesModule: {},
    maxFineFaces: 2 ** 15,
    maxFineEdges: 2 ** 18,
    maxBins: 2 ** 16
};
// inputSize: TwoPassRunSize
export default class TwoPassModule extends CompositeModule {
    constructor(providedOptions) {
        const options = optionize3()({}, TWO_PASS_MODULE_DEFAULTS, providedOptions);
        const fineRenderableFacesSlot = new BufferArraySlot(getVariableLengthArrayType(TwoPassFineRenderableFaceType, options.maxFineFaces));
        const fineEdgesSlot = new BufferArraySlot(getVariableLengthArrayType(LinearEdgeType, options.maxFineEdges));
        const addressesAtomicSlot = new BufferArraySlot(getVariableLengthArrayType(U32AtomicType, options.maxBins + 2));
        const addressesPlainSlot = addressesAtomicSlot.castTo(getVariableLengthArrayType(U32Type, options.maxBins + 2));
        const initializeAddressesModule = new MainTwoPassInitializeAddressesModule({
            name: `${providedOptions.name} initialize_addresses`,
            log: providedOptions.log, // TODO: how can we avoid needing this forward?
            ...options.mainTwoPassInitializeAddressesModule, // eslint-disable-line phet/no-object-spread-on-non-literals
            addresses: addressesPlainSlot
        });
        const coarseModule = new MainTwoPassCoarseModule({
            name: `${providedOptions.name} coarse`,
            log: providedOptions.log, // TODO: how can we avoid needing this forward?
            ...options.mainTwoPassCoarseModuleOptions, // eslint-disable-line phet/no-object-spread-on-non-literals
            // input
            config: providedOptions.config,
            coarseRenderableFaces: providedOptions.coarseRenderableFaces,
            coarseEdges: providedOptions.coarseEdges,
            // output
            fineRenderableFaces: fineRenderableFacesSlot,
            fineEdges: fineEdgesSlot,
            addresses: addressesAtomicSlot,
            numCoarseRenderableFaces: options.numCoarseRenderableFaces
        });
        const fineModule = new MainTwoPassFineModule({
            name: `${providedOptions.name} fine`,
            log: providedOptions.log, // TODO: how can we avoid needing this forward?
            ...options.mainTwoPassFineModuleOptions, // eslint-disable-line phet/no-object-spread-on-non-literals
            config: providedOptions.config,
            addresses: addressesPlainSlot,
            fineRenderableFaces: fineRenderableFacesSlot,
            renderProgramInstructions: providedOptions.renderProgramInstructions,
            edges: fineEdgesSlot,
            output: providedOptions.output,
            storageFormat: providedOptions.storageFormat
        });
        super([
            initializeAddressesModule,
            coarseModule,
            fineModule
        ], (context, runSize) => {
            initializeAddressesModule.execute(context, runSize.numBins);
            coarseModule.execute(context, runSize.numCoarseRenderableFaces);
            fineModule.execute(context, runSize.numBins);
        });
        this.config = providedOptions.config;
        this.coarseRenderableFaces = providedOptions.coarseRenderableFaces;
        this.coarseEdges = providedOptions.coarseEdges;
        this.renderProgramInstructions = providedOptions.renderProgramInstructions;
        this.output = providedOptions.output;
        this.initializeAddressesModule = initializeAddressesModule;
        this.coarseModule = coarseModule;
        this.fineModule = fineModule;
    }
}
alpenglow.register('TwoPassModule', TwoPassModule);
//# sourceMappingURL=TwoPassModule.js.map