#include <wiringPi.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <unistd.h>


void sendData(int sockfd, int x){
	int n;

	//declare buffer to store the data to send
	char buffer[32];
	//store the data into the buffer to be sent
	sprintf(buffer, "%d\n", x);
	//send the data through the specified socket and check for errors
	if((n = write(sockfd, buffer, strlen(buffer))) < 0){
		printf("error writing to socket\n");
	}

	buffer[n] = '\0';
}

int main(int argc, char *argv[]){
	//declare variables
	int sockfd, newsockfd, portno = 51717, clilen;
	char buf[250]; char *myIP;
	struct sockaddr_in serv_addr, cli_addr;
	int n;
	int data, incdec, count = 0;
	struct hostent *myStruct;
	struct in_addr **addr_list;	
	int lowFlag = 0; int highFlag = 0;

	//setup the wiringPi GPIO pin setup and set which pins will be inputs and outputs
	wiringPiSetup();
	pinMode(0, OUTPUT);
	pinMode(1, INPUT);
	pinMode(2, INPUT);

	int inside = 0, outside = 0;

	//inform the user what port number we are using
	printf("using port #: %d\n", portno);

	//set socket options and check for errors on creation
	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd < 0){
		printf("sock create err\n");
	} 

	//clear a buffer that will serve as the server address
	bzero((char *) &serv_addr, sizeof(serv_addr));

	//set the specified fields in order to begin transmission
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = INADDR_ANY;
	serv_addr.sin_port = htons(portno);
	//bind the socket and check for errors
	if(bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0){
		printf("error on bind\n");
	}

	//listen for a connection
	listen(sockfd, 100);
	clilen = sizeof(cli_addr);

	//loop forever
	while(1){
		printf("client accept...\n");
		//wait for the handshake from the connection and check for errors on the accept
		if((newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t *) &clilen)) < 0){
			printf("error on accept\n");
		}

		printf("reopened, polling\n");
		//loop until the status of a sensor has been changed
		while(1){
			//read the status of both sensors from the Arduino
			inside = digitalRead(1);
			outside = digitalRead(2);
			//if the inside pin has been tripped, this means a person has entered the room
			if(inside){
				//increment the count and send the new count the the client
				count++;
				sendData(newsockfd, count);
				break;
			}
			//if the outside pin has been tripped, this means a person has exited the room
			else if(outside){
				//decrement the count and ensure that it never goes below zero
				count--;
				if(count < 0){
					count = 0;
				}
				//transmit the new count to the client
				sendData(newsockfd, count);
				break;
			}
		}

		//if the count is equal to zero and the light is on, turn the light off
		if(count == 0 && lowFlag == 0){
			digitalWrite(0, LOW);
			lowFlag = 1;
			highFlag = 0;
		}
		//if the count is greater than zero and the light is current off, turn the light off
		if(count > 0 && highFlag == 0){
			//turn light off
			digitalWrite(0, HIGH);
			//set high flag to show the light is currently on
			highFlag = 1;
			//set low flag to show that the light is not off
			lowFlag = 0;
		}
		//wait for the connection to close and then loop back to the accept to wait for another handshake from the client
		delay(1000);	
	}

 	return 0;
}
