bool buttonCurrentState[3] = {HIGH, HIGH, HIGH};
bool buttonLastState[3] = {HIGH, HIGH, HIGH};
unsigned long buttonDownMillis[3] = {0, 0, 0};
unsigned long buttonHoldTime[3] = {0, 0, 0};
bool buttonFired[3] = {false, false, false};
bool buttonHoldFired[3] = {false, false, false};
unsigned long lastButtonPress[3] = {0, 0, 0};

int debounceTime = 120;

void buttonAction(byte relnr) {
  lastSwitchSource[relnr] = 0;
  relaisToggle(relnr);
}

void buttonHoldAction(byte btn) {
  switch (btn) {
    case 0:
      mqttclient.publish(mqtt_topic_out_hold_1, mqtt_payload_out_hold_1);
      break;
    case 1:
      mqttclient.publish(mqtt_topic_out_hold_2, mqtt_payload_out_hold_2);
      break;
    case 2:
      mqttclient.publish(mqtt_topic_out_hold_3, mqtt_payload_out_hold_3);
      break;
  }
}

void checkButtonStates() {
  for (int i = 0; i < BUTTONS_COUNT; i++) {
    checkButtonState(i);
  }
}

void checkButtonState(byte btn) {
  buttonHoldTime[btn] = millis() - buttonDownMillis[btn];
  buttonCurrentState[btn] = digitalRead(buttons_pins[btn]);
  if (buttonCurrentState[btn] == LOW && buttonLastState[btn] == HIGH) { // button was unpressed and is millis() pressed
    buttonDownMillis[btn] = millis();
    buttonLastState[btn] = buttonCurrentState[btn];
  }
  else if (buttonCurrentState[btn] == LOW && buttonLastState[btn] == LOW) { // button is held
    if ( buttonHoldTime[btn] > debounceTime ) {
      buttonLastState[btn] = buttonCurrentState[btn];
      if ( buttonHoldTime[btn] > 750 && !buttonHoldFired[btn] ) {
        // button is held longer
        if ( (millis() - lastButtonPress[btn]) > 700 ) { // mitigate double triggering
          lastButtonPress[btn] = millis();
          Serial.print("Button ");
          Serial.print(btn + 1);
          Serial.println(" long pressed");
          buttonHoldAction(btn);
          buttonHoldFired[btn] = true;
        }
      }
    }
  }
  else if (buttonCurrentState[btn] == HIGH && buttonLastState[btn] == LOW) { // button is released again
    if (buttonHoldTime[btn] > debounceTime) {          // entprellung
      buttonLastState[btn] = buttonCurrentState[btn];
      if (!buttonHoldFired[btn] && !buttonFired[btn]) {
        if ( (millis() - lastButtonPress[btn]) > 700 ) { // mitigate double triggering
          lastButtonPress[btn] = millis();
          Serial.print("Button ");
          Serial.print(btn + 1);
          Serial.println(" short pressed");
          buttonAction(btn);
        }
      }
      buttonFired[btn] = false;
      buttonHoldFired[btn] = false;
    }
  }
}

