/* global React, window, Vex */
// Lesson 2.2 — Rests.
// Body-only.

(function () {
  'use strict';
  window.PracticeLab = window.PracticeLab || {};
  window.PracticeLab.ui = window.PracticeLab.ui || {};

  function vexAvailable() {
    return !!(typeof window.Vex !== 'undefined' && window.Vex && window.Vex.Flow);
  }

  // Render a single rest symbol in 4/4. VexFlow duration for rests is
  // the same digit + 'r' (wr, hr, qr, 8r).
  function renderSingleRest(containerEl, vexDur) {
    if (!vexAvailable() || !containerEl) return;
    containerEl.innerHTML = '';
    try {
      var VF = window.Vex.Flow;
      var width = 130;
      var height = 110;
      var renderer = new VF.Renderer(containerEl, VF.Renderer.Backends.SVG);
      renderer.resize(width, height);
      var ctx = renderer.getContext();
      var stave = new VF.Stave(6, 12, width - 12);
      stave.addClef('treble');
      stave.setContext(ctx).draw();
      // VexFlow rests use the 'r' suffix and any key works.
      var note = new VF.StaveNote({
        clef: 'treble',
        keys: ['b/4'],
        duration: vexDur,
      });
      var voice = new VF.Voice({ num_beats: 4, beat_value: 4 });
      voice.setStrict(false);
      voice.addTickables([note]);
      new VF.Formatter().joinVoices([voice]).format([voice], width - 60);
      voice.draw(ctx, stave);
    } catch (e) {}
  }

  // A bar with [quarter, quarter rest, quarter, quarter rest] in 4/4 —
  // the "off-on-off-on" feel that makes rest-counting click for new
  // students.
  function renderRestBar(containerEl) {
    if (!vexAvailable() || !containerEl) return;
    containerEl.innerHTML = '';
    try {
      var VF = window.Vex.Flow;
      var width = 260;
      var height = 110;
      var renderer = new VF.Renderer(containerEl, VF.Renderer.Backends.SVG);
      renderer.resize(width, height);
      var ctx = renderer.getContext();
      var stave = new VF.Stave(6, 12, width - 12);
      stave.addClef('treble').addTimeSignature('4/4');
      stave.setContext(ctx).draw();
      var notes = [
        new VF.StaveNote({ clef:'treble', keys:['c/5'], duration:'q', autoStem:true }),
        new VF.StaveNote({ clef:'treble', keys:['b/4'], duration:'qr' }),
        new VF.StaveNote({ clef:'treble', keys:['c/5'], duration:'q', autoStem:true }),
        new VF.StaveNote({ clef:'treble', keys:['b/4'], duration:'qr' }),
      ];
      var voice = new VF.Voice({ num_beats:4, beat_value:4 });
      voice.setStrict(false);
      voice.addTickables(notes);
      new VF.Formatter().joinVoices([voice]).format([voice], width - 80);
      voice.draw(ctx, stave);
    } catch (e) {}
  }

  var LessonRests = function () {
    const Bits = window.PracticeLab.ui.LessonBits;
    if (!Bits) return null;
    const Section = Bits.Section;
    const DemoBox = Bits.DemoBox;
    const PlayButton = Bits.PlayButton;
    const audio = window.PracticeLab.audio;
    const rhythm = window.PracticeLab.rhythm;

    const wRef = React.useRef(null);
    const hRef = React.useRef(null);
    const qRef = React.useRef(null);
    const eRef = React.useRef(null);
    const barRef = React.useRef(null);

    const [vexReady, setVexReady] = React.useState(vexAvailable());

    React.useEffect(function () {
      if (vexReady) return;
      const id = setInterval(function () {
        if (vexAvailable()) { setVexReady(true); clearInterval(id); }
      }, 100);
      return function () { clearInterval(id); };
    }, [vexReady]);

    React.useEffect(function () {
      if (!vexReady) return;
      renderSingleRest(wRef.current, 'wr');
      renderSingleRest(hRef.current, 'hr');
      renderSingleRest(qRef.current, 'qr');
      renderSingleRest(eRef.current, '8r');
      renderRestBar(barRef.current);
    }, [vexReady]);

    const playOnOffBar = React.useCallback(function () {
      // 1 bar of 4/4: quarter (sound) - quarter rest - quarter (sound) - quarter rest
      var pattern = { events: [
        { value:'quarter' },
        { value:'quarter_rest', isRest:true },
        { value:'quarter' },
        { value:'quarter_rest', isRest:true },
      ]};
      var timeline = rhythm.patternToTimeline(pattern);
      return audio.playRhythm(timeline, 90, { withMetronome: true });
    }, [audio, rhythm]);

    return (
      <div>
        <Section heading="Silence has a duration too">
          A <strong>rest</strong> is the same idea as a note — it has a duration — but no pitch is played. You stay quiet for exactly that long, then the next note comes in. Counting rests is just as important as counting notes; skip them and the bar falls apart.
        </Section>

        <Section heading="The four basic rests">
          <DemoBox label="Whole rest · 4 beats silent">
            <div ref={wRef} />
            <div style={{ marginTop: 8, fontSize: 13, color: 'oklch(40% 0.04 265)' }}>A small black rectangle hanging <em>below</em> the 4th line from the bottom. Holds for an entire bar in 4/4.</div>
          </DemoBox>
          <DemoBox label="Half rest · 2 beats silent">
            <div ref={hRef} />
            <div style={{ marginTop: 8, fontSize: 13, color: 'oklch(40% 0.04 265)' }}>Same rectangle, but <em>sitting on top of</em> the middle line. (Many students remember "half-rest sits like a hat".)</div>
          </DemoBox>
          <DemoBox label="Quarter rest · 1 beat silent">
            <div ref={qRef} />
            <div style={{ marginTop: 8, fontSize: 13, color: 'oklch(40% 0.04 265)' }}>The squiggly "Z"-with-a-tail symbol. Most common rest you'll meet.</div>
          </DemoBox>
          <DemoBox label="Eighth rest · ½ beat silent">
            <div ref={eRef} />
            <div style={{ marginTop: 8, fontSize: 13, color: 'oklch(40% 0.04 265)' }}>Like a tiny flag with one dot. Half a beat of silence — you'll often see it inside a beam of eighth notes.</div>
          </DemoBox>
        </Section>

        <Section heading="Hear the difference">
          <DemoBox label="One bar of 4/4: note, rest, note, rest">
            <div ref={barRef} />
            <div style={{ marginTop: 10 }}>
              <PlayButton label="Play with metronome" onPlay={playOnOffBar} />
            </div>
            <div style={{ marginTop: 8, fontSize: 13, color: 'oklch(40% 0.04 265)' }}>
              You hear the quarter on beats 1 and 3, with quarter rests on 2 and 4. The metronome ticks every beat so you can feel the silence.
            </div>
          </DemoBox>
        </Section>

        <Section heading="Counting tip" last>
          When you see a rest, keep counting in your head exactly the way you would for a note of the same value. Many beginners stop counting during the rest and re-enter late on the next note — keep the count rolling, and rests stop being a trap.
        </Section>
      </div>
    );
  };

  window.PracticeLab.ui.LessonRests = LessonRests;
})();
