#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

const byte passLength = 7;
char correctPass[passLength] = { '1', '1', '1', '1', '1', '1', '1' };
char userPass[passLength] = { '*', '*', '*', '*', '*', '*', '*' };
int enterIndex = 0;
int beepIndex = 0;

void (*resetFunc)(void) = 0;  // create a standard reset function

const byte radky = 4;
const byte sloupce = 4;
const int ledPinRed = 12;
const int ledPinZel = 13;
const int buzzerPin = 10;
// vytvoření pole s rozmístěním kláves
char keys[radky][sloupce] = {
  { '1', '2', '3', 'A' },
  { '4', '5', '6', 'B' },
  { '7', '8', '9', 'C' },
  { 'D', 'E', 'F', '#' }
};
// nastavení čísel pinů pro spojení s klávesnicí
byte pinyRadku[radky] = { 5, 4, 3, 2 };
byte pinySloupcu[sloupce] = { 6, 7, 8, 9 };

// vytvoření instance klavesnice z knihovny Keypad
Keypad klavesnice = Keypad(makeKeymap(keys), pinyRadku, pinySloupcu, radky, sloupce);


void printTempPass() {
  for (int i = 0; i < enterIndex; i++) {
    lcd.setCursor(i, 0);
    lcd.print("*");
  }
}

void resetProgram() {
  // lcd.clear();
  // enterIndex = 0;
  resetFunc();
}

void timer() {
}

void bomb() {
  // bomb stuff
  //lcd.noBacklight();
  Serial.println("BOMB EXPLODING IN...");

  // test buzzer
  // tone(buzzerPin, 4000);
  // delay(500);
  // noTone(buzzerPin);
  // delay(500);
  // tone(buzzerPin, 4000);
  // delay(500);
  // noTone(buzzerPin);
  unsigned long startTime = millis();
  int sec = 39;
  int oneSecond = 1000;
  int freq = 0;
  int max = 266;

  while (true) {
    Serial.println("startTime: " + String(startTime) + "         millis: " + millis());
    if (millis() - startTime >= oneSecond) {
      startTime = millis();
      lcd.setCursor(5, 1);
      sec--;

      int displayMin = sec / 60;
      if (displayMin < 10) {
        lcd.print("0");
      }
      lcd.print(displayMin);
      lcd.print(":");
      int displaySec = sec % 60;
      if (displaySec < 10) {
        lcd.print("0");
      }
      lcd.print(sec % 60);

      // Podmínky pro pípání podle zbývajícího času
      if (sec >= 30) { // 1x za vteřinu do 30 vterin
        tone(buzzerPin, 3000, 100);
        digitalWrite(ledPinRed, HIGH);
        delay(100);           
        noTone(buzzerPin);     
        digitalWrite(ledPinRed, LOW);
        delay(900);  
      } else if (sec >= 20 && sec <= 29) { // 2x za vteřinu
        tone(buzzerPin, 3000, 100);
        digitalWrite(ledPinRed, HIGH);
        delay(100);           
        noTone(buzzerPin);     
        digitalWrite(ledPinRed, LOW);
        delay(400);  
        tone(buzzerPin, 3000); 
        digitalWrite(ledPinRed, HIGH);
        delay(100);           
        noTone(buzzerPin);   
        digitalWrite(ledPinRed, LOW);  
        delay(400);
      } else if (sec >= 10 && sec <= 19) { // 3x za vteřinu
        tone(buzzerPin, 3000);
        digitalWrite(ledPinRed, HIGH);
        delay(100);           
        noTone(buzzerPin);   
        digitalWrite(ledPinRed, LOW);   
        delay(233);  
        tone(buzzerPin, 3000); 
        digitalWrite(ledPinRed, HIGH);
        delay(100);           
        noTone(buzzerPin);   
        digitalWrite(ledPinRed, LOW);       
        delay(233);  
        tone(buzzerPin, 3000); 
        digitalWrite(ledPinRed, HIGH);
        delay(100);           
        noTone(buzzerPin);   
        digitalWrite(ledPinRed, LOW);   
        delay(234);  
      } else if (sec >= 5 && sec <= 9) { // 4x za vteřinu
        tone(buzzerPin, 3000);
        digitalWrite(ledPinRed, HIGH);
        delay(100);           
        noTone(buzzerPin);   
        digitalWrite(ledPinRed, LOW);     
        delay(150);  
        tone(buzzerPin, 3000); 
        digitalWrite(ledPinRed, HIGH);
        delay(100);           
        noTone(buzzerPin);   
        digitalWrite(ledPinRed, LOW);     
        delay(150);  
        tone(buzzerPin, 3000); 
        digitalWrite(ledPinRed, HIGH);
        delay(100);           
        noTone(buzzerPin);   
        digitalWrite(ledPinRed, LOW);    
        delay(150);  
        tone(buzzerPin, 3000);
        digitalWrite(ledPinRed, HIGH);
        delay(100);           
        noTone(buzzerPin);   
        digitalWrite(ledPinRed, LOW);     
        delay(150);  
      } else if (sec >= 1 && sec <= 4) { // 5x za vteřinu
        tone(buzzerPin, 3000);
        digitalWrite(ledPinRed, HIGH);
        delay(100);           
        noTone(buzzerPin);   
        digitalWrite(ledPinRed, LOW);     
        delay(100);  
        tone(buzzerPin, 3000); 
        digitalWrite(ledPinRed, HIGH);
        delay(100);           
        noTone(buzzerPin);   
        digitalWrite(ledPinRed, LOW);     
        delay(100);  
        tone(buzzerPin, 3000); 
        digitalWrite(ledPinRed, HIGH);
        delay(100);           
        noTone(buzzerPin);   
        digitalWrite(ledPinRed, LOW);    
        delay(100);  
        tone(buzzerPin, 3000);
        digitalWrite(ledPinRed, HIGH);
        delay(100);           
        noTone(buzzerPin);   
        digitalWrite(ledPinRed, LOW);     
        delay(100);  
        tone(buzzerPin, 3000);
        digitalWrite(ledPinRed, HIGH);
        delay(100);           
        noTone(buzzerPin);   
        digitalWrite(ledPinRed, LOW);     
        delay(100);
      }

      // bomb is exploding
      if (sec == 0) {
        digitalWrite(ledPinRed, HIGH);
        for (int freq = 0; freq <= 4000; freq = freq + 20) {
          tone(buzzerPin, freq);
          delay(3);
          noTone(buzzerPin);
          delay(2);
        }
        tone(buzzerPin, 600);
        delay(100);           
        noTone(buzzerPin);       
        delay(100);  
        tone(buzzerPin, 600);
        delay(100);           
        noTone(buzzerPin);       
        delay(100);
        tone(buzzerPin, 600); 
        delay(100);           
        noTone(buzzerPin);       
        delay(100);  
        tone(buzzerPin, 600); 
        delay(100);           
        noTone(buzzerPin);      
        delay(100);  
        tone(buzzerPin, 600);
        delay(100);    
        noTone(buzzerPin);      
        delay(100); 
        digitalWrite(ledPinRed, LOW);
      }

      // if the bomb exploded
      if (sec < 0) {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.println("Terrorists Win.");

        tone(buzzerPin, 1500);
        delay(500);    
        noTone(buzzerPin);      
        delay(500); 
        tone(buzzerPin, 1500);
        delay(500);    
        noTone(buzzerPin);      
        delay(500); 
        tone(buzzerPin, 1500);
        delay(500);    
        noTone(buzzerPin);      
        delay(500); 
        tone(buzzerPin, 1500);
        delay(500);    
        noTone(buzzerPin);      
        delay(500); 
        tone(buzzerPin, 1500);
        delay(500);    
        noTone(buzzerPin);      
        delay(500); 
        break;
      }
    }
  }
  resetProgram();
}
      
