#ifdef ENABLE_INPUT_BUTTONS

const unsigned int buttonMaxClickTime = 500;
const unsigned int buttonMaxClickTime_2 = 350;     // actual max time a button may be pressed to get detected as short press/click
const unsigned int buttonDebounceTime = 50;
const unsigned int buttonRepeatTime = 350;
const unsigned int buttonHoldTime = 1000;
const unsigned int buttonRepeatTime_menuButton = 1000;

// Use this function to configure the internal Bounce object to suit you. See the documentation at: https://github.com/thomasfredericks/Bounce2/wiki
// This function can be left out if the defaults are acceptable - just don't call configureButton
void configurePushButton(Bounce &bouncedButton)
{
  // Set the debounce interval to 15ms - default is 10ms
  bouncedButton.interval(15);
}

void setupInputsButtons()
{
  #if defined(FIRMWARE_VARIANT_THERMOSTAT) || defined(FIRMWARE_VARIANT_HEATCONTROL)
  buttonMode.configureButton(configurePushButton);
  buttonMode.onPress(onButtonPressed); // When the button is first pressed, call the function onButtonPressed (further down the page)
  //buttonMode.onHold(1000, onButtonHeldNoRepeat); // Once the button has been held for 1 second (1000ms) call onButtonHeld
  buttonMode.onHoldRepeat(buttonHoldTime, buttonRepeatTime_menuButton, onButtonHeld); // Once the button has been held for 1 second (1000ms) call onButtonHeld
  buttonMode.onRelease(buttonDebounceTime, buttonMaxClickTime, onButtonReleased);   // When the button is held >50ms and released after <500ms, call onButtonReleased
  #endif

  #ifdef FIRMWARE_VARIANT_THERMOSTAT
  buttonPlus.configureButton(configurePushButton);
  //buttonPlus.onPress(onButtonPressed); // When the button is first pressed, call the function onButtonPressed (further down the page)
  buttonPlus.onHoldRepeat(buttonHoldTime, buttonRepeatTime, onButtonHeld); // Once the button has been held for 1 second (1000ms) call onButtonHeld. Call it again every 350ms until it is let go
  buttonPlus.onRelease(buttonDebounceTime, buttonMaxClickTime, onButtonReleased);  // When the button is held >50ms and released after <500ms, call onButtonReleased

  buttonMinus.configureButton(configurePushButton);
  //buttonMinus.onPress(onButtonPressed); // When the button is first pressed, call the function onButtonPressed (further down the page)
  buttonMinus.onHoldRepeat(buttonHoldTime, buttonRepeatTime, onButtonHeld); // Once the button has been held for 1 second (1000ms) call onButtonHeld. Call it again every 350ms until it is let go
  buttonMinus.onRelease(buttonDebounceTime, buttonMaxClickTime, onButtonReleased);  // When the button is held >50ms and released after <500ms, call onButtonReleased
  #endif

  #ifdef ENABLE_SENSOR_PIR
  pirSensor.configureButton(configurePushButton);
  //pirSensor.onPress(onButtonPressed); // When the button is first pressed, call the function onButtonPressed (further down the page)
  pirSensor.onHold(150, onButtonHeldNoRepeat); // Once the button has been held for 1 second (1000ms) call onButtonHeld
  pirSensor.onRelease(150, onButtonReleased);  // When the button is held >50ms and released after <500ms, call onButtonReleased
  #endif
}

// btn is a reference to the button that fired the event. That means you can use the same event handler for many buttons
//void onButtonPressed(Button& btn) {
//
//}

// duration reports back how long it has been since the button was originally pressed.
// repeatCount tells us how many times this function has been called by this button.
void onButtonPressed(Button& btn) {
  if (buttonMode.isPressed()) {
    #ifdef FIRMWARE_VARIANT_HEATCONTROL
      display_enable();
    #endif
  }
}

void onButtonHeld(Button &btn, uint16_t duration, uint16_t repeatCount)
{
  if (buttonMode.isPressed())
  {
    if (repeatCount <= 2)
      modeButtonHoldAction();
    else if (repeatCount == 7)
      modeButtonRebootPendingAction();
    else if (repeatCount > 7)
      modeButtonRebootAction();
  }

  #ifdef FIRMWARE_VARIANT_THERMOSTAT
    if (buttonPlus.isPressed())
    {
      plusButtonAction();
    }

    if (buttonMinus.isPressed())
    {
      minusButtonAction();
    }
  #endif
}

void onButtonHeldNoRepeat(Button &btn, uint16_t duration)
{
  //if (buttonMode.isPressed()) {
  //  modeButtonHoldAction();
  //}
  #ifdef ENABLE_SENSOR_PIR
  if (pirSensor.isPressed())
  {
    pirSensorOnAction();
  }
  #endif
}

