// Define pins for each segment (A-G)
const int segmentPins[] = {2, 3, 4, 5, 6, 7, 8};  // A, B, C, D, E, F, G

// Define pins for each digit (common-cathodes)
const int digitPins[] = {9, 10, 11, 12}; // Pins to control each digit

// Define pins for the start, increase, and decrease buttons
const int buttonPinStart = 13;
const int buttonPinIncrease = A0;  // Pin for increase button
const int buttonPinDecrease = A1;  // Pin for decrease button

// Define pin for the LED (using analog pin A2 as a digital output)
const int ledPin = A2;  // LED connected to analog pin A2 (can be used as digital pin 14)

// Digit patterns for 0-9 (common-cathode)
const byte digitPatterns[] = {
  0b00111111, // 0
  0b00000110, // 1
  0b01011011, // 2
  0b01001111, // 3
  0b01100110, // 4
  0b01101101, // 5
  0b01111101, // 6
  0b00000111, // 7
  0b01111111, // 8
  0b01101111  // 9
};

// Initialize countdown time to 0 seconds
int countdownTime = 0;
unsigned long previousMillis = 0;
const long interval = 1000;  // 1-second interval

// For smooth button handling
unsigned long lastButtonPress = 0; // Time of the last button press
const long debounceDelay = 50; // Minimum time between button presses (debounce delay)

// Countdown state variable
bool startCountdown = false;
bool pulseSent = false;  // Track if the pulse was already sent
bool increasePressed = false;  // Track if the increase button is pressed

void setup() {
  // Initialize segment pins as outputs
  for (int i = 0; i < 7; i++) {
    pinMode(segmentPins[i], OUTPUT);
  }
  // Initialize digit pins as outputs
  for (int i = 0; i < 4; i++) {
    pinMode(digitPins[i], OUTPUT);
    digitalWrite(digitPins[i], HIGH);  // Turn off all digits initially
  }

  // Initialize button pins as inputs with pull-down resistors
  pinMode(buttonPinStart, INPUT);
  pinMode(buttonPinIncrease, INPUT);
  pinMode(buttonPinDecrease, INPUT);
  
  // Initialize the LED pin as output (using analog pin A2 as digital pin 14)
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, LOW);  // Initially turn off the LED
}

void loop() {
  unsigned long currentMillis = millis();

  // Check if the start button is pressed to start the countdown
  if (digitalRead(buttonPinStart) == HIGH && !startCountdown) {
    if (currentMillis - lastButtonPress > debounceDelay) {
      lastButtonPress = currentMillis;
      startCountdown = true;  // Start countdown when button is pressed
    }
  }

  // Handle smooth increase of countdown time
  if (digitalRead(buttonPinIncrease) == HIGH) {
    if (currentMillis - lastButtonPress > debounceDelay) {
      lastButtonPress = currentMillis;
      increasePressed = true;  // Mark that the increase button is pressed
      countdownTime++;  // Increase countdown by 1 second
      digitalWrite(ledPin, LOW);  // Turn off the LED while increasing
    }
  }

  // Handle smooth decrease of countdown time
  if (digitalRead(buttonPinDecrease) == HIGH) {
    if (currentMillis - lastButtonPress > debounceDelay) {
      lastButtonPress = currentMillis;
      countdownTime--;  // Decrease countdown by 1 second
      if (countdownTime < 0) {
        countdownTime = 0;  // Prevent countdown from going below 0
      }
    }
  }

  // Update countdown only if it has been started
  if (startCountdown && countdownTime > 0) {
    if (currentMillis - previousMillis >= interval) {
      previousMillis = currentMillis;
      countdownTime--;  // Decrease countdown by 1 second
    }
  }

  // Check if countdown reached 0
  if (countdownTime == 0 && startCountdown && !pulseSent) {
    startCountdown = false;  // Stop the countdown
    sendPulse();  // Send pulse when countdown hits 0
    digitalWrite(ledPin, HIGH);  // Turn on LED to signal countdown reached 0
    pulseSent = true;  // Ensure pulse is only sent once
  }

  // If the increase button was released, reset pulseSent flag
  if (increasePressed && digitalRead(buttonPinIncrease) == LOW) {
    increasePressed = false;  // Reset the flag
    pulseSent = false;  // Reset pulseSent so the pulse can be triggered again next time countdown reaches 0
  }

  // Display the current countdown time
  displayTime(countdownTime);

  // Small delay to reduce flickering
  delay(5);
}

void displayTime(int time) {
  // Just use the full time as seconds, no need for minutes/seconds division anymore
  int digit0 = (time / 1000) % 10;  // Thousands place
  int digit1 = (time / 100) % 10;   // Hundreds place
  int digit2 = (time / 10) % 10;    // Tens place
  int digit3 = time % 10;           // Ones place

  // Display each digit
  displayDigit(digit0, 0);
  displayDigit(digit1, 1);
  displayDigit(digit2, 2);
  displayDigit(digit3, 3);
}

// Function to display a single digit at a specific position
void displayDigit(int number, int position) {
  // Turn off all digits
  for (int i = 0; i < 4; i++) {
    digitalWrite(digitPins[i], HIGH);
  }

  // Set segment pattern for the current number
  byte pattern = digitPatterns[number];
  for (int i = 0; i < 7; i++) {
    digitalWrite(segmentPins[i], (pattern >> i) & 0x01);
  }

  // Turn on the current digit
  digitalWrite(digitPins[position], LOW);
  
  // Short delay to allow display persistence
  delay(2);

  // Turn off the digit to prepare for the next
  digitalWrite(digitPins[position], HIGH);
}

// Function to send a pulse on the LED pin when countdown reaches 0
void sendPulse() {
  digitalWrite(ledPin, HIGH);  // Send a pulse by turning the LED ON
  delay(100);                  // Keep it on for 100ms (pulse duration)
  digitalWrite(ledPin, LOW);   // Turn the LED off again
}