#define BTN1 0xC
#define BTN2 0x18
#define BTN0 0x16
#define BTN4 0x08

boolean nec_ok = 0;

byte  index, nec_state = 0, command, inv_command;
unsigned long nec_code;

void setup() {
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;
  TIMSK1 = 1;
  attachInterrupt(0, remote_read, CHANGE);
  Serial.begin(9600);
}

void remote_read() {
  unsigned int timer_value;
  if (nec_state != 0) {
    timer_value = TCNT1;
    TCNT1 = 0;
  }
  switch (nec_state) {
    case 0 :
      TCNT1  = 0;
      TCCR1B = 2;
      nec_state = 1;
      index = 0;
      return;
    case 1 :
      if ((timer_value > 19000) || (timer_value < 17000)) {
        nec_state = 0;
        TCCR1B = 0;
      }
      else
        nec_state = 2;
      return;
    case 2 :
      if ((timer_value > 10000) || (timer_value < 8000)) {
        nec_state = 0;
        TCCR1B = 0;
      }
      else
        nec_state = 3;
      return;
    case 3 :
      if ((timer_value > 1400) || (timer_value < 800)) {
        TCCR1B = 0;
        nec_state = 0;
      }
      else
        nec_state = 4;
      return;
    case 4 :
      if ((timer_value > 3600) || (timer_value < 800)) {
        TCCR1B = 0;
        nec_state = 0;
        return;
      }
      if ( timer_value > 2000)
        bitSet(nec_code, (31 - index));
      else
        bitClear(nec_code, (31 - index));
      index++;
      if (index > 31) {
        nec_ok = 1;
        detachInterrupt(0);
        return;
      }
      nec_state = 3;
  }
}

ISR(TIMER1_OVF_vect) {
  nec_state = 0;
  TCCR1B = 0;
}

void loop() {
  static int count = 0;
  if (nec_ok) {
    nec_ok = 0;
    nec_state = 0;
    TCCR1B = 0;
    command = (nec_code >> 8) & 0xFF;
    inv_command = nec_code;
    if (command == BTN1 || command == BTN2 || command == BTN0 || command == BTN4) {
      // Serial.print("Pressed button: ");
      int btnNum;
      if (command == BTN1) {
        btnNum = 1;
      } else if (command == BTN2) {
        btnNum = 2;
      } else if (command == BTN0) {
        btnNum = 0;
      } else if (command == BTN4) {
        btnNum = 4;
      }
      Serial.print(btnNum);
      Serial.print(" Binary Code: ");
      Serial.println(inv_command, BIN);
      count++;
      // if (count == 2) {
      //   Serial.print("/");
      //   count = 0;
      // }

    } else {
      Serial.println("Button Pressed Ignored");
    }
    attachInterrupt(0, remote_read, CHANGE);
  }
}