import _ from 'lodash';
import '../../assert/js/assert.js';
import '../../globals.js';
import optionize, { combineOptions } from '../../phet-core/js/optionize.js';
import { FlowBox, Node } from '../../scenery/js/imports.js';
import LevelSelectionButton from './LevelSelectionButton.js';
import Tandem from '../../tandem/js/Tandem.js';
import vegas from './vegas.js';
export default class LevelSelectionButtonGroup extends Node {
    /**
     * @param items - descriptions of the LevelSelectionButtons, ordered by increasing level number
     * @param [providedOptions]
     */
    constructor(items, providedOptions) {
        assert && assert(items.length > 0, 'at least one item must be specified');
        const options = optionize()({
            // The default layout is a single row of buttons.
            flowBoxOptions: {
                orientation: 'horizontal',
                spacing: 10
            },
            // @ts-expect-error This default is provided for JavaScript simulations.
            tandem: Tandem.REQUIRED
        }, providedOptions);
        // Create the LevelSelectionButton instances.
        const buttons = items.map((item, index) => {
            let tandem = Tandem.OPT_OUT;
            if (options.tandem.supplied) {
                const tandemName = item.tandemName || `level${index + 1}Button`;
                tandem = options.tandem.createTandem(tandemName);
            }
            const buttonOptions = combineOptions({
                buttonHeight: options.groupButtonHeight,
                buttonWidth: options.groupButtonWidth,
                tandem: tandem
            }, options.levelSelectionButtonOptions, item.options);
            return new LevelSelectionButton(item.icon, item.scoreProperty, buttonOptions);
        });
        // Hide buttons for levels that are not included in gameLevels.
        // All buttons must be instantiated so that the PhET-iO API is not changed conditionally.
        // While options.gameLevels is required, this guard is provided for .js sims that do not comply.
        if (options.gameLevels) {
            assert && assert(options.gameLevels.length > 0, 'at least 1 gameLevel must be visible');
            assert && assert(_.every(options.gameLevels, gameLevel => (Number.isInteger(gameLevel) && gameLevel > 0)), 'gameLevels must be positive integers');
            buttons.forEach((button, index) => {
                button.visible = options.gameLevels.includes(index + 1);
            });
        }
        let layoutNode;
        if (options.createLayoutNode) {
            layoutNode = options.createLayoutNode(buttons);
        }
        else {
            // The default layout is a FlowBox, customizable via options.flowBoxOptions.
            layoutNode = new FlowBox(combineOptions({
                children: buttons
            }, options.flowBoxOptions));
        }
        options.children = [layoutNode];
        super(options);
        this.buttons = buttons;
    }
    /**
     * Sets the focus to the button associated with a specified level number. If your simulation supports keyboard
     * traversal, you'll typically need to call this when returning to the UI that show the LevelSelectionButtonGroup,
     * for example, when the 'Back' or 'Start Over' button is pressed in a game.
     * @param level - numbered starting from 1, to comply with gameLevels query parameter
     */
    focusLevelSelectionButton(level) {
        assert && assert(Number.isInteger(level) && level > 0 && level <= this.buttons.length, `invalid level: ${level}`);
        this.buttons[level - 1].focus();
    }
}
vegas.register('LevelSelectionButtonGroup', LevelSelectionButtonGroup);
//# sourceMappingURL=LevelSelectionButtonGroup.js.map