#include <stdio.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <stdlib.h>
#include <strings.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#include "client.h"
#include "ui_client.h"


#define SERVER_TCP_PORT     7000    // Default port
#define BUFLEN              255      // Buffer length
#define USRSIZE             100

Client::Client(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Client)
{
    ui->setupUi(this);
}

Client::~Client()
{
    delete ui;
}

void Client::on_sendButton_clicked()
{

    ui->chatwin->setText(ui->msg->text());

}

void Client::ioLoop()
{
    int n, bytes_to_read;
    int sd, port;
    struct hostent  *hp;
    struct sockaddr_in server;
    char  *host, *bp, rbuf[BUFLEN], sbuf[BUFLEN], **pptr;
    char str[16];
    bool forkFlag = true;
    char usrName[USRSIZE];
    char temp[BUFLEN];
    char closeChat[] = "--close";
    char localhost[] = "127.0.0.1";

    pid_t childpid;

    childpid = fork();

    if(childpid > 0){
        /*switch(argc)
        {
            case 1:
                host = localhost;
                port = SERVER_TCP_PORT;
            break;
            case 2:
                host =  argv[1];    // Host name
                port =  SERVER_TCP_PORT;
            break;
            case 3:
                host =  argv[1];
                port =  atoi(argv[2]);  // User specified port
            break;
            default:
                fprintf(stderr, "Usage: %s host [port]\n", argv[0]);
                exit(1);
        }*/


        // Create the socket
        if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
        {
            perror("Cannot create socket");
            exit(1);
        }
        bzero((char *)&server, sizeof(struct sockaddr_in));
        server.sin_family = AF_INET;
        server.sin_port = htons(port);
        if ((hp = gethostbyname(host)) == NULL)
        {
            fprintf(stderr, "Unknown server address\n");
            exit(1);
        }
        bcopy(hp->h_addr, (char *)&server.sin_addr, hp->h_length);

        printf("Enter a username: ");
        //fgets (usrName, sizeof(usrName), stdin);
        for(int k = 0; k < USRSIZE; k++)
        {
            if(usrName[k] == '\n')
                usrName[k] = '\0';
        }
        strcat(usrName, ": ");


        // Connecting to the server
        if (connect (sd, (struct sockaddr *)&server, sizeof(server)) == -1)
        {
            fprintf(stderr, "Can't connect to server\n");
            perror("connect");
            exit(1);
        }
        printf("Connected:    Server Name: %s\n", hp->h_name);
        pptr = hp->h_addr_list;
        printf("\t\tIP Address: %s\n", inet_ntop(hp->h_addrtype, *pptr, str, sizeof(str)));
        while(true){

            printf(usrName);
            //gets(sbuf); // get user's text
            //fgets (sbuf, BUFLEN - USRSIZE, stdin);

            if(strcmp(sbuf, closeChat) != 0)
            {

                strcpy(temp, usrName);
                strcat(temp, sbuf);
                strcpy(sbuf, temp);
            }
            else
            {
                break;
            }
            // Transmit data through the socket
            send (sd, sbuf, BUFLEN, 0);

            if(forkFlag)
            {
                forkFlag = false;
                if(fork())
                {
                    while(true)
                    {
                        //printf("Receive:\n");
                        bp = rbuf;
                        bytes_to_read = BUFLEN;

                        // client makes repeated calls to recv until no more data is expected to arrive.
                        n = 0;
                        while ((n = recv (sd, bp, bytes_to_read, 0)) < BUFLEN)
                        {
                            bp += n;
                            bytes_to_read -= n;
                        }
                        printf ("%s\n", rbuf);
                    }
                }
            }

        }
        fflush(stdout);
        close (sd);
    }
}