// Library Imports 

// Written by the IP-Team 13 
// E.S

#include <SoftwareSerial.h>
#include <DFRobotDFPlayerMini.h>
#include <Wire.h>
#include <Adafruit_PN532.h>

//Pin Definition

#define SDA_PIN 21   // Pin für SDA beim PN532
#define SCL_PIN 22   // Pin für SCL beim PN532
#define RSTO_PIN 5   // Pin für SDA beim PN532
#define IRQ_PIN 18   // Pin für SCL beim PN532

// Modul-Object Initiation 

Adafruit_PN532 nfc(IRQ_PIN, RSTO_PIN);
SoftwareSerial mySerial(16, 17);
DFRobotDFPlayerMini mp3;

// Setup

void setup() {

// Start Serial Connection

  Serial.begin(115200);
  mySerial.begin(9600);

// Start Module Objects

  Wire.begin();
  nfc.begin();


// Check MP3-Module

  if (!mp3.begin(mySerial)) {
    while (true) {
      delay(0);
    }
  }

// Set Volume 

  mp3.volume(30);


// Check PN532

  uint32_t versionData = nfc.getFirmwareVersion();
  if (!versionData) {
    Serial.println("Didn't find PN53x board");
    while (1);
  }
}


// Loop 

void loop() {

// Define Variables

  uint8_t success;
  uint8_t uid[] = {0, 0, 0, 0, 0, 0, 0};
  uint8_t uidLength;

// Read NFC 

  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);


  if (success) {

// Analyse Data 

    for (uint8_t block = 7; block < 8; block++) {
      uint8_t data[16];
      success = nfc.mifareclassic_ReadDataBlock(block, data);

      if (success) {

        // Get Hexadecimal Format

        String firstByteAsString = String(data[0], HEX);
       
       // Play Card Name

       playCardName(firstByteAsString);
       
      } 
      else {
        
        // Error Handling
        
        Serial.println("Read failed!");
      }
      Serial.println("");
    }

    // Reduction of Workload 
    delay(1000);
  }
}


// Function : Handling Hexadecimal Format

void playCardName(String hexMod) {
  
  // Copy the String
  
  String kopie = hexMod;
  
  // Define Variables 

  int farbe, symbol;

// Check the length of the String for leading zeros

  if (hexMod.length() == 1) {
    
    // Converting the Hexadecimal to a leading zero Format

    hexMod = String("00" + hexMod).substring(hexMod.length(), hexMod.length() + 2);
    
    // Setting the Color to Red 
    
    farbe = 0;
    
    // Get the Charakter for the Symbol

    int symbolChar = hexMod.charAt(1);


// Check if the Symbol is one of the letter s a to f

    if (symbolChar >= 'a' && symbolChar <= 'f') {
    
    // Calculate the decimal number for the letters from a to f
      symbol = 10 + (symbolChar - 'a');
    } else {

        // Calculate the Decimal Number of the Hexadecimal Number
      symbol = hexMod.charAt(1)-'0';
    }
  } 
  else {

    // Define Variables

    farbe = hexMod.substring(0, 1).toInt();
    int symbolChar = hexMod.charAt(1);


// Check if the Symbol is a letter between a and f

    if (symbolChar >= 'a' && symbolChar <= 'f') {
      // Wenn das Symbol eine der Zeichen 'A' bis 'F' ist, ordne es richtig zu
      symbol = 10 + (symbolChar - 'a');
    } else {

    // Covert the String to a Decimal Number
      symbol = hexMod.substring(1, 2).toInt();
    }
  }

// Play the Corrosponding Audiofile from the Storage

  playCard(farbe, symbol);
}



// Function: Playing the corrosponding Audiofile for the Cardname

void playCard(int farbNummer, int symbolNummer) {
  
  // First Switch : Check the Color 

  switch (farbNummer) {
    case 0: mp3.play(16); break; // Red
    case 1: mp3.play(17); break; // Yellow
    case 2: mp3.play(18); break; // Blue
    case 3: mp3.play(19); break; // Green
    case 4: mp3.play(20); break; // black
  }

  // Wait 2 Seconds to avoid Latency or Noises of the File

  delay(2000);

    // Switch 2: Check the Symbol 

  switch (symbolNummer) {
    case 0: mp3.play(1);  break; // Zero
    case 1: mp3.play(2);  break; // One
    case 2: mp3.play(3);  break; // Two 
    case 3: mp3.play(4);  break; // Three
    case 4: mp3.play(5);  break; // Four
    case 5: mp3.play(6);  break; // Five 
    case 6: mp3.play(7);  break; // Six
    case 7: mp3.play(8);  break; // Seven
    case 8: mp3.play(9);  break; // Eight
    case 9: mp3.play(10); break; // Nine
    case 10: mp3.play(11); break; // Skip
    case 11: mp3.play(12); break; // Reverse 
    case 12: mp3.play(13); break; // Draw 2
    case 13: mp3.play(15); break; // Draw 4
    case 14: mp3.play(14); break; // Color Change
  }

// Wait 1 Seconds to avoid noises and latency

  delay(1000);
}
