// this corresponds to what segment of the display will turn on
int numbers[][7] = {
  {0, 0, 0, 0, 0, 0, 1}, // zero
  {1, 0, 0, 1, 1, 1, 1}, // one
  {0, 0, 1, 0, 0, 1, 0}, // two
  {0, 0, 0, 0, 1, 1, 0}, // three
  {1, 0, 0, 1, 1, 0, 0}, // four
  {0, 1, 0, 0, 1, 0, 0}, // five
  {0, 1, 0, 0, 0, 0, 0}, // six
  {0, 0, 0, 1, 1, 1, 1}, // seven
  {0, 0, 0, 0, 0, 0, 0}, // eight
  {0, 0, 0, 0, 1, 0, 0}  // nine
};

// constants 
const int buttonPin = 5;  // input pin of the button
int digitPins[] = {2, 3, 4}; // output pins for the digit pins of the 7 segment display
int segmentPins[] = {6, 7, 8, 9, 10, 11, 12, 13}; // output pins for the segment pins of the 7 segment display

// Variables will change:
int buttonState;            // the current reading from the input pin
int lastButtonState = LOW;  // the previous reading from the input pin
int count = 0; // the count to be displayed



unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers


// function for initializing the pins
void intializePins() {
  pinMode(buttonPin, INPUT);

  for (int i = 0; i < 7; i++) {
    pinMode(segmentPins[i], OUTPUT);
  }

  for (int i = 0; i < 4; i++) {
    pinMode(digitPins[i], OUTPUT);
  }
}

// function for turning off the display
void turnOffDisplay() {
  for (int i = 0; i < 7; i++) {
    digitalWrite(segmentPins[i], 1);  
  }
}

// function for displaying a number on a desired digit
void displayNumber(int number, int digitPin) {

  // select the digit you want the number to be written into, and turn the pin for that into 1
  digitalWrite(digitPins[digitPin], 1);

  // set the value of the segment pins into the corresponding values according to the numbers array
  for (int i = 0; i < 7; i++) {
    digitalWrite(segmentPins[i], numbers[number][i]);  
  }

  // turn of the display
  digitalWrite(digitPins[digitPin], 0);
  turnOffDisplay();

  
}


// function for displaying to all of the digits
void displayToThreeDigit(int num) {
  int hundreds = num / 100; // Extract hundreds digit
  int tens = (num / 10) % 10; // Extract tens digit
  int ones = num % 10; // Extract ones digit
  
  displayNumber(hundreds, 0);
  displayNumber(tens, 1);
  displayNumber(ones, 2);

  // the idea is to turn on and off the display very fast for each of the digit
  // more on that here: https://www.youtube.com/watch?v=fYAlE1u5rno
}


// function for incrementing the counter using the button
void getInput() {

  // read the signal coming from the button
  int reading = digitalRead(buttonPin);



  // the following code is just a debouncing code to avoid getting multiple input once you pressed the button
  /// the code is from here: https://docs.arduino.cc/built-in-examples/digital/Debounce

  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // increment the counter
      if (buttonState == HIGH) {
        count++;
      }
    }
  }

  lastButtonState = reading;
}

void setup() {
  // put your setup code here, to run once:
  intializePins();
  turnOffDisplay();
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  getInput();
  displayToThreeDigit(count);
}