#include <IRremote.h>

const int led = LED_BUILTIN; // On board LED, Pin 13
const int RECV_PIN = 7; // IR Receiver
//String input = "";
long code = 0;
int count = 0;
bool repeat = false;
int parse_item = 0;
const int CODE_DELAY = 30;

void reset_code() {
  code = 0;
  count = 0;
  repeat = false;
  parse_item = 0;
}

const char hexadecimal[] = "0123456789ABCDEF";

int hextoi(char hexch) {
  char *pos = strchr(hexadecimal, toupper(hexch));
  if (pos == NULL) {
    printf("WARN: Invalid hex digit [%c/%d]\n", hexch, hexch);
    return 0;
  }
  return (pos - hexadecimal);
}

IRsend sendr; // Make Send Object, DANGER a fixed pin number is always used! (3)
//IRrecv recvr(RECV_PIN); // Make Recever Object
//decode_results results; // Make Results Object to store received codes
//String result_code[] = {"", "", ""};

void setup() {
  // Initalize on board LED
  pinMode(led, OUTPUT);
  digitalWrite(led, LOW);
  
  // Initalize input routine
  //input.reserve(60); // Max input of chars, to merge into string
  reset_code();

  // Initalize IR connections
  //recvr.enableIRIn();
  //recvr.blink13(false); // Disabled Pin 13 blinking on IR signal received
  
  // Initalize Output routine
  Serial.begin(9600); // Serial COM's Port
  while(!Serial) { delay(10); } // Wait for conection
  Serial.println("Ready!");
  digitalWrite(led, LOW);
}

void sendCode(long code, int bit_len, bool repeat) {
  // If repeat the code then repeat it 3 times
  if(repeat) {
    for(int x = 0; x <= 3; x++) {
      sendr.sendNEC(code, bit_len);
      delay(CODE_DELAY);
    }
  } else {
    // Else send the code then repeat a blank 2 times
    sendr.sendNEC(code, bit_len);
    delay(CODE_DELAY);
    for(int x = 0; x <= 2; x++) {
      sendr.sendNEC(0xFFFFFFFF, 32);
      delay(CODE_DELAY);
    }
  }
}

void loop() {
  //reset_code();
  // Are we sending/receiving data?
  while(Serial.available()) {
    char in = (char)Serial.read();
#ifdef DEBUG_OUT
      Serial.print(": ");
      Serial.println(in);
#endif
    if (in == ',') {
      parse_item++;
      if (parse_item > 2) {
        Serial.println("Error: Too many items!");
        while (Serial.read() != '\n') {
          
        }
        reset_code();
        break;
      }
    }
    if (in == '\n') {
      if (parse_item == 2) {
        Serial.print("Received: ");
        Serial.print(code, HEX);
        Serial.print(", ");
        Serial.print(count);
        Serial.print(", ");
        Serial.println(repeat);
        Serial.println("Sending...");
        sendCode(code, count, repeat);
        Serial.println("Ok");
      } else {
        Serial.print("Error: Missing items, I saw ");
        Serial.println(parse_item + 1);
        break;
      }
      reset_code();
      continue;
    }
    switch (parse_item) {
      case 0:
#ifdef DEBUG_OUT
          Serial.print("Before: ");
          Serial.print(code, HEX);
          Serial.print(" ");
          Serial.print(in);
          Serial.println(hextoi(in));
#endif
        code = code << 4;
#ifdef DEBUG_OUT
          Serial.print("After: ");
          Serial.println(code, HEX);
#endif
        code += hextoi(in);
#ifdef DEBUG_OUT
          Serial.print("After: ");
          Serial.println(code, HEX);
#endif
        break;
      case 1:
        count *= 10;
        count += hextoi(in);
        break;
      case 2:
        repeat *= 10;
        repeat += hextoi(in);
        break;
    }
  }
}
