#include <NewRemoteReceiver.h>
#include <NewRemoteTransmitter.h>
#include <IRremote.h>

// Serial Connection Variables
//
const byte serialBufferSize = 100;
char serialBuffer[serialBufferSize];
const char startMarker = '<';
const char endMarker = '>';
byte serialBytesReceived = 0;
boolean serialReadInProgress = false;
boolean newSerialData = false;
char serialData[serialBufferSize] = {0};

char commandLimiter[2] = ":";

// IR Comms
//
#define IR_SEND_PIN 9 // NOT CHANGEABLE
IRsend irTransmitter;
int irTransmitterFreq = 38; // 38KHz NEC Protocol

// RF Comms
//
#define RF_SEND_PIN 7
char rf_switch_on[10] = "true";
char rf_switch_off[10] = "false";
char rf_type_switch[10] = "switch";

// Main Program
//

void setup() {
  // Init Serial Connection
  Serial.begin(115200);

  // Init Serial Connection LED Controller
  Serial1.begin(115200);

  // Init RF Transmitters / Receivers

  // Init Climate Sensors
  initClimateSensors();

  // Init Movement Sensor
  initMovementSensor();

  Serial.println("<0:0:0>");
}

void loop() {
  // Handle Serial Comms
  handleSerial();

  // Handle Motion Sensor
  handleMotionSensor();
}

// Serial Handling
//
void handleSerial() {
  if(Serial.available() > 0) {
    char x = Serial.read();

    // the order of these IF clauses is significant
    if (x == endMarker) {
      serialReadInProgress = false;
      newSerialData = true;
      serialBuffer[serialBytesReceived] = 0;
      parseData();
    }
    
    if(serialReadInProgress) {
      serialBuffer[serialBytesReceived] = x;
      serialBytesReceived ++;
      if (serialBytesReceived == serialBufferSize) {
        serialBytesReceived = serialBufferSize - 1;
      }
    }

    if (x == startMarker) { 
      serialBytesReceived = 0; 
      serialReadInProgress = true;
    }
  }

  if(Serial1.available() > 0) {
    char x = Serial1.read();

    // the order of these IF clauses is significant
    if (x == endMarker) {
      serialReadInProgress = false;
      newSerialData = true;
      serialBuffer[serialBytesReceived] = 0;
      parseSerial1Data();
    }
    
    if(serialReadInProgress) {
      serialBuffer[serialBytesReceived] = x;
      serialBytesReceived ++;
      if (serialBytesReceived == serialBufferSize) {
        serialBytesReceived = serialBufferSize - 1;
      }
    }

    if (x == startMarker) { 
      serialBytesReceived = 0; 
      serialReadInProgress = true;
    }
  }
}

void parseData() {
  char * strtokIndex;
  char deviceUUID[10];
  char command[20];
  char data[69];

  // Get Device UUID
  strtokIndex = strtok(serialBuffer, ":");
  strcpy(deviceUUID, strtokIndex);

  // Get Command
  strtokIndex = strtok(NULL, ":");
  strcpy(command, strtokIndex);

  // Get Data
  strtokIndex = strtok(NULL, ":");
  strcpy(data, strtokIndex);

  handleCommand(deviceUUID, command, data);
}

void parseSerial1Data() {
  char * strtokIndex;
  char deviceUUID[10];
  char command[20];
  char data[69];

  // Get Device UUID
  strtokIndex = strtok(serialBuffer, ":");
  strcpy(deviceUUID, strtokIndex);

  strtokIndex = strtok(NULL, ":");
  strcpy(command, strtokIndex);

  strtokIndex = strtok(NULL, ":");
  strcpy(data, strtokIndex);

  sendSerialCommand(deviceUUID, command, data);
}

void sendSerialCommand(char* deviceUUID, char* command, char* data) {
  char serialCommandBuffer[serialBufferSize];
  char _startMarker[2] = "<";
  char _endMarker[2] = ">";
  sprintf(serialCommandBuffer, "%s%s:%s:%s%s", _startMarker, deviceUUID, command, data, _endMarker);
  Serial.println(serialCommandBuffer);
}


void sendSerial1Command(char* deviceUUID, char* command, char* data) {
  char serialCommandBuffer[serialBufferSize];
  char _startMarker[2] = "<";
  char _endMarker[2] = ">";
  sprintf(serialCommandBuffer, "%s%s:%s:%s%s", _startMarker, deviceUUID, command, data, _endMarker);
  Serial1.println(serialCommandBuffer);
}


void handleCommand(char* deviceUUID, char* command, char* data) {
  //
  // Climate Sensors
  //
  if (strcmp(deviceUUID, "aa50-48fd") == 0) {
    climateSensorCommand(deviceUUID, command, data);
  }

  //
  // Light Sensors
  //
  if (strcmp(deviceUUID, "be0c-4bc7") == 0) {
    lightSensorCommand(deviceUUID, command, data);
  }

  //
  // Handle Lights
  //
  if (strcmp(deviceUUID, "9472-4f60") == 0) {
    lightSwitchCommand(deviceUUID, command, data);
  }

  //
  // Handle Sun Blinds
  //

  if (strcmp(deviceUUID, "b039-471a") == 0) {
    sunBlindsCommand(deviceUUID, command, data);
  }

  //
  // Handle Air Conditioner
  //

  if (strcmp(deviceUUID, "70c4-40d2") == 0) {
    airConditionerCommand(deviceUUID, command, data);
  }

  //
  // Handle LED Strip
  //
  if (strcmp(deviceUUID, "34gr-54jf") == 0) {
    sendSerial1Command(deviceUUID, command, data);
  }

}

//
// RF Trancieving
//

void sendRFNCommand(int unitCode, char* commandType, char* commandValue) {
  NewRemoteTransmitter mainTransmitter(long(34659090), 7, 255);

  if(strcmp(commandType, "switch") == 0) {

    // True means on
    if(strcmp(commandValue, "true") == 0) {
      mainTransmitter.sendUnit(unitCode, true);
    }

    // False means off
    if(strcmp(commandValue, "false") == 0) {
      mainTransmitter.sendUnit(unitCode, false);
    }

  }

}
