import '../../../globals.js';
import Range from '../../../dot/js/Range.js';
import optionize from '../../../phet-core/js/optionize.js';
import brightMarimba_mp3 from '../../sounds/brightMarimba_mp3.js';
import tambo from '../tambo.js';
import SoundClip from './SoundClip.js';
import BinMapper from '../BinMapper.js';
class DiscreteSoundGenerator extends SoundClip {
    /**
     * @param valueProperty - the value that is monitored to trigger sounds
     * @param valueRange - the range of values expected and over which sounds will be played
     * @param [providedOptions] - options for this sound generation and its parent class
     */
    constructor(valueProperty, valueRange, providedOptions) {
        const options = optionize()({
            sound: brightMarimba_mp3,
            initialOutputLevel: 1,
            numBins: 7,
            playbackRateRange: new Range(1, 1), // default is no change to the sound
            alwaysPlayOnChangesProperty: null,
            playSoundAtMin: true,
            playSoundAtMax: true,
            outOfRangeValuesOK: false
        }, providedOptions);
        // invoke superconstructor
        super(options.sound, options);
        // create the object that will place the continuous values into bins
        const binMapper = new BinMapper(valueRange, options.numBins, {
            tolerateOutOfRangeValues: options.outOfRangeValuesOK
        });
        // function for playing sound when the appropriate conditions are met
        const playSoundOnChanges = (newValue, oldValue) => {
            const newBin = binMapper.mapToBin(newValue);
            const oldBin = binMapper.mapToBin(oldValue);
            if (options.alwaysPlayOnChangesProperty && options.alwaysPlayOnChangesProperty.value ||
                (newValue === valueRange.min && options.playSoundAtMin) ||
                (newValue === valueRange.max && options.playSoundAtMax) ||
                newBin !== oldBin) {
                const normalizedValue = (newValue - valueRange.min) / valueRange.getLength();
                const playbackRate = normalizedValue * (options.playbackRateRange.max - options.playbackRateRange.min) +
                    options.playbackRateRange.min;
                this.setPlaybackRate(playbackRate);
                this.play();
            }
        };
        // monitor the value, playing sounds when appropriate
        valueProperty.lazyLink(playSoundOnChanges);
        // dispose function
        this.disposeDiscreteSoundGenerator = () => { valueProperty.unlink(playSoundOnChanges); };
    }
    /**
     */
    dispose() {
        this.disposeDiscreteSoundGenerator();
        super.dispose();
    }
}
tambo.register('DiscreteSoundGenerator', DiscreteSoundGenerator);
export default DiscreteSoundGenerator;
//# sourceMappingURL=DiscreteSoundGenerator.js.map