/**
 * Petit synthetiseur WebAudio, sans fichier son, pour du feedback audio leger.
 * Usage: SFX.drop(), SFX.perfect(), SFX.gift(), SFX.follow(), SFX.gameOver()
 */
const SFX = (() => {
  let ctx = null;

  function ensureCtx() {
    if (!ctx) ctx = new (window.AudioContext || window.webkitAudioContext)();
    if (ctx.state === 'suspended') ctx.resume();
    return ctx;
  }

  function tone({ freq, duration = 0.15, type = 'sine', gain = 0.2, delay = 0, slideTo = null }) {
    try {
      const audio = ensureCtx();
      const osc = audio.createOscillator();
      const gainNode = audio.createGain();
      osc.type = type;
      const startTime = audio.currentTime + delay;
      osc.frequency.setValueAtTime(freq, startTime);
      if (slideTo) osc.frequency.exponentialRampToValueAtTime(slideTo, startTime + duration);
      gainNode.gain.setValueAtTime(gain, startTime);
      gainNode.gain.exponentialRampToValueAtTime(0.001, startTime + duration);
      osc.connect(gainNode).connect(audio.destination);
      osc.start(startTime);
      osc.stop(startTime + duration + 0.02);
    } catch (e) {
      // audio indisponible, silencieux
    }
  }

  return {
    unlock() { ensureCtx(); },
    drop() { tone({ freq: 160, duration: 0.12, type: 'square', gain: 0.15 }); },
    // scale permet de jouer le meme son de reussite en plus discret quand il
    // est repete en rafale (ex: les 50 etages de "You're on a Roll").
    perfect(scale) {
      const s = scale === undefined ? 1 : scale;
      tone({ freq: 660, duration: 0.12, type: 'sine', gain: 0.2 * s });
      tone({ freq: 880, duration: 0.16, type: 'sine', gain: 0.18 * s, delay: 0.06 });
      tone({ freq: 1100, duration: 0.2, type: 'sine', gain: 0.15 * s, delay: 0.12 });
    },
    gift() {
      tone({ freq: 520, duration: 0.1, type: 'triangle', gain: 0.2 });
      tone({ freq: 780, duration: 0.14, type: 'triangle', gain: 0.18, delay: 0.08 });
    },
    follow() {
      tone({ freq: 440, duration: 0.25, type: 'sine', gain: 0.18, slideTo: 900 });
    },
    gameOver() {
      tone({ freq: 300, duration: 0.5, type: 'sawtooth', gain: 0.15, slideTo: 80 });
    },
    tick() {
      tone({ freq: 700 + Math.random() * 200, duration: 0.06, type: 'sine', gain: 0.12 });
    },
    miss() {
      tone({ freq: 180, duration: 0.2, type: 'square', gain: 0.15, slideTo: 90 });
    },
    cut() {
      tone({ freq: 1400, duration: 0.09, type: 'sawtooth', gain: 0.18, slideTo: 250 });
      tone({ freq: 2000, duration: 0.05, type: 'triangle', gain: 0.12, delay: 0.02 });
    }
  };
})();