// duration reports back the total time that the button was held down
void onButtonReleased(Button &btn, uint16_t duration)
{
  if (btn.is(buttonMode) && duration < buttonMaxClickTime_2)
  {
    modeButtonAction();
  }

  #ifdef FIRMWARE_VARIANT_THERMOSTAT
  else if (btn.is(buttonPlus) && duration < buttonMaxClickTime_2)
  {
    plusButtonAction();
  }
  else if (btn.is(buttonMinus) && duration < buttonMaxClickTime_2)
  {
    minusButtonAction();
  }
  #endif
  
  #ifdef ENABLE_SENSOR_PIR
  else if (btn.is(pirSensor))
  {
    pirSensorOffAction();
  }
  #endif
}

#ifdef FIRMWARE_VARIANT_THERMOSTAT
void plusButtonAction()
{
  //Serial.println("Btn +");
  sendLog("DEV: Btn +", LOGLEVEL_INFO);
  if (!display_active)
  {
    display_enable();
  }
  else
  {
    display_extendTimeout();
    if (thermostat_heatingMode == 1 && thermostat_preset != 0)
      thermostat_setPresetTo(0);
    else
      thermostat_setTempStepUp();
  }
}

void minusButtonAction()
{
  //Serial.println("Btn -");
  sendLog("DEV: Btn -", LOGLEVEL_INFO);
  if (thermostat_heatingMode == 1 && thermostat_preset != 0)
    thermostat_setPresetTo(0);
  if (!display_active)
  {
    display_enable();
  }
  else
  {
    display_extendTimeout();
    #ifdef FIRMWARE_VARIANT_THERMOSTAT
    if (thermostat_heatingMode == 1 && thermostat_preset != 0)
      thermostat_setPresetTo(0);
    else
      thermostat_setTempStepDown();
    #endif
  }
}
#endif

void modeButtonAction()
{
  //Serial.println("Btn mode");
  sendLog("DEV: Btn MODE", LOGLEVEL_INFO);
  if (!display_active)
  {
    display_enable();
    //display_showRow2OverlayMessage(currentPresetName);
  }
  else
  {
    display_extendTimeout();
    if (system_pendingRestart)
    {
      system_doRestart = true;
      display_update();
    }

    #ifdef FIRMWARE_VARIANT_THERMOSTAT
    else {
      if (thermostat_heatingMode > 0)
      {
        if (thermostat_pendingPresetToggle) thermostat_togglePreset();
        else {
          thermostat_pendingPresetToggle = true;
          display_showRow2OverlayMessage(thermostat_currentPresetName);
        }
      }
    }
    #endif

    #ifdef FIRMWARE_VARIANT_HEATCONTROL
    else {
      display_toggleFullscreenMessage();
    }
    #endif
  }
}

void modeButtonHoldAction()
{
  //Serial.println("Btn mode held - toggle on/off");
  sendLog("DEV: Btn MODE HOLD", LOGLEVEL_INFO);
  display_extendTimeout();
  if (system_pendingRestart)
  {
    system_doRestart = true;
    display_update();
  }

  #ifdef FIRMWARE_VARIANT_THERMOSTAT
    else {
      thermostat_toggleOnOff();
    }
  #endif

  #ifdef FIRMWARE_VARIANT_HEATCONTROL
    else {
        heatcontrol_testMode_toggle();
    }
  #endif

}

void modeButtonRebootPendingAction()
{
  display_extendTimeout();
  system_pendingRestart = true;
  system_pendingRestart_lastMillis = millis();
  display_update();
}

void modeButtonRebootAction()
{
  display_extendTimeout();
  system_doRestart = true;
  display_update();
}


#ifdef ENABLE_SENSOR_PIR
void pirSensorOnAction()
{
  PIRSensorOn = true;
  //Serial.println("PIR sensor ON");
  //sendLog("SENS: PIR=ON", LOGLEVEL_INFO);
  publishCurrentPIRValue();
  if (confDisplay.PIRenablesDisplay)
  {
    #ifdef FIRMWARE_VARIANT_THERMOSTAT
      if (confTherm.PIRenablesDisplay_preset0only && thermostat_preset == 0)
        display_enable();
      else if (!confTherm.PIRenablesDisplay_preset0only)
        display_enable();
    #else
      display_enable();
    #endif
  }
}

void pirSensorOffAction()
{
  PIRSensorOn = false;
  //Serial.println("PIR sensor OFF");
  //sendLog("SENS: PIR=OFF", LOGLEVEL_INFO);
  publishCurrentPIRValue();
}
#endif // ENABLE_SENSOR_PIR

#endif // ENABLE_INPUT_BUTTONS
