#include <SPI.h>
#include <MFRC522.h>


#define SDA_PIN 5  // SDA Pin
#define RST_PIN 4  // Reset Pin

// Create an instance of MFRC522 
MFRC522 mfrc522(SDA_PIN, RST_PIN);

// Create an instance of MIFARE_Key 
MFRC522::MIFARE_Key key;          

int blockNum = 2;         //choose which block to write to
byte leveltoken;          //level stored on the token
byte inputLevel = 7;      //value which will not be reached by the buttons to make sure the user can only select one level to be written
byte blockData[2];        //array to store the input level

void setup() 
{
  // Initialize serial communications with the PC 
  Serial.begin(115200);
  // Initialize SPI bus 
  SPI.begin();
  // Initialize MFRC522 Module 
  mfrc522.PCD_Init();
  pinMode(13, OUTPUT); //Red Led
  pinMode(12, OUTPUT); //LVL1
  pinMode(14, OUTPUT); //LVL2
  pinMode(27, OUTPUT); //LVL3
  pinMode(26, OUTPUT); //LVL4
  pinMode(25, INPUT); //Button LVL0
  pinMode(33, INPUT); //Button LVL1
  pinMode(32, INPUT); //Button LVL2
  pinMode(35, INPUT); //Button LVL3
  pinMode(34, INPUT); //Button LVL4
}

void loop()
{
  // by checking if inputlevel equals 7, the program makes sure that multiple levels can't be selected by spamming buttons.
  while (inputLevel == 7){
    if (digitalRead(25) == 1){
      inputLevel = 0;
      digitalWrite(13, HIGH);
    }
    if ((digitalRead(33) == 1) && (inputLevel == 7)){
      inputLevel = 1;
      digitalWrite(12, HIGH);
    }
    if ((digitalRead(32) == 1) && (inputLevel == 7)){
      inputLevel = 2;
      digitalWrite(12, HIGH);
      digitalWrite(14, HIGH);
    }
    if ((digitalRead(35) == 1) && (inputLevel == 7)){
      inputLevel = 3;
      digitalWrite(12, HIGH);
      digitalWrite(14, HIGH);
      digitalWrite(27, HIGH);
    }
    if ((digitalRead(34) == 1) && (inputLevel == 7)){
      inputLevel = 4;
      digitalWrite(12, HIGH);
      digitalWrite(14, HIGH);
      digitalWrite(27, HIGH);
      digitalWrite(26, HIGH);
    }
    blockData[0] = inputLevel;
    Serial.println(inputLevel);
  }

  // Prepare the ksy for authentication 
  // All keys are set to FFFFFFFFFFFFh at chip delivery from the factory 
  for (byte i = 0; i < 6; i++)
  {
    key.keyByte[i] = 0xFF;
  }

  // Look for new cards 
  // Reset the loop if no new card is present on RC522 Reader 
  if ( ! mfrc522.PICC_IsNewCardPresent())
  {
    return;
  }

  // Select one of the cards 
  if ( ! mfrc522.PICC_ReadCardSerial()) 
  {
    return;
  }

  // Authenticating the desired data block for write access using Key A 
  mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, blockNum, &key, &(mfrc522.uid));
  // Write data to the block 
  mfrc522.MIFARE_Write(blockNum, blockData, 16);

  //flash the red light
  if(inputLevel == 0){
    digitalWrite(13, LOW);
    delay(500);
    digitalWrite(13, HIGH);
  }
  //flash one green light
  else if(inputLevel == 1){
    digitalWrite(12, LOW);
    delay(500);
    digitalWrite(12, HIGH);
  }
  //flash 2 green lights
  else if(inputLevel == 2){
    digitalWrite(12, LOW);
    digitalWrite(14, LOW);
    delay(500);
    digitalWrite(12, HIGH);
    digitalWrite(14, HIGH);
  }
  //flash 3 green lights
  else if(inputLevel == 3){
    digitalWrite(12, LOW);
    digitalWrite(14, LOW);
    digitalWrite(27, LOW);
    delay(500);
    digitalWrite(12, HIGH);
    digitalWrite(14, HIGH);
    digitalWrite(27, HIGH);
  }
  //flash 4 green lights
  else if(inputLevel == 4){
    digitalWrite(12, LOW);
    digitalWrite(14, LOW);
    digitalWrite(27, LOW);
    digitalWrite(26, LOW);
    delay(500);
    digitalWrite(12, HIGH);
    digitalWrite(14, HIGH);
    digitalWrite(27, HIGH);
    digitalWrite(26, HIGH);
  }
  //error flash
  else{
    digitalWrite(13, HIGH);
    digitalWrite(12, LOW);
    digitalWrite(14, HIGH);
    digitalWrite(27, LOW);
    digitalWrite(26, HIGH);
  }

  delay(500);
  //turn all leds off
  digitalWrite(13, LOW);
  digitalWrite(12, LOW);
  digitalWrite(14, LOW);
  digitalWrite(27, LOW);
  digitalWrite(26, LOW);

  ESP.restart();
}
