import '../../../../assert/js/assert.js';
import '../../../../globals.js';
import optionize, { combineOptions } from '../../../../phet-core/js/optionize.js';
import { AlignGroup, HBox, Node, RichText, Text, VBox } from '../../../../scenery/js/imports.js';
import PhetFont from '../../PhetFont.js';
import sceneryPhet from '../../sceneryPhet.js';
import SceneryPhetStrings from '../../SceneryPhetStrings.js';
import KeyboardHelpIconFactory from './KeyboardHelpIconFactory.js';
import KeyboardHelpSection from './KeyboardHelpSection.js';
// text fonts and max widths
const LABEL_FONT = new PhetFont(16);
const OR_TEXT_MAX_WIDTH = 16;
class KeyboardHelpSectionRow {
    constructor(text, label, icon, providedOptions) {
        const options = optionize()({
            readingBlockContent: null
        }, providedOptions);
        this.text = text;
        this.label = label;
        this.icon = icon;
        this.readingBlockContent = options.readingBlockContent;
    }
    /**
     * Sets visibility of the label, icon, and text so that it can be hidden if necessary. If using
     * KeyboardHelpSection, this will also correctly layout the content because of scenery dynamic layout.
     */
    setContentsVisible(visible) {
        this.text.visible = visible;
        this.label.visible = visible;
        this.icon.visible = visible;
    }
    /**
     * Horizontally align a label and an icon, with the label on the left and the icon on the right. AlignGroup is used
     * to give the label and icon identical dimensions for easy layout in KeyboardHelpSection.
     */
    static labelWithIcon(labelString, icon, providedOptions) {
        const options = optionize()({
            labelInnerContent: null,
            readingBlockContent: null,
            labelOptions: {
                font: LABEL_FONT
            },
            iconOptions: {
                tagName: 'li'
            }
        }, providedOptions);
        const labelText = new RichText(labelString, options.labelOptions);
        // make the label and icon the same height so that they will align when we assemble help section group
        const labelIconGroup = new AlignGroup({ matchHorizontal: false });
        const labelBox = labelIconGroup.createBox(labelText);
        const iconBox = labelIconGroup.createBox(new Node({ children: [icon] }), options.iconOptions);
        iconBox.innerContent = options.labelInnerContent;
        return new KeyboardHelpSectionRow(labelText, labelBox, iconBox, {
            readingBlockContent: options.readingBlockContent || options.labelInnerContent
        });
    }
    /**
     * Create a label with a list of icons. The icons will be vertically aligned, each separated by 'or' text. The
     * label will be vertically centered with the first item in the list of icons. To vertically align the label
     * with the first icon, AlignGroup is used. Finally, an AlignGroup is used to make the label
     * content match height with the entire icon list. When assembled, the label with icon list will look like:
     *
     * This is the label: Icon1 or
     *                    Icon2 or
     *                    Icon3
     */
    static labelWithIconList(labelString, icons, providedOptions) {
        const options = optionize()({
            labelInnerContent: null,
            readingBlockContent: null,
            iconsVBoxOptions: {},
            labelOptions: {
                font: LABEL_FONT
            }
        }, providedOptions);
        options.iconsVBoxOptions = combineOptions({
            spacing: KeyboardHelpSection.DEFAULT_VERTICAL_ICON_SPACING * 0.75, // less than the normal vertical icon spacing since it is a group
            align: 'left',
            // pdom - each icon will be presented as a list item under the parent 'ul' of the KeyboardHelpSectionRow.
            tagName: 'li',
            innerContent: options.labelInnerContent
        }, options.iconsVBoxOptions);
        const labelText = new RichText(labelString, options.labelOptions);
        // horizontally align the label with the first item in the list of icons, guarantees that the label and first
        // icon have identical heights
        const labelFirstIconGroup = new AlignGroup({ matchHorizontal: false });
        labelFirstIconGroup.createBox(new Node({ children: [icons[0]] })); // create the box to restrain bounds, but a reference isn't necessary
        const labelBox = labelFirstIconGroup.createBox(labelText);
        const iconsWithOrText = [];
        // for each of the icons (excluding the last one, add a vertically aligned 'or' text to the right
        for (let i = 0; i < icons.length - 1; i++) {
            const orText = new Text(SceneryPhetStrings.keyboardHelpDialog.orStringProperty, {
                font: LABEL_FONT,
                maxWidth: OR_TEXT_MAX_WIDTH
            });
            // place orText with the icon in an HBox
            const hBox = new HBox({
                children: [new Node({ children: [icons[i]] }), orText],
                spacing: KeyboardHelpIconFactory.DEFAULT_ICON_SPACING
            });
            iconsWithOrText.push(hBox);
        }
        iconsWithOrText.push(icons[icons.length - 1]);
        // place icons in a VBox, passing through optional spacing and a11y representation
        const iconsVBox = new VBox(combineOptions({
            children: iconsWithOrText
        }, options.iconsVBoxOptions));
        // make the label the same height as the icon list by aligning them in a box that matches height
        const groupOptions = { yAlign: 'top' };
        const labelIconListGroup = new AlignGroup({ matchHorizontal: false });
        const iconsBox = labelIconListGroup.createBox(iconsVBox, groupOptions); // create the box to match height, but reference not necessary
        const labelWithHeightBox = labelIconListGroup.createBox(labelBox, groupOptions);
        return new KeyboardHelpSectionRow(labelText, labelWithHeightBox, iconsBox, {
            readingBlockContent: options.readingBlockContent || options.labelInnerContent
        });
    }
    /**
     * Create a row for the keyboard help dialog from a HotkeyData object. Optionally override the icons and labels if
     * you want to customize the row so it is different from the actual key data.
     */
    static fromHotkeyData(hotkeyData, providedOptions) {
        const options = optionize()({
            icon: null,
            labelStringProperty: hotkeyData.keyboardHelpDialogLabelStringProperty,
            pdomLabelStringProperty: hotkeyData.keyboardHelpDialogPDOMLabelStringProperty,
            labelWithIconOptions: {}
        }, providedOptions);
        // fromHotkeyData is not used in options so that it is only called if necessary
        const icon = options.icon || KeyboardHelpIconFactory.fromHotkeyData(hotkeyData);
        assert && assert(options.labelStringProperty, 'labelStringProperty must be defined');
        return KeyboardHelpSectionRow.labelWithIcon(options.labelStringProperty, icon, combineOptions({
            labelInnerContent: options.pdomLabelStringProperty
        }, options.labelWithIconOptions));
    }
}
// Reusable font style and size for the KeyboardHelpDialog labels.
KeyboardHelpSectionRow.LABEL_FONT = LABEL_FONT;
sceneryPhet.register('KeyboardHelpSectionRow', KeyboardHelpSectionRow);
export default KeyboardHelpSectionRow;
//# sourceMappingURL=KeyboardHelpSectionRow.js.map