void setup() {
  Serial.begin(9600);
  pinMode(ledPinRed, OUTPUT);
  pinMode(ledPinZel, OUTPUT);
  lcd.begin(16, 2);

  lcd.init();
  lcd.backlight();
}

void loop() {

  digitalWrite(ledPinRed, HIGH); 
  digitalWrite(ledPinZel, HIGH); 

  if (beepIndex == 0) { 
    tone(buzzerPin, 2000);
    delay(100);           
    noTone(buzzerPin);       
    delay(100);
    tone(buzzerPin, 2500);
    delay(75);           
    noTone(buzzerPin);       
    delay(75);
    tone(buzzerPin, 2500);
    delay(75);           
    noTone(buzzerPin);       
    delay(75);
    beepIndex = 1;
  }
  
  // načtení hodnoty stisknuté klávesy do proměnné
  char klavesa = klavesnice.getKey();

  if (klavesa) {
    Serial.print("Stisknuta klavesa: ");
    Serial.println(klavesa);
    digitalWrite(ledPinRed, HIGH);

    userPass[enterIndex] = klavesa;
    enterIndex++;

    printTempPass();

    delay(250);

    if (enterIndex >= passLength) {
      // the whole password was entered
      bool wrongPass = false;
      for (int i = 0; i < passLength; i++) {
        if (correctPass[i] != userPass[i]) {
          // invalid password was entered, start over
          Serial.println("invalid password");
          lcd.setCursor(0, 0);
          lcd.println("INVALID PASSWORD");
          delay(2000);

          resetProgram();
          wrongPass = true;
          break;
        }
      }
      if (wrongPass == false) {
        // the password is correct
        delay(100);
        digitalWrite(ledPinRed, LOW); 
        digitalWrite(ledPinZel, LOW); 
        lcd.clear();
        bomb();
      }
    }

  } else {
    digitalWrite(ledPinRed, LOW);
  }
}
$abcdeabcde151015202530354045505560fghijfghij