#include "iClickerEmulator.h"
#include <string.h>

iClickerEmulator clicker(8, 3, digitalPinToInterrupt(3), true);
bool newCommand;
String command;

void setup(){
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  newCommand = true;
  Serial.begin(115200);
  clicker.begin(iClickerChannels::AA);
  clicker.startPromiscuous(CHANNEL_SEND, recvPacketHandler);
}

void loop(){
  if (Serial.available()) {
    char c = Serial.read();
    if(newCommand && c != '\n') command = c, newCommand = false; 
    else if(!newCommand && c != '\n') command += c;
    else {
      newCommand = true;
      processCommand(command);
    }
  }
}

void recvPacketHandler(iClickerPacket *recvd){
  if(recvd->type == PACKET_ANSWER){
    char tmp[50];
    uint8_t *id = recvd->packet.answerPacket.id;
    char answer = iClickerEmulator::answerChar(recvd->packet.answerPacket.answer);
    snprintf(tmp, sizeof(tmp), "$%c%02X%02X%02X%02X", answer, id[0], id[1], id[2], id[3]);
    Serial.println(tmp);
  }
}

void processCommand(String command){
  if(command[0] == '#'){ // SetChannel (#[CHANNEL])
    clicker.setChannel(iClickerChannels::channels[(command[1] - 'A') * 4 + (command[2] - 'A')]);
  }else if(command[0] == '$'){ // SendAnswer ($[ANSWER][ID])
    uint8_t id[4];
    id[0] = hex2int(command[2]) * 16 + hex2int(command[3]);
    id[1] = hex2int(command[4]) * 16 + hex2int(command[5]);
    id[2] = hex2int(command[6]) * 16 + hex2int(command[7]);
    id[3] = hex2int(command[8]) * 16 + hex2int(command[9]);
    if(iClickerEmulator::validId(id)){
      if(clicker.submitAnswer(id, iClickerEmulator::charAnswer(command[1]), true, DEFAULT_ACK_TIMEOUT, true)) // return status (%[STATUS])
        Serial.println("%1");
      else
        Serial.println("%0");
    }
  }
}

int hex2int(char ch){
    if (ch >= '0' && ch <= '9') return ch - '0';
    if (ch >= 'A' && ch <= 'F') return ch - 'A' + 10;
    if (ch >= 'a' && ch <= 'f') return ch - 'a' + 10;
    return 0;
}