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

#define HETXPIN PIND7


/************ ETHERNET STUFF ************/
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 10, 10, 10, 111 };
Server server(80);

// variables used for receiving the messages
unsigned int pulseWidth = 0;
unsigned int latchStage = 0;
signed int bitCount = 0;
byte bit = 0;
byte prevBit = 0;

// variables for storing the data received
unsigned long sender = 0;
unsigned int recipient = 0;
byte command = 0;
bool group = false;

// variables for sending messages
byte messageType;
unsigned int messageCount;

void setup() {
  
  // ensure the receiver pin is set for input
        DDRD &= ~_BV(PIND6);
        
        // disable PWM (default)
        TCCR1A = 0x00;
        
        // set prescaler to 1/8.  TCNT1 increments every 0.5 micro seconds
        // falling edge used as trigger
        TCCR1B = 0x02;
        
        // enable input capture interrupt for timer 1
        TIMSK1 = _BV(ICIE1);
  */
  Ethernet.begin(mac, ip);
  server.begin();
}



ISR(TIMER1_CAPT_vect)
{
        // reset counter
        TCNT1 = 0;
        
        // get value of input compare register, divide by two to get microseconds
        pulseWidth = (ICR1 / 2);
        
        if(bit_is_clear(TCCR1B, ICES1))
        {       // falling edge was detected, HIGH pulse end
                
                if(latchStage == 1 && pulseWidth > 230 && pulseWidth < 280)
                {       // advanced protocol latch
                        
                        latchStage = 2;
                }
                else if(latchStage == 3 && (pulseWidth < 150 || pulseWidth > 500))
                {       // advanced protocol data out of timing range
                        
                        latchStage = 0;
                        bitCount = 0;
                        
                        sender = 0;
                        recipient = 0;
                }
                else if(latchStage == 1)
                {       // simple protocol data
                        
                        bitCount++;
                        
                        if(pulseWidth > 320 && pulseWidth < 430)
                        {
                                bit = 0;
                        }
                        else if(pulseWidth > 1030 && pulseWidth < 1150 && bitCount % 2 == 0)
                        {
                                bit = 0x08;
                        }
                        else
                        {       // start over if the low pulse was out of range
                                
                                latchStage = 0;
                                bitCount = 0;
                                
                                sender = 0;
                                recipient = 0;
                        }
                        
                        if(bitCount % 2 == 0)
                        {
                                if(bitCount < 9)
                                {
                                        sender >>= 1;
                                        sender |= bit;
                                }
                                else if(bitCount < 17)
                                {
                                        recipient >>= 1;
                                        recipient |= bit;
                                }
                                else
                                {
                                        command >>= 1;
                                        command |= bit;
                                }
                        }
                        
                        if(bitCount == 25)
                        {       // message is complete
                                
                                // TODO send to server...                                 
                                
                                latchStage = 0;
                                bitCount = 0;
                                
                                sender = 0;
                                recipient = 0;
                        }
                }
        }
        else
        {       // raising edge was detected, LOW pulse end
                
                if(latchStage == 0 && pulseWidth > 9480 && pulseWidth < 11500)
                {       // pause between messages
                
                        latchStage = 1;
                }
                else if(latchStage == 2 && pulseWidth > 2550 && pulseWidth < 2750)
                {       // advanced protocol latch
                        
                        latchStage = 3;
                }
                else if(latchStage == 3)
                {       // advanced protocol data

                 }
        }
        
        // toggle bit value to trigger on the other edge
        TCCR1B ^= _BV(ICES1);
}

