import { Gain } from 'tone';
import { ToneAudioNode } from 'tone';
import { ToneAudioNodeOptions } from 'tone';
import { Unit } from 'tone';

declare interface KeyEvent {
    time?: Unit.Time;
    velocity?: number;
    note?: string;
    midi?: number;
}

declare interface PedalEvent {
    time?: Unit.Time;
}

/**
 * A progressive piano that upgrades velocity resolution in the background.
 * Always starts with a single velocity for fast time-to-ready, then expands
 * to the target velocity count. Cache hits make each expansion step fast.
 */
export declare class Piano extends ToneAudioNode<PianoOptions> {
    readonly name = "Piano";
    readonly input: any;
    readonly output: Gain<"gain">;
    private _sampler?;
    private _velocities;
    private _samplerConfig;
    private _onPlayable?;
    private _onLoadProgress?;
    private _onTimeout?;
    private _loaded;
    constructor(options?: Partial<PianoOptions>);
    static getDefaults(): Required<PianoOptions>;
    /**
     * Load samples progressively. Resolves after the first velocity pass is ready;
     * upgrades to the target velocity count continue in the background.
     */
    load(): Promise<void>;
    /**
     * If the first velocity pass is loaded and ready to play
     */
    get loaded(): boolean;
    /**
     * Play a note.
     */
    keyDown(event: KeyEvent): this;
    /**
     * Release a held note.
     */
    keyUp(event: KeyEvent): this;
    /**
     * Put the pedal down. Causes subsequent notes and currently held notes to sustain.
     */
    pedalDown(event?: PedalEvent): this;
    /**
     * Put the pedal up. Dampens sustained notes.
     */
    pedalUp(event?: PedalEvent): this;
    /**
     * Stop all currently playing notes.
     */
    stopAll(): this;
    private _expandInBackground;
}

export declare interface PianoOptions extends ToneAudioNodeOptions {
    /**
     * The maximum number of velocity levels to load. Progressive loading starts
     * with 1 velocity and upgrades to this target during browser idle time.
     * Default: 8.
     */
    velocities?: number;
    /**
     * The lowest note to load
     */
    minNote?: number;
    /**
     * The highest note to load
     */
    maxNote?: number;
    /**
     * If it should include a 'release' sounds composed of a keyclick and string harmonic
     */
    release?: boolean;
    /**
     * If the piano should include a 'pedal' sound.
     */
    pedal?: boolean;
    /**
     * The directory of the salamander grand piano samples
     */
    url?: string;
    /**
     * The maximum number of notes that can be held at once
     */
    maxPolyphony?: number;
    /**
     * Volume levels for each of the components (in decibels)
     */
    volume?: {
        pedal: number;
        strings: number;
        keybed: number;
        harmonics: number;
    };
    /**
     * Called once when the piano is first ready to play (after the initial velocity pass loads).
     */
    onPlayable?: () => void;
    /**
     * Called after each velocity loading step with a normalized progress value (0–1).
     * Fires after the initial load and after each background expansion step.
     * Progress reaches 1.0 when all target velocities are loaded.
     */
    onLoadProgress?: (_progress: number) => void;
    /**
     * Called if background velocity upgrades do not complete within 30 seconds.
     */
    onTimeout?: () => void;
}

/**
 * Sample preloader that fetches piano audio files without importing Tone.js
 * Uses existing Salamander.ts utilities to avoid duplication
 */
export declare interface PreloadOptions {
    /**
     * Base URL for samples (defaults to Piano default)
     */
    baseUrl?: string;
    /**
     * Lowest MIDI note to preload (default: 21)
     */
    minNote?: number;
    /**
     * Highest MIDI note to preload (default: 108)
     */
    maxNote?: number;
    /**
     * Include harmonics samples (default: false)
     */
    includeHarmonics?: boolean;
    /**
     * Include pedal samples (default: false)
     */
    includePedal?: boolean;
    /**
     * Include release samples (default: false)
     */
    includeRelease?: boolean;
}

/**
 * Preload piano samples into the Cache Storage API.
 * Skips URLs already present in the cache.
 */
export declare function preloadSamples(velocities: number, options?: PreloadOptions): Promise<void>;

export { }
