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


#define SDA_PIN 5         //define SDA Pin
#define RST_PIN 4         //define RST Pin
#define SecurityLevel 1   //define securitylevel

// 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 bufferLen = 18;      //determine the bufferlength (2 more than the read array)
byte readBlockData[16];   //read array
byte leveltoken;          //level stored on the token
byte SL = SecurityLevel;   //the determines security 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
}

void loop()
{
  // 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 Read access using Key A 
  mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, blockNum, &key, &(mfrc522.uid));
  // Reading data from the Block 
  mfrc522.MIFARE_Read(blockNum, readBlockData, &bufferLen);

  // Print the data read from block 
  leveltoken = readBlockData[0];

  //if token level is bigger or equal to securitylevel
  if(int(leveltoken) >= int(SL)){
  Serial.println("Acces Granted!");
  }
  //else turn on the red light, this will make sure the current level is shown with a red light to indicate restricted access
  else{
    Serial.println("Acces Restricted.");
    //turn on the red light
    digitalWrite(13, HIGH);
  }
  //flash one green light
  if(leveltoken == 1){
    digitalWrite(12, HIGH);
  }
  //flash 2 green lights
  else if(leveltoken == 2){
    digitalWrite(12, HIGH);
    digitalWrite(14, HIGH);
  }
  //flash 3 green lights
  else if(leveltoken == 3){
    digitalWrite(12, HIGH);
    digitalWrite(14, HIGH);
    digitalWrite(27, HIGH);
  }
  //flash 4 green lights
  else if(leveltoken == 4){
    digitalWrite(12, HIGH);
    digitalWrite(14, HIGH);
    digitalWrite(27, HIGH);
    digitalWrite(26, HIGH);
  }
  else if(leveltoken == 0){
    Serial.println("Red led turned on");
  }
  //error flash
  else{
    digitalWrite(13, HIGH);
    digitalWrite(12, LOW);
    digitalWrite(14, HIGH);
    digitalWrite(27, LOW);
    digitalWrite(26, HIGH);
  }
  delay(2000);
  //turn all leds off
  digitalWrite(13, LOW);
  digitalWrite(12, LOW);
  digitalWrite(14, LOW);
  digitalWrite(27, LOW);
  digitalWrite(26, LOW);
  ESP.restart();
}
