import '../../../globals.js';
// Copyright 2017-2024, University of Colorado Boulder
/**
 * KeyNode looks like a keyboard key. It has a shadow rectangle under the key icon, with a slight offset so that it
 * has a 3D appearance.  KeyNodes are primarily used for accessibility to provide extra information about keyboard
 * navigation and functionality, but an icon could be used for any purpose.
 *
 * Each KeyNode has the same height by default, and icon will be scaled down if it is too large to maintain the proper
 * key height. The width will expand based on padding and the width of the icon in order to surround content fully.
 *
 * @author Jesse Greenberg
 */
import Bounds2 from '../../../dot/js/Bounds2.js';
import optionize from '../../../phet-core/js/optionize.js';
import { AlignBox, Node, Rectangle } from '../../../scenery/js/imports.js';
import sceneryPhet from '../sceneryPhet.js';
export default class KeyNode extends Node {
    constructor(keyIcon, providedOptions) {
        const options = optionize()({
            keyFill: 'white',
            keyShadowFill: 'black',
            lineWidth: 1.3,
            cornerRadius: 2,
            xShadowOffset: 1.7,
            yShadowOffset: 1.7,
            xMargin: 0,
            yMargin: 0,
            xAlign: 'center',
            yAlign: 'center',
            xPadding: 4,
            yPadding: 4,
            keyHeight: 23,
            minKeyWidth: 23, // default equal to keyHeight, a square key as the minimum.
            forceSquareKey: false
        }, providedOptions);
        // Add the height scale to a new node based on the height, with keyIcon as a child so that we don't mutate the parameter node.
        const heightScaleNode = new Node({ children: [keyIcon] });
        // Add the scale to a new node based on the width
        const widthScaleNode = new Node({ children: [heightScaleNode] });
        // place content in an align box so that the key surrounding the icon has minimum bounds calculated above
        // with support for margins
        const content = new AlignBox(widthScaleNode, {
            xAlign: options.xAlign,
            yAlign: options.yAlign,
            xMargin: options.xMargin,
            yMargin: options.yMargin
        });
        // background (shadow rectangle)
        const backgroundShadow = new Rectangle(0, 0, 1, 1, options.cornerRadius, options.cornerRadius, {
            fill: options.keyShadowFill
        });
        // foreground
        const whiteForeground = new Rectangle(0, 0, 1, 1, options.cornerRadius, options.cornerRadius, {
            fill: options.keyFill,
            stroke: 'black',
            lineWidth: options.lineWidth
        });
        const listener = () => {
            // scale down the size of the keyIcon passed in if it is taller than the max height of the icon
            let heightScalar = 1;
            const availableHeightForKeyIcon = options.keyHeight - options.yPadding; // adjust for the vertical margin
            if (keyIcon.height > availableHeightForKeyIcon) {
                heightScalar = availableHeightForKeyIcon / keyIcon.height;
            }
            heightScaleNode.setScaleMagnitude(heightScalar);
            // Set the keyWidth to either be the minimum, or the width of the icon + padding, which ever is larger.
            let keyWidth = Math.max(options.minKeyWidth, heightScaleNode.width + options.xPadding);
            // Make the width the same as the height by scaling down the icon if necessary
            if (options.forceSquareKey) {
                // If we are forcing square, we may have to scale the node down to fit
                const availableWidthForKeyIcon = options.minKeyWidth - options.xPadding; // adjust for the horizontal margin
                let widthScalar = 1;
                if (keyIcon.width > availableWidthForKeyIcon) {
                    widthScalar = availableWidthForKeyIcon / keyIcon.width;
                }
                // Set the width to the height to make sure the alignBounds below are set correctly as a square.
                keyWidth = options.keyHeight;
                widthScaleNode.setScaleMagnitude(widthScalar);
            }
            content.setAlignBounds(new Bounds2(0, 0, keyWidth, options.keyHeight));
            backgroundShadow.setRectBounds(content.bounds.shiftedXY(options.xShadowOffset, options.yShadowOffset));
            whiteForeground.setRectBounds(content.bounds);
        };
        keyIcon.boundsProperty.link(listener);
        // children of the icon node, including the background shadow, foreground key, and content icon
        options.children = [
            backgroundShadow,
            whiteForeground,
            // content on top
            content
        ];
        super(options);
        this.disposeEmitter.addListener(() => keyIcon.boundsProperty.unlink(listener));
    }
}
sceneryPhet.register('KeyNode', KeyNode);
//# sourceMappingURL=KeyNode.js.map