#include "TCPCallbackConnection.h"
#include "NetServer.h"
#include "mbed.h"

/* Some Lights */
DigitalOut led1(LED1);
DigitalOut led2(LED2);
int x = 0;

/* Two static html pages ready for serving, includeing http header */
const char *page[] = {
    "HTTP/1.1 200 OK\r\n"
    "Server:mbed embedded\r\n"
    "Content-Type: text/html\r\n"
    "Content-Length: 190\r\n"
    "\r\n"
    "<html>\r\n"
    "  <header>\r\n"
    "    <title>Whats up?<title>\r\n"
    "  </header>\r\n"
    "  <body>\r\n"
    "    <h1>Hello World!!11elf</h1>\r\n"
    "    <p>Have a greate day.</p>\r\n"
    "    <a href=\"/1.html\">turn  </a>\r\n"
    "  </body>\r\n"
    "</html>\r\n"
    "\r\n"
    ,
    "HTTP/1.1 200 OK\r\n"
    "Server:mbed embedded\r\n"
    "Content-Type: text/html\r\n"
    "Content-Length: 178\r\n"
    "\r\n"
    "<html>\r\n"
    "  <header>\r\n"
    "    <title>LED Power<title>\r\n"
    "  </header>\r\n"
    "  <body>\r\n"
    "    <h1>Lets rotate!!11elf</h1>\r\n"
    "    <p>Bam!!!!!!!!!!.</p>\r\n"
    "    <a href=\"/\">back</a>\r\n"
    "  </body>\r\n"
    "</html>\r\n"
    "\r\n"
};

/* Every time called if a packet is received for a */
/* TCPConnection which registerd this Callback. */
err_t recv_callback(TCPCallbackConnection *arg, struct pbuf *p, err_t err) {
    int i;
    char *data;

    /* Check if status is ok and data is arrived. */
    if (err == ERR_OK && p != NULL) {
        /* Inform TCP that we have taken the data. */
        arg->recved(p->tot_len);
        data = static_cast<char *>(p->payload);

        /* If the data is a GET request we can handle it. */
        if (strncmp(data, "GET ", 4) == 0) {
            for (i = 0; i < 40; i++) {
                if (((char *)data + 4)[i] == ' ' ||
                        ((char *)data + 4)[i] == '\r' ||
                        ((char *)data + 4)[i] == '\n') {
                    ((char *)data + 4)[i] = 0;
                }
            }

            /* Check the URL */
            /* We only know two URLs /1.html and default */
            /* store the URL information in our global x variable to change twinkle behaviour. */
            x = (strncmp((char *)(data + 4), "/1.html", 7) == 0)? 1: 0;
            /* Clean up the Memory */

            /* Send the right page as answere. */
            if (arg->write((void *)page[x], strlen(page[x])) != ERR_OK) {
                error("Could not write", 0);
            }
        } else {
            /* This message was not a GET request.
               Maybe it was a follow message or another kind of request. */
        }
    } else {
        /* No data arrived */
        /* That means the client closes the connection and sent us a packet with FIN flag set to 1. */
        /* We have to cleanup and destroy out TCPConnection. */
        arg->close();
        NetServer::get()->free(arg);
    }

    pbuf_free(p);
    /* Don't panic! Everything is fine. */
    return ERR_OK;
}

/* Accept an incomming call on the registered port */
err_t accept_callback(TCPCallbackListener *arg, struct tcp_pcb *npcb, err_t err) {
    /* Create a new TCPConnection for the new incomming call. */
    TCPCallbackConnection *con = new TCPCallbackConnection((TCPListener *)arg, npcb,
            NO_SENT_FNC,
            &recv_callback, /* set only a callback for receiving data. */
            NO_POLL_FNC,
            NO_CONNECT_FNC,
            NO_ERR_FNC
                                                          );

    /* Don't panic! Everything is fine. */
    return ERR_OK;
}

int main(void) {
    /* Bind a function to a tcp port */
    NetServer::ready()->bindTCPPort(80, &accept_callback);

    /* Give the signal that we are ready */
    printf("entering while loop\n");
    while (1) {
        wait(0.1);
        NetServer::poll();
        if (x) {
            led1 = !led1;
        } else {
            led2 = !led2;
        }
    }
}

