<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8">
	<meta http-equiv="x-ua-compatible" content="ie=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" href="favicon.ico" type="image/x-icon"/>
  <link rel="stylesheet" href="examples-styles.css"/>

	<title>abcjs: Play On Repeat Demo</title>

	<style>
		main {
			max-width: 770px;
			margin: 0 auto;
		}
		.abcjs-cursor {
			stroke: red;
		}
	</style>

	<script src="../dist/abcjs-basic.js" type="text/javascript"></script>
	<script type="text/javascript">
		var abc = "T: Cooley's\n" +
			"%%barnumbers 1\n" +
			"M: 4/4\n" +
			"L: 1/8\n" +
			"R: reel\n" +
			"K: Emin\n" +
			"EBBA B2 EB|~B2 AB dBAG|FDAD BDAD|FDAD dAFD|\n" +
			"EBBA B2 EB|B2 AB defg|afe^c dBAF|DEFD E2 gf|\n" +
			"|eB B2 efge|eB B2 gedB|A2 FA DAFA|A2 FA defg|\n" +
			"eB B2 eBgB|eB B2 defg|afe^c dBAF|DEFD E2 D2||";
		var NUM_MEASURES = 16;
		var NUM_BEATS_PER_MEASURE = 4;
		var synth = new ABCJS.synth.CreateSynth();
		var startMeasure;
		var endMeasure;
		var timingCallbacks;

		function load() {
			// First draw the music - this supplies an object that has a lot of information about how to create the synth.
			// NOTE: If you want just the sound without showing the music, use "*" instead of "paper" in the renderAbc call.
			var visualObj = ABCJS.renderAbc("paper", abc, {
				responsive: "resize" })[0];

			var startAudioButton = document.querySelector(".activate-audio");
			var stopAudioButton = document.querySelector(".stop-audio");
			var explanationDiv = document.querySelector(".suspend-explanation");
			startMeasure = document.querySelector("#start-measure");
			endMeasure = document.querySelector("#end-measure");

			startAudioButton.addEventListener("click", function() {
				startAudioButton.setAttribute("style", "display:none;");
				explanationDiv.setAttribute("style", "opacity: 0;");
				if (ABCJS.synth.supportsAudio()) {
					stopAudioButton.setAttribute("style", "");

					// An audio context is needed - this can be passed in for two reasons:
					// 1) So that you can share this audio context with other elements on your page.
					// 2) So that you can create it during a user interaction so that the browser doesn't block the sound.
					// Setting this is optional - if you don't set an audioContext, then abcjs will create one.
					window.AudioContext = window.AudioContext ||
						window.webkitAudioContext ||
						navigator.mozAudioContext ||
						navigator.msAudioContext;
					var audioContext = new window.AudioContext();
					audioContext.resume().then(function () {
						// In theory the AC shouldn't start suspended because it is being initialized in a click handler, but iOS seems to anyway.

						synth.init({
							audioContext: audioContext,
							visualObj: visualObj
						}).then(function () {
							timingCallbacks = new ABCJS.TimingCallbacks(visualObj, {
								beatCallback: cursorControl.onBeat,
								eventCallback: cursorControl.onEvent
							});
							cursorControl.onStart();
							synth.prime().then(function () {
								var start = (startMeasure.value - 1) / NUM_MEASURES;
								synth.seek(start);
								timingCallbacks.setProgress(start);
								synth.start();
								timingCallbacks.start();
							});
						}).catch(function (error) {
							console.log("Audio Failed", error);
						});
					});
				} else {
					var audioError = document.querySelector(".audio-error");
					audioError.setAttribute("style", "");
				}
			});

			stopAudioButton.addEventListener("click", function() {
				startAudioButton.setAttribute("style", "");
				explanationDiv.setAttribute("style", "");
				stopAudioButton.setAttribute("style", "display:none;");
				synth.stop();
				timingCallbacks.stop();
			});
		}

		function CursorControl() {
			var self = this;

			self.onStart = function() {
				var svg = document.querySelector("#paper svg");
				var cursor = document.createElementNS("http://www.w3.org/2000/svg", "line");
				cursor.setAttribute("class", "abcjs-cursor");
				cursor.setAttributeNS(null, 'x1', 0);
				cursor.setAttributeNS(null, 'y1', 0);
				cursor.setAttributeNS(null, 'x2', 0);
				cursor.setAttributeNS(null, 'y2', 0);
				svg.appendChild(cursor);

			};
			self.onBeat = function(beatNumber, totalBeats, totalTime) {
				console.log(beatNumber)
				var end = (endMeasure.value-1) * NUM_BEATS_PER_MEASURE;
				if (beatNumber >= end) {
					var start = (startMeasure.value-1) / NUM_MEASURES;
					synth.seek(start);
					timingCallbacks.setProgress(start);
				}
			};
			self.onEvent = function(ev) {
				if (ev.measureStart && ev.left === null)
					return; // this was the second part of a tie across a measure line. Just ignore it.

				var lastSelection = document.querySelectorAll("#paper svg .highlight");
				for (var k = 0; k < lastSelection.length; k++)
					lastSelection[k].classList.remove("highlight");

				for (var i = 0; i < ev.elements.length; i++ ) {
					var note = ev.elements[i];
					for (var j = 0; j < note.length; j++) {
						note[j].classList.add("highlight");
					}
				}

				var cursor = document.querySelector("#paper svg .abcjs-cursor");
				if (cursor) {
					cursor.setAttribute("x1", ev.left - 2);
					cursor.setAttribute("x2", ev.left - 2);
					cursor.setAttribute("y1", ev.top);
					cursor.setAttribute("y2", ev.top + ev.height);
				}
			};
			self.onFinished = function() {
				var els = document.querySelectorAll("svg .highlight");
				for (var i = 0; i < els.length; i++ ) {
					els[i].classList.remove("highlight");
				}
				var cursor = document.querySelector("#paper svg .abcjs-cursor");
				if (cursor) {
					cursor.setAttribute("x1", 0);
					cursor.setAttribute("x2", 0);
					cursor.setAttribute("y1", 0);
					cursor.setAttribute("y2", 0);
				}
			};
		}

		var cursorControl = new CursorControl();
	</script>
</head>
<body onload="load()">
  <header>
    <img src="https://paulrosen.github.io/abcjs/img/abcjs_comp_extended_08.svg" alt="abcjs logo">
    <h1>Play on Repeat</h1>
  </header>
  <div class="container">
    <main>
      <p>Demonstration of playing a selection of a tune in a loop. Set the start and end measures on the fly using the inputs.</p>
      <div>
      <label>Start Measure: <input type="number" min="1" max="16" id="start-measure" value="5"></label>
      <label>End Measure: <input type="number" min="1" max="16" id="end-measure" value="8"></label>
      </div>
      <div id="paper"></div>
      <p class="suspend-explanation">Browsers won't allow audio to work unless the audio is started in response to a user action. This prevents auto-playing web sites. Therefore, the
        following button is needed to do the initialization:</p>
      <button class="activate-audio">Activate Audio Context And Play</button>
      <button class="stop-audio" style="display:none;">Stop Audio</button>
      <div class='audio-error' style="display:none;">Audio is not supported in this browser.</div>
    </main>
  </div>
</body>
</html>