#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;

int buttonPins[16] = {19,18,17,16,15,14,2,3,4,5,6,7,8,9,12,13};   // Pins, an denen die Taster angeschlossen sind

void setup() {
  mySoftwareSerial.begin(9600);           // Start der SoftwareSerial Kommunikation
  Serial.begin(9600);                   // Start der "normalen" seriellen Kommunikation für den Serial Monitor

  if (!myDFPlayer.begin(mySoftwareSerial)) {  // Verbindung der Software Serial Kommunikation mit dem DFPlayer
    Serial.println(F("Unable to begin:"));
    Serial.println(F("1.Please recheck the connection!"));
    Serial.println(F("2.Please insert the SD card!"));
    while(true){                          // Programmabbruch -> while(true) ist Endlosschleife
      delay(0);                           // Code für den Watchdog des ESP8266, nicht relevant für Arduino UNO
    }
  }
  

    
  myDFPlayer.volume(20);                      // Lautstärke auf 10 ( Werte von 0 – 30 ist möglich)  Nastavení hlasitosti trvale. Rád bych ji ale reguloval dvěmi tlačítky, tak aby si nastavenou hodnotu tlačítky trvale pamatoval.
  for (int i=0; i<16; i++){                   // wiederhole 16 Mal (für jeden Taster)
    pinMode(buttonPins[i], INPUT_PULLUP);     // Taster werden mit internen Pullup-Widerständen verwendet  
  }
  
}

void loop() {
  for (int i=0; i<16; i++){                   // wiederhole 16 Mal (für jeden Taster)
    if (digitalRead(buttonPins[i]) == LOW){   // wenn ein Taster gedrückt wird
     Serial.println(i);
     myDFPlayer.playMp3Folder(i+1);                      // spiele das MP3 der Nummer des Tasters nach von der SD-Karte
     delay(200);
    }
  }



  delay(20);      // Pokyn k možnému znovu stisknutí tlačítka. Sem bych potřeboval zadat příkaz, aby byla zpětná vazba z DFPlayeru, když skončí stopa, tak teprve potom je možno ji pustit znova. 






  /* Alles ab hier dient dem Debugging und kommt aus den Beispiel-Dateien der Library */
  if (myDFPlayer.available()) {
    printDetail(myDFPlayer.readType(), myDFPlayer.read()); // Print the detail message from DFPlayer to handle different errors and states.
  }
}

void printDetail(uint8_t type, int value){
 
  switch (type) {
    case TimeOut:
      Serial.println(F("Time Out!"));
      break;
    case WrongStack:
      Serial.println(F("Stack Wrong!"));
      break;
    case DFPlayerCardInserted:
      Serial.println(F("Card Inserted!"));
      break;
    case DFPlayerCardRemoved:
      Serial.println(F("Card Removed!"));
      break;
    case DFPlayerCardOnline:
      Serial.println(F("Card Online!"));
      break;
    case DFPlayerUSBInserted:
      Serial.println("USB Inserted!");
      break;
    case DFPlayerUSBRemoved:
      Serial.println("USB Removed!");
      break;
    case DFPlayerPlayFinished:
      Serial.print(F("Number:"));
      Serial.print(value);
      Serial.println(F(" Play Finished!"));
      break;
    case DFPlayerError:
      Serial.print(F("DFPlayerError:"));
      switch (value) {
        case Busy:
          Serial.println(F("Card not found"));
          break;
        case Sleeping:
          Serial.println(F("Sleeping"));
          break;
        case SerialWrongStack:
          Serial.println(F("Get Wrong Stack"));
          break;
        case CheckSumNotMatch:
          Serial.println(F("Check Sum Not Match"));
          break;
        case FileIndexOut:
          Serial.println(F("File Index Out of Bound"));
          break;
        case FileMismatch:
          Serial.println(F("Cannot Find File"));
          break;
        case Advertise:
          Serial.println(F("In Advertise"));
          break;
        default:
          break;
      }
      break;
    default:
      break;
  }
}