#include "IRremote.hpp"

#define IR_RECEIVE_PIN 11


class ButtonPress{

private:

  static const long MAX_DELAY = 200;

  bool isValid = false;
  byte command = 0;
  uint32_t duration = 0;
  float durationSecondes = 0.0f;
  long startTime = 0;
  long lastUpdateTime = 0;
  bool hasSentInfos = false;

  void refreshLastUpdateTime(){
    lastUpdateTime = millis();
  }

  void setCommand(uint16_t c){
    command = (byte) c;
  }


public:

  ButtonPress(){
    // timeout imediatly
    startTime = -MAX_DELAY;
  }

  ButtonPress(IRData & irData){
    startTime = millis();
    setCommand(irData.command);
    refreshLastUpdateTime();
  }

  void addDuration(uint32_t d){
    duration += d;
    durationSecondes = (float)duration / 100000.0f;

    refreshLastUpdateTime();
  }

  bool isTimedout(){
    return millis() - lastUpdateTime > MAX_DELAY;
  }

  void sendInfos(){
    float duration = (millis() - startTime) / 1000.0f;

    if(command != 0 && !hasSentInfos){
      while(!Serial);

      byte hole;
      byte decimal;
      if(duration > 255){
        hole = 255;
        decimal = 255;
      }else{
        hole = (byte)duration;
        decimal = duration - hole * 100;
      }

      Serial.write(command);
      Serial.write(hole);
      Serial.write(decimal);

      hasSentInfos = true;
    }    
  }
};



IRData irData;
ButtonPress buttonPress;
bool isRepeated = false;


void setup() {
  Serial.begin(9600);
  IrReceiver.begin(IR_RECEIVE_PIN, ENABLE_LED_FEEDBACK);  
}


void loop() {
  if(IrReceiver.decode()) {
    irData = IrReceiver.decodedIRData;

    isRepeated = irData.flags & IRDATA_FLAGS_IS_REPEAT;
    
    if(buttonPress.isTimedout() || !isRepeated){
      // sent the data of the previous button press before overwiting it
      buttonPress.sendInfos();
      buttonPress = *new ButtonPress(irData);
    }

    buttonPress.addDuration(IrReceiver.getTotalDurationOfRawData());

    IrReceiver.resume();
  }

  if(buttonPress.isTimedout()){
    buttonPress.sendInfos();
  }
}