/*
 * Test code for playing melodies.
 *
 * https://github.com/arduino12 11/12/2021
 */
#include "notes.h"
#include "melodies.h"

#define SPEAKER_PIN             (8)
#define BUTTON_PIN              (10)
#define ARRAY_COUNT(arr)        (sizeof(arr) / sizeof(arr[0]))

const uint16_t *melodies[] = {
  MELODY_360_START,
  MELODY_360_GOOD,
	MELODY_HAPPY_BIRTHDAY,
	MELODY_LITTLE_JONATHAN,
	MELODY_HANUKKAH,
	MELODY_HATIKVA,
};

bool is_button_pressed()
{
  return !digitalRead(BUTTON_PIN);
}

bool beep_delay_button(uint16_t freq, uint32_t ms)
{
  if (freq)
    tone(SPEAKER_PIN, freq);
  else
    noTone(SPEAKER_PIN);

	ms += millis();
	while (millis() < ms)
		if (is_button_pressed()) {
      noTone(SPEAKER_PIN);
      while (is_button_pressed());
      delay(100);
			return true;
    }
	return false;
}

bool play_melody(const uint16_t *melody)
{
	uint16_t note, duration, note_1_32_ms = 7500 / pgm_read_word(melody++);

	while (1) {
		note = pgm_read_word(melody++);
		if (note == NOTE_END)
			return false;

    duration = note_1_32_ms * pgm_read_byte(NOTE_BEAT_1_32 + (note >> NOTE_BEAT_BIT));
		if (beep_delay_button(note & NOTE_BEAT_MASK, duration))
			return true;

		if (beep_delay_button(0, note_1_32_ms * 2)) // short note pause
			return true;
	}
}

void setup()
{ 
  pinMode(SPEAKER_PIN, OUTPUT);
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  delay(1000); // needed for simulation only because the first call to tone takes time to start
}

void loop()
{
  static uint8_t cur_melody_index = 0;

  if (play_melody(melodies[cur_melody_index])) {
    while (!is_button_pressed())
      delay(100);
    while (is_button_pressed())
      delay(100);
  }
  else
    delay(1000);

  if (++cur_melody_index >= ARRAY_COUNT(melodies))
    cur_melody_index = 0;
}