/* global React, window, Vex */
// Lesson 2.3 — Time signatures.
// 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 one bar with the given time sig + a canonical pattern from
  // PATTERNS_BY_TIMESIG. We pick the FIRST pattern in the list so the
  // demo lines up with what the lesson explains visually.
  function renderTimeSigBar(containerEl, tsId) {
    if (!vexAvailable() || !containerEl) return;
    containerEl.innerHTML = '';
    try {
      var VF = window.Vex.Flow;
      var ts = window.PracticeLab.rhythm.getTimeSig(tsId);
      if (!ts) return;
      var patterns = window.PracticeLab.rhythm.patternsForTimeSig(tsId);
      if (patterns.length === 0) return;
      var pattern = patterns[0];

      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(tsId);
      stave.setContext(ctx).draw();

      var vexNotes = pattern.events.map(function (e) {
        var info = window.PracticeLab.rhythm.lookup(e.value);
        if (!info) return null;
        // Pick a default pitch for rendering. Rests ignore key but VF
        // still wants something parseable in `keys`.
        var keys = ['b/4'];
        return new VF.StaveNote({
          clef: 'treble',
          keys: keys,
          duration: info.vex,
          autoStem: true,
        });
      }).filter(function (n) { return n; });

      var voice = new VF.Voice({ num_beats: ts.num, beat_value: ts.den });
      voice.setStrict(false);
      voice.addTickables(vexNotes);
      new VF.Formatter().joinVoices([voice]).format([voice], width - 90);
      voice.draw(ctx, stave);
    } catch (e) {}
  }

  var LessonTimeSignatures = 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 fourRef = React.useRef(null);
    const threeRef = React.useRef(null);
    const sixRef = 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;
      renderTimeSigBar(fourRef.current,  '4/4');
      renderTimeSigBar(threeRef.current, '3/4');
      renderTimeSigBar(sixRef.current,   '6/8');
    }, [vexReady]);

    const playFirstPattern = React.useCallback(function (tsId, bpm) {
      var patterns = rhythm.patternsForTimeSig(tsId);
      if (!patterns.length) return Promise.resolve(false);
      var timeline = rhythm.patternToTimeline(patterns[0]);
      return audio.playRhythm(timeline, bpm, { withMetronome: true });
    }, [audio, rhythm]);

    return (
      <div>
        <Section heading="The two numbers at the start of a piece">
          At the start of every piece you see two numbers stacked like a fraction — that's the <strong>time signature</strong>. It tells you how the music is grouped:
          <ul style={{ marginTop: 8, marginBottom: 0, paddingLeft: 20 }}>
            <li>The <strong>top number</strong> = how many beats per bar.</li>
            <li>The <strong>bottom number</strong> = what kind of note gets one beat (4 = quarter note, 8 = eighth note).</li>
          </ul>
        </Section>

        <Section heading="4/4 — the most common">
          Four quarter notes per bar. The vast majority of pop, rock, soul, country, and gospel is in 4/4. Beat 1 is the strongest, beat 3 a softer "down", 2 and 4 are the backbeat.
          <DemoBox label="4/4 — count: 1 2 3 4 | 1 2 3 4">
            <div ref={fourRef} />
            <div style={{ marginTop: 10 }}>
              <PlayButton label="Play in 4/4" onPlay={function () { return playFirstPattern('4/4', 90); }} />
            </div>
          </DemoBox>
        </Section>

        <Section heading="3/4 — the waltz">
          Three beats per bar — that distinctive <em>ONE-two-three, ONE-two-three</em> feel. Used in classical waltzes, country ballads, and a lot of Disney songs.
          <DemoBox label="3/4 — count: 1 2 3 | 1 2 3">
            <div ref={threeRef} />
            <div style={{ marginTop: 10 }}>
              <PlayButton label="Play in 3/4" onPlay={function () { return playFirstPattern('3/4', 100); }} />
            </div>
          </DemoBox>
        </Section>

        <Section heading="6/8 — compound time">
          Six eighth notes per bar, but felt in <strong>two</strong> — each group of three eighths counts as one larger beat. That's why 6/8 has a swinging, lilting feel. Think nursery rhymes and Irish jigs.
          <DemoBox label="6/8 — count: 1-2-3 4-5-6 | 1-2-3 4-5-6">
            <div ref={sixRef} />
            <div style={{ marginTop: 10 }}>
              <PlayButton label="Play in 6/8" onPlay={function () { return playFirstPattern('6/8', 130); }} />
            </div>
          </DemoBox>
        </Section>

        <Section heading="How to feel the difference" last>
          The fastest way to internalize a time signature is to clap on beat 1 every bar. In 4/4 you'll clap every 4 ticks; in 3/4 every 3; in 6/8 every 6 (or every "main beat" — two claps per bar). The next two lessons drill this with quizzes.
        </Section>
      </div>
    );
  };

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