*/
void send(unsigned int s, unsigned int r, byte c){
        // disable all interrupts
        TIMSK1 = 0;
        
        // reset variables
        messageCount = 0;
        latchStage = 0;
        bitCount = 0;
        bit = 0;
        prevBit = 0;
        pulseWidth = 10000;
        
        // set data to transmit
        sender = s;
        recipient = r;
        command = c;
        
               // ensure the transmitter pin is set for output
        DDRD |= _BV(HETXPIN);
        
        // the value that the timer will count up to before firing the interrupt
        OCR1A = (pulseWidth * 2);

        // toggle OC1A on compare match
        TCCR1A = _BV(COM1A0);

        // CTC mode: top of OCR1A, immediate update of OCR1A, TOV1 flag set on MAX
        TCCR1B |= _BV(WGM12);

        // enable timer interrupt for timer 1, disable input capture interrupt
        TIMSK1 = _BV(OCIE1A);
        
}

ISR(TIMER1_COMPA_vect)
{
                if(!prevBit && bitCount != 25)
                {
                        PORTD |= _BV(HETXPIN);
                }
                else
                {
                        PORTD &= ~_BV(HETXPIN);
                }
                
                if(bitCount % 2 == 0)
                {       // every other bit is a zero
                        bit = 0;
                }
                else if(bitCount < 8)
                {       // sender
                        bit = ((sender & _BV((bitCount - 1) / 2)) != 0);
                }
                else if(bitCount < 16)
                {       // recipient
                        bit = ((recipient & _BV((bitCount - 9) / 2)) != 0);
                }
                else if(bitCount < 24)
                {       // command
                        bit = ((command & _BV((bitCount - 17) / 2)) != 0);
                }
                
                if(bitCount == 25)
                {       // message finished
                        
                        bitCount = 0;
                        messageCount++;
                        
                        pulseWidth = 10000;
                        
                        if(messageCount == 5)
                        {       // go back to receiving
                                
                                messageCount = 0;
                                
                                TCCR1A = 0x00;
                                TCCR1B = 0x02;
                                //TIMSK1 = _BV(ICIE1);
                                
                                return;
                        }
                }
                else
                {
                        if(prevBit && bit || !prevBit && !bit)
                        {
                                pulseWidth = 375;
                        }
                        else
                        {
                                pulseWidth = 1125;
                        }
                        
                        if(prevBit)
                        {
                                bitCount++;
                        }
                        
                        prevBit = !prevBit;
                }
 
        // set the next delay
        OCR1A = (pulseWidth * 2);
}



void loop()
{
  char clientline[100];
  int index = 0;
  
  Client client = server.available();
  if (client) {
    // an http request ends with a blank line
    boolean current_line_is_blank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        // if we've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so we can send a reply
        // If it isn't a new line, add the character to the buffer
        if (c != '\n' && c != '\r') {
          clientline[index] = c;
          index++;
          // are we too big for the buffer? start tossing out data
          if (index >= 100) 
            index = 100 -1;
          
          // continue to read more data!
          continue;
        }
        clientline[index] = 0;

        
         if (strstr(clientline, "GET / ") != 0) {
  // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
           client.println("<bg> <h1> ");
           client.println("RFhandler Ready. </h1><br>");
         
           
        }else{
          char *outp;
          if (strstr(clientline, "GET /") != 0){
            outp = clientline + 5;
             (strstr(clientline, " HTTP"))[0] = 0;

          }else{
             outp = clientline;
          }
          if(outp[2] == '-' ){
              int dev=0;
              int rec=0;
              int cmd=0;
              client.println("HTTP/1.1 200 OK");
              client.println("Content-Type: text/html");
              client.println();
              client.println("sending: <br>dev ");
              dev = (outp[0]-48)*10;
              dev = dev+(outp[1]-48);
              client.println(dev);
              client.println("<br>rec ");
              rec = (outp[3]-48)*10;
              rec = rec+(outp[4]-48);
              client.println(rec);
              client.println("<br>cmd ");
              cmd = (outp[6]-48)*10;
              cmd = cmd+(outp[7]-48);
              client.println(cmd);
              send(dev,rec,cmd);
          }else{
            client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println();
           client.println("invalid request");
           client.println(outp);
          }
        }
        break;
      }
    }
    delay(1);
    client.stop();
}