/*Written by T.P. GOFF for Norwich Hckspace Musical LED Fesite Bauble project*/

/* Notes frequency:
C = 523
d = 587
e = 659
f = 698
g = 784
*/


// Define pin numbers
const int buttonPin = 2;    // Pin for button
const int buzzerPin = 3;     // Pin for buzzer

const int led1 = 4;     // Pin for led
const int led2 = 5;     // Pin for led
const int led3 = 6;     // Pin for led
const int led4 = 7;     // Pin for led
const int led5 = 8;     // Pin for led
const int led6 = 9;     // Pin for led
const int led7 = 10;     // Pin for led
const int led8 = 11;     // Pin for led

int ledArray [] = {led1, led2, led3, led4, led5, led6, led7, led8};

// Button state variables
bool buttonState = HIGH;     // Current state of the button
bool lastButtonState = HIGH; // Previous state of the button
unsigned long lastDebounceTime = 0;  // Debounce timer
unsigned long debounceDelay = 50;    // Debounce delay in milliseconds

// Frequencies for Jingle Bells chorus (notes in Hz)
int melody[] = {
  659, 659, 659,  // E E E jingle bells
  659, 659, 659,  // E E E jingle bells
  659, 784, 523, 587, 659,  // E G C D E jingle all the way
  698, 698, 698, 698, 698,  // F F F F F oh what fun it is
  659, 659, 659, 659, //E E E to ride on a 
  784, 784, 698, 587, 523  // G G F D C one horse open slay

 
};

// Note durations (4 = quarter note, 8 = eighth note, etc.)
int noteDurations[] = {
  8, 8, 4,  
  8, 8, 4,  
  8, 8, 8, 8, 2,  
  8, 8, 8, 12, 8,
  8, 8, 8, 8,  
  8, 8, 8, 8, 2  
};

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);  // Set button pin as input with internal pull-up
  pinMode(buzzerPin, OUTPUT);        // Set buzzer pin as output

  // for loop to set all led pins as outputs.
  for (int i = 0; i<8; i++) {
    pinMode (ledArray[i], OUTPUT);
  }
}

void loop() {
  // Read the state of the button
  int reading = digitalRead(buttonPin);

  // Debounce the button press
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading == LOW && buttonState == HIGH) {
      // Button was pressed, so play the melody
      ledChaser1();
      playJingleBells();
      ledChaser2();
    }
    buttonState = reading;
  }

  lastButtonState = reading;
}

// Function to play the full chorus of Jingle Bells
void playJingleBells() {
  int totalNotes = sizeof(melody) / sizeof(melody[0]);  // Calculate number of notes in the melody
  for (int thisNote = 0; thisNote < totalNotes; thisNote++) {
    // Calculate the note duration
    int noteDuration = 1000 / noteDurations[thisNote];
    tone(buzzerPin, melody[thisNote], noteDuration);
    
    // Pause for the note's duration plus 30% gap between notes
    int pauseBetweenNotes = noteDuration * 1.30;
    delay(pauseBetweenNotes);

    // Stop the tone after the note is played
    noTone(buzzerPin);
  }
}


// Function turn on LEDs CW
void ledChaser1() {

// turn lights off

for (int i = 0; i<8; i++) {
  digitalWrite (ledArray[i], LOW);
}

for (int i = 0; i<8; i++) {
  digitalWrite (ledArray[i], HIGH);
  delay (100);
}
}


// Function turn on LEDs CCW
void ledChaser2() {

// turn lights off

for (int i = 0; i<8; i++) {
  digitalWrite (ledArray[i], LOW);
}

for (int i = 8; i>=0; i--) {
  digitalWrite (ledArray[i], HIGH);
  delay (100);
}
}
