/*
  Bulldozer

  by Chris Ritchie - 02/11/2017

  Tones from http://arcadetones.emuunlim.com/
*/

#include <avr/sleep.h>
#include <avr/interrupt.h>
#include <rtttl.h>

// Define pins for speaker, LEDs and button
const int pinSpeaker = 1;
const int yellowLED = 0;
const int redLED = 4;
const int playBttn = 2;

// State of button
boolean playState = 0;

// Song to play
int playSong = 0;
const int octave = 0;

const char song_0[] PROGMEM =
  "gbusters:d=4,o=5,b=112:16b,16b,8d#6,8b,8c#6,8a,2p,16b,16b,16b,16b,8a,8b,2p,16b,16b,8d#6,8b,8c#6,8a,2p,16b,16b,16b,16b,8a,8c#6,8b";
const char song_1[] PROGMEM =
  "pacinter:d=4,o=5,b=160:8f#6,8f#6,8f#6,16d#6,16c#6,16f#6,8f#6,8a.6,8p,8f#6,8f#6,8f#6,16d#6,16c#6,16f#6,8f#6,8d#.6,8p,8f#6,8f#6,8f#6,16d#6,16c#6,16f#6,8f#6,8a6,8b6,8c7,8b6,8a6,8f#6,8a.6,8f#6,8p,8f#6,8f#6,8f#6,16d#6,16c#6,16f#6,8f#6,8a.6,8p,8f#6,8f#6,8f#6,16d#6,16c#6,16f#6,8f#6,8d#.6,8p,8f#6,8f#6,8f#6,16d#6,16c#6,16f#6,8f#6,8a6,8b6,8c7,8b6,8a6,8f#6,8a.6,8f#6";
const char song_2[] PROGMEM =
  "starwars:d=4,o=5,b=180:8f,8f,8f,2a#.,2f.6,8d#6,8d6,8c6,2a#.6,f.6,8d#6,8d6,8c6,2a#.6,f.6,8d#6,8d6,8d#6,2c6,p,8f,8f,8f,2a#.,2f.6,8d#6,8d6,8c6,2a#.6,f.6,8d#6,8d6,8c6,2a#.6,f.6,8d#6,8d6,8d#6,2c6";
const char song_3[] PROGMEM =
  "tmnt:d=4,o=5,b=100:8e,8f#,8e,8f#,8e,16f#,8e.,8f#,8g,8a,8g,8a,8g,16a,8g.,8a,8c6,8d6,8c6,8d6,8c6,16d6,8c.6,8d6,16a,16a,16a,16a,8g,8a,8p,16a,16a,16a,16a";
const char song_4[] PROGMEM =
  "alteredb:d=2,o=6,b=63:16d#,16c#,16d#,8g#5,16a#5,16b5,16c#,16c#,16b5,16c#,8f#5,16g#5,16a#5,16b5,16d#,16c#,16d#,8g#5,16a#5,16b5,16c#,16c#,16b5,16c#,8f#5,16g#5,16a#5,16b5,16d#,16c#,16d#,8g#,16f#,16e,16d#,16c#,16b5,16c#,8d#,16a#5,16g#5,16f#5,g#5";
const char song_5[] PROGMEM =
  "dkctitle:d=4,o=5,b=125:8c,8c,a.,p,8f,8g,8f,d.,p,8d,8d,a#.,p,8g,8a,8g,e.,p,8e,8e,c.6,p,8a,8a#,8c6,d.6,p,8f,8g,a,f,8p,8e,8f,8g,d.";
const char song_6[] PROGMEM =
  "scooby:d=4,o=5,b=80:16e6,16e6,16d6,16d6,c6,16d6,8f6,a,16a,8b,8g,8e6,16e6,8d6,c6,16p,16e6,16e6,16d6,16d6,c6,16d6,8e6,f6,16a,8g,8g,8e6,16e6,8d6,c6";
const char song_7[] PROGMEM =
  "larry:d=4,o=5,b=112:8e,16p,8f,16p,8f#,16p,8g,16a,8e,8g,16p,8a,16p,16e,8g,16a,8g,8c.6,p,8a,16c6,8g#,8a,16p,8c6,16p,16g#,8a,16c6,8d6,8d#.6,16p,8c6,16p,8e6,16p,8e6,16p,8e6,16p,8e6,16p,8e6,16d#6,8d6,8c#.6,16p,8a,16p,8d#6,16e6,8d#6,16e6,8c6,8d6,16p,8c6,16p";
const char song_8[] PROGMEM =
  "themepark:d=4,o=5,b=125:8b,8a#,16a,16a#,16a,16g#,8g,8f#,8f,8f#,8g#,8f#,16f,16f#,16f,16f#,8e,8d#,8d,8d#,8f#,16d#,16e,8c,8c#,8f#,16d#,16e,8c,8c#,16a#4,16b4,16c,16c#,16d,16d#,16e,16f,16f#,16g,16g#,16a#,8g#,8f#,8b,8a#,16a,16a#,16a,16g#,8g,8f#,8f,8f#,8g#,8f#,16f,16f#,16f,16f#,8e,8d#,8d,8d#,8f#,16d#,16e,8c,8c#,8f#,16d#,16e,8c,8c#,16a#4,16b4,16c#,16d#,16e,16f#,16g#,16a#,8b,8f#,8b";
