#include <DFPlayerMini_Fast.h>
#include <SoftwareSerial.h>
#include <Keypad.h>

DFPlayerMini_Fast DF1;
SoftwareSerial DFSoftwareSerial(10, 11); // RX, TX

const byte ROWS = 3;
const byte COLS = 3;

// how the keypad has its keys laid out
const char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
};

const byte colPins[COLS] = {2, 3, 4}; //connect to the column pinouts of the keypad
const byte rowPins[ROWS] = {5, 6, 7}; //connect to the row pinouts of the keypad

Keypad keypad = Keypad (makeKeymap (keys), rowPins, colPins, ROWS, COLS );

unsigned long time_lastledblink = 0;
unsigned long time_lastactivity = 0;

// Shutdown after this many milleseconds of inactivity
const unsigned long time_shutdowndelay = 5000;

void play_song(char id) {
  Serial.println("play_song()");
  Serial.println(id);
  
  switch (id) {
    case '1': DF1.playFromMP3Folder(1); break;
    case '2': DF1.playFromMP3Folder(2); break;
    case '3': DF1.playFromMP3Folder(3); break;
    case '4': DF1.playFromMP3Folder(4); break;
    case '5': DF1.playFromMP3Folder(5); break;
    case '6': DF1.playFromMP3Folder(6); break;
    case '7': DF1.playFromMP3Folder(7); break;
    case '8': DF1.playFromMP3Folder(8); break;
    case '9': DF1.playFromMP3Folder(9); break;
  }
}

void setup() {
  Serial.begin(9600);
	DFSoftwareSerial.begin(9600);

  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_BUILTIN, OUTPUT);

	// Use pin 13 for shutting down
	pinMode(13, OUTPUT); // sets the digital pin 13 as output

	time_lastactivity = millis();

	// Init DFplayer serial
  DF1.begin(DFSoftwareSerial, false);

  Serial.println("Setting volume to 30/30");
  DF1.volume(30);
}

void loop() {
  char key = keypad.getKey();
  
  if (key) {
    play_song(key);
  }

  // Blink LED 50ms when playing, 500ms when not
  if (DF1.isPlaying()) {
		if (millis() - time_lastledblink > 50) {
    	digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
    	time_lastledblink = millis();
		}
		time_lastactivity = millis();
  } else
  if (millis() - time_lastledblink > 500) {     
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN)); 
    time_lastledblink = millis(); 
  }

	if (millis() - time_lastactivity > time_shutdowndelay) {
		// Play shutdown music, wait a bit, then send shutdown to pololu switch & turn off ourselves
		Serial.println("Shutting down after idle timeout.");
		DF1.playFromMP3Folder(0);
		delay(3000);
		digitalWrite(13, HIGH);
	}
}