#include "network.h"

/* This library is (C)2002 by Aleksander Malinowski, Bradley University */
/* See also http://gdansk.bradley.edu/olekmali/ for more about author */
/* It may be used and redistributed free of charge under the GNU license*/
/* provided  that this copyright note is not removed.                   */

Err AmNetLibLoad(AM_tcpip *S) {
    Err err;
    (*S).error=errNone;

    err = SysLibFind("Net.lib", &(*S).AppNetRefnum );
    if (err) return err;

    err = NetLibOpen((*S).AppNetRefnum, &(*S).error);
    return err;
}

Err AmNetLibConnect(AM_tcpip *S, const Char *hostname, const UInt16 port, const UInt16 tout) {
    NetHostInfoBufType  hostdata;
    NetSocketAddrEnum   socketdomain;
    NetSocketTypeEnum   sockettype;
    Int16               socketprotocol;
    NetSocketAddrINType socketaddrtype;
    Int16               socketaddrtlen;

    (*S).AppNetTimeout = SysTicksPerSecond() * tout; /* defaultis 2 */

    NetLibGetHostByName((*S).AppNetRefnum, hostname, &hostdata, (*S).AppNetTimeout, &(*S).error);
    if ((*S).error) return (errNone);

    socketdomain            = netSocketAddrINET;    /* socket address type */
    sockettype              = netSocketTypeStream;  /* - TCP/IP but =netSocketTypeDatagram - UDP */
    socketprotocol          = netSocketProtoIPTCP;  /* currently ignored */
    socketaddrtype.family   = netSocketAddrINET;
    socketaddrtype.port     = port;
    StrNCopy( (char*) &socketaddrtype.addr,  (char*) *hostdata.hostInfo.addrListP, hostdata.hostInfo.addrLen ); 
    socketaddrtlen          = sizeof(socketaddrtype);
    (*S).sendreceiveflags   = 0;

    (*S).socket =  NetLibSocketOpen ((*S).AppNetRefnum, socketdomain, sockettype, socketprotocol, (*S).AppNetTimeout, &(*S).error);
    if ((*S).error) return (errNone);

    return NetLibSocketConnect ((*S).AppNetRefnum, (*S).socket, (NetSocketAddrType*) &socketaddrtype, socketaddrtlen, (*S).AppNetTimeout, &(*S).error);
}

Int16 AmNetLibSend(AM_tcpip *S, Char *buffer, UInt16 buflen) {
    return NetLibSend((*S).AppNetRefnum, (*S).socket, buffer, buflen, (*S).sendreceiveflags, NULL,  0,  (*S).AppNetTimeout, &(*S).error);
}

Int16 AmNetLibRecv(AM_tcpip *S, Char *buffer, const int maxlen) {
    Int16 bufdone;
    bufdone = NetLibReceive ((*S).AppNetRefnum, (*S).socket, buffer, maxlen, (*S).sendreceiveflags, NULL,  NULL, (*S).AppNetTimeout, &(*S).error);
    return(bufdone);
}

Int16 AmNetLibSendLine(AM_tcpip *S, Char *line) {
    return NetLibSend((*S).AppNetRefnum, (*S).socket, line, StrLen(line), (*S).sendreceiveflags, NULL,  0,  (*S).AppNetTimeout, &(*S).error);
}

Int16 AmNetLibRecvLine(AM_tcpip *S, Char *line, const int maxlen) {
    Int16 n;
    Int16 len=0;
    Char  bch;
    n = AmNetLibRecv(S, &bch, 1);
    while (n > 0) {
        if (len>=maxlen) return(-1); /* someone overruns our buffer! */
		if (bch!='\n'&&bch!='\r')
		{
			line[len]=bch;
			len++;
		}
		else
		{
			line[len]='\0';
            if (len>0) return(len);
            /* else - an empty string, skip it */
		}
        n = AmNetLibRecv(S, &bch, 1);
    }
    return(n);    
}

Err AmNetLibClose(AM_tcpip *S) {
    Err err;
    err = NetLibSocketClose ((*S).AppNetRefnum, (*S).socket, (*S).AppNetTimeout, &(*S).error);
    if (err || (*S).error) {
        err=NetLibClose((*S).AppNetRefnum, false);
        return err;
    }
    return errNone;
}

Err AmNetLibUnload(AM_tcpip *S) {
    Err err;
    (*S).error=errNone;
    err = NetLibClose((*S).AppNetRefnum, false);
    return err;
}