const char song_9[] PROGMEM =
  "mission:d=4,o=6,b=100:32d,32d#,32d,32d#,32d,32d#,32d,32d#,32d,32d,32d#,32e,32f,32f#,32g,16g,8p,16g,8p,16a#,16p,16c7,16p,16g,8p,16g,8p,16f,16p,16f#,16p,16g,8p,16g,8p,16a#,16p,16c7,16p,16g,8p,16g,8p,16f,16p,16f#,16p,16a#,16g,2d,32p,16a#,16g,2c#,32p,16a#,16g,2c,16p,16a#5,16c";
const char song_10[] PROGMEM =
  "Indy:d=4,o=5,b=250:e,8p,8f,8g,8p,1c6,8p.,d,8p,8e,1f,p.,g,8p,8a,8b,8p,1f6,p,a,8p,8b,2c6,2d6,2e6,e,8p,8f,8g,8p,1c6,p,d6,8p,8e6,1f.6,g,8p,8g,e.6,8p,d6,8p,8g,e.6,8p,d6,8p,8g,f.6,8p,e6,8p,8d6,2c6";
const char song_11[] PROGMEM =
  "xmen:d=4,o=6,b=140:16f#5,16g5,16b5,16d,c#,8b5,8f#5,p,16f#5,16g5,16b5,16d,c#,8b5,8g5,p,16f#5,16g5,16b5,16d,c#,8b5,8d,2p,8c#,8b5,2p,16b5,16e,16f#,16g,f#,8e,8b5,p,16b5,16e,16f#,16g,f#,8e,8c,p,16f#5,16g5,16b5,16d,c#,8b5,8d,2p,8c#,8b5,2p";
const char song_12[] PROGMEM =
  "Takeonme:d=4,o=5,b=180:8e6,8e6,8c6,a,a,d6,d6,16d6,16d6,8f#6,8f#6,8g6,8a6,8g6,8g6,8g6,d6,c6,e6,e6,16e6,16e6,8d6,8d6,8e6,8d6,8e6,8e6,8c6,a,a,d6,d6,8d6,8f#6,8f#6,8g6,8a6,8g6,8g6,8g6,d6,c6,e6,e6,8e6,8d6,8d6,8e6,8d6";

Rtttl player;

void setup(void)
{
  analogReference(INTERNAL);
  pinMode(playBttn, INPUT_PULLUP);
  pinMode(yellowLED, OUTPUT);
  pinMode(redLED, OUTPUT);

  player.begin(pinSpeaker);

}

void loop(void)
{
  sleep(); // Stay in low power mode until button is pressed

  playState = digitalRead(playBttn); // Check state of button

  // Play song if button is pressed
  if (playState == LOW)
  {
    // Reset playSong variable if all songs have been played
    if (playSong > 12) playSong = 0;

    switch (playSong)
    {
      case 0:
        player.play_P(song_0, octave);
        break;
      case 1:
        player.play_P(song_1, octave);
        break;
      case 2:
        player.play_P(song_2, octave);
        break;
      case 3:
        player.play_P(song_3, octave);
        break;
      case 4:
        player.play_P(song_4, octave);
        break;
      case 5:
        player.play_P(song_5, octave);
        break;
      case 6:
        player.play_P(song_6, octave);
        break;
      case 7:
        player.play_P(song_7, octave);
        break;
      case 8:
        player.play_P(song_8, octave);
        break;
      case 9:
        player.play_P(song_9, octave);
        break;
      case 10:
        player.play_P(song_10, octave);
        break;
      case 11:
        player.play_P(song_11, octave);
        break;
      case 12:
        player.play_P(song_12, octave);
        break;
    }

    playSong++;
  }
}

void sleep() {

  GIMSK |= _BV(PCIE);                     // Enable Pin Change Interrupts
  PCMSK |= _BV(PCINT2);                   // Use PB2 as interrupt pin
  PCMSK |= _BV(PCINT3);                   // Use PB3 as interrupt pin
  PCMSK |= _BV(PCINT4);                   // Use PB4 as interrupt pin
  ADCSRA &= ~_BV(ADEN);                   // ADC off
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);    // replaces above statement

  sleep_enable();                         // Sets the Sleep Enable bit in the MCUCR Register (SE BIT)
  sei();                                  // Enable interrupts
  sleep_cpu();                            // sleep

  cli();                                  // Disable interrupts
  PCMSK &= ~_BV(PCINT2);                  // Turn off PB2 as interrupt pin
  PCMSK &= ~_BV(PCINT3);                  // Turn off PB3 as interrupt pin
  PCMSK &= ~_BV(PCINT4);                  // Turn off PB4 as interrupt pin
  sleep_disable();                        // Clear SE bit
  ADCSRA |= _BV(ADEN);                    // ADC on

  sei();                                  // Enable interrupts
} // sleep

ISR(PCINT0_vect) {
  // This is called when the interrupt occurs, but I don't need to do anything in it
}