#include <TM1637Display.h>
#include <Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <IRremote.h>

// Define TM1637 display pins
const int CLK = 2;
const int DIO = 3;

// Define servo pins
#define SERVO1 5
#define SERVO2 6

// Define IR Receiver pin
int receiver_pin=9;

// Define the correct code
const int correctCode[4] = {1, 2, 3, 4}; // Change to your desired code
int enteredCode[4] = {0, 0, 0, 0};
int codeIndex = 0;

// Create TM1637 display object
TM1637Display display(CLK, DIO);

// Create Servo objects
Servo servo1;
Servo servo2;

// Initialize LCD
LiquidCrystal_I2C lcd(0x27, 16, 2); // Adjust address if needed



// Flag to track door state
bool doorOpened = false;

void setup() {
    display.setBrightness(7); // Set maximum brightness
    //Serial.begin(9600);

    // Attach servos
    servo1.attach(SERVO1);
    servo2.attach(SERVO2);
    
    // Initialize LCD
    lcd.begin(16, 2);
    lcd.backlight();
    lcd.setCursor(0, 0);
    lcd.print("Enter Code:");
    
    // Ensure servos start in the closed position
    closeDoors();
    
    // Start IR receiver
    IrReceiver.begin(receiver_pin,ENABLE_LED_FEEDBACK);
    //.begin(...) is a function that initializes the IR receiver module 
    //and prepares it to receive signals.

    //When enabled, it blinks the built-in LED (on pin 13 on most Arduino boards) 
    //whenever an IR signal is received.
}

void loop() {
    if (IrReceiver.decode()) {
      //IrReceiver.decode() checks if a new IR signal
      // has been received.
        int key = IrReceiver.decodedIRData.command;
        //extracts the decoded command from the received IR signal.
        //This is usually the button code sent by an IR remote control
        IrReceiver.resume(); // Receive next value

        //Serial.print("IR Key Pressed: ");
        //Serial.println(key, HEX);

        // Map IR remote values to number keys (adjust according to your remote's codes)
        int digit = -1;
        if (key == 48) digit = 1;
        if (key == 24) digit = 2;
        if (key == 122) digit = 3;
        if (key == 16) digit = 4;
        if (key == 56) digit = 5;
        if (key == 90) digit = 6;
        if (key == 66) digit = 7;
        if (key == 74) digit = 8;
        if (key == 82) digit = 9;
        if (key == 104) digit = 0;

        if (digit != -1 && codeIndex < 4) {
            enteredCode[codeIndex] = digit;
            codeIndex++;
        }

        // Display entered digits
        int displayNumber = enteredCode[0] * 1000 + enteredCode[1] * 100 + enteredCode[2] * 10 + enteredCode[3];
        display.showNumberDec(displayNumber);
        lcd.setCursor(0, 1);
        lcd.print(displayNumber);
        lcd.print("            "); // Clear extra digits if necessary

        // Check code when 4 digits are entered
        if (codeIndex == 4) {
            if (enteredCode[0] == correctCode[0] && enteredCode[1] == correctCode[1] &&
                enteredCode[2] == correctCode[2] && enteredCode[3] == correctCode[3]) {              
                lcd.setCursor(0, 0);
                lcd.print("Valid Code!     ");
                lcd.setCursor(0, 1);
                lcd.print("Opening...      ");
                openDoors();
                delay(1000); // Keep the door open for 5 seconds               
                lcd.setCursor(0, 0);
                lcd.print("Closing in 5s   ");
                lcd.setCursor(0, 1);
                lcd.print("Please wait...  ");
                delay(5000);
                closeDoors();
                lcd.setCursor(0, 0);
                lcd.print("Enter Code:     ");
                display.showNumberDec(0, true);
                lcd.setCursor(0, 1);
                lcd.print("                          "); // Reset the display to show 0000
            } else {               
                lcd.setCursor(0, 0);
                lcd.print("Wrong Code!     ");
                lcd.setCursor(0, 1);
                lcd.print("Try again       ");
                delay(1000);
                lcd.setCursor(0, 0);
                lcd.print("Enter Code:     ");
            }
            codeIndex = 0; // Reset code entry
        }
    }
}

void closeDoors(){
  servo1.write(180);
  servo2.write(0);
}

void openDoors(){
  servo1.write(90);
  servo2.write(90);
}
4-Digit Display