#include <SPI.h>
#include <Ethernet.h>
#include <RCSwitch.h>

byte mac[] = {0xDE, 0xAD, 0xBE, 0xAA, 0xDE, 0x01};
IPAddress ip(192,168,2,114);
const int serverPort = 2313;
const int senderPin = 6;
const int requestBufferLength = 16;
const int attemptsCount = 3;

EthernetServer server(serverPort);
RCSwitch sender = RCSwitch();
char requestBuffer[requestBufferLength];

void setup() 
{
  Serial.begin(9600);
  
  sender.enableTransmit(senderPin);
  Serial.println("transmission enabled");
  
  Ethernet.begin(mac, ip);
  server.begin();
  
  Serial.print("started ardvindo server at ");
  Serial.print(Ethernet.localIP());
  Serial.print(":");
  Serial.println(serverPort);
}

void errorResponse(EthernetClient& client, const char* cmd, const char* msg) 
{
  Serial.print("error: ");
  Serial.println(msg);
  
  client.print("cmd: ");
  client.println(cmd);
  client.print("error: ");
  client.println(msg);
}

void processCmd(EthernetClient& client, const char* cmd) 
{
  if(cmd[0] == 'e' || cmd[0] == 'd') {
    char family = requestBuffer[2];
    int group = requestBuffer[4] - '0';
    int device = requestBuffer[6] - '0';
    
    if(family < 'a' || family > 'f') {
      errorResponse(client, cmd, "error: family < 'a' || family > 'f'");
    } else if(group < 0) {
      errorResponse(client, cmd, "group < 0");
    } else if(device < 0) {
      errorResponse(client, cmd, "device < 0");
    } else {     
      bool on = (requestBuffer[0] == 'e');
         
      for(int i = 0; i < attemptsCount; i++) {
        if(on) {
          sender.switchOn(family, group, device);
        } else {
          sender.switchOff(family, group, device);
        }
        delay(1);
      }
      
      client.print(family);
      client.print(" ");
      client.print(group);
      client.print(" ");
      client.print(device);
      client.print(" ");
      if(on) {
        client.println("switched on");
        Serial.println("switched on");
      } else {
        client.println("switched off");
        Serial.println("switched off");
      }
      
      //sender.switchOn('b', 3, 2);
      //delay(1500);
      //sender.switchOff('b', 3, 2);
    }
  } else {
    errorResponse(client, cmd, "unknown command");
  }
}

void loop() 
{
  EthernetClient client = server.available();
  if (client) {
    Serial.println("client connected");
    
    client.println("ardvindo");
    
    while(client.connected()) {
      if(client.available()) {
        for(int i=0; i<requestBufferLength && client.available(); i++) {
          char c = client.read();
          if(c == '\n') {
            break;
          }
          requestBuffer[i] = c;
          requestBuffer[i+1] = '\0';
        }
        Serial.print("> ");
        Serial.println(requestBuffer);
        processCmd(client, requestBuffer);
      }
    }
    
    delay(1);
    client.stop();
    
    Serial.println("client disonnected");
  }
}