#ifndef NET_H
#define NET_H

#ifdef __cplusplus
extern "C" {
#endif

#ifdef _MSC_VER
#ifdef BUILD_DLL
#define NET_API __declspec(dllexport)
#else
#define NET_API __declspec(dllimport)
#endif
#else
#define NET_API
#endif

// possible error codes
// every function, which returns an int, returns a value >= 0,
// or a value < 0, -error_code, with error_code:
enum {
	NET_STARTUP_FAILED=1,
	NET_CLEANUP_FAILED,
	NET_BIND_FAILED,
	NET_CREATE_SOCKET_FAILED,
	NET_GET_HOST_BY_NAME_FAILED,
	NET_LISTEN_FAILED,
	NET_ACCEPT_FAILED,
	NET_CLOSE_SOCKET_FAILED,
	NET_CONNECT_FAILED,
	NET_WRITE_FAILED,
	NET_READ_FAILED,
	NET_LOOP_FAILED
};

// signature of the callback functions
typedef void(*SocketEventCallback)(int socket);

NET_API extern SocketEventCallback g_readCallback;
NET_API extern SocketEventCallback g_writeCallback;
NET_API extern SocketEventCallback g_errorCallback;

// register callback for read events. The callback is called:
// - when data can be read without blocking
// - when an incoming connection for a server socket can be accepted
NET_API void netRegisterReadCallback(SocketEventCallback callback);

// functions for registering the callback functions. The callback is called:
// - when a socket was connected
// - when it is possible to write more data with netWrite
NET_API void netRegisterWriteCallback(SocketEventCallback callback);

// functions for registering the callback functions
NET_API void netRegisterErrorCallback(SocketEventCallback callback);

// initialize the network system
NET_API int netStartup();

// shutdown the network system
NET_API int netCleanup();

// create an outgoing socket
NET_API int netCreateSocket();

// create and bind a server socket (if address is NULL, bind to any address)
NET_API int netCreateServerSocket(const char* address, int port);

// start listening on a server socket
NET_API int netListen(int serverSocket, int backlog);

// connect to the specified address and port
NET_API int netConnect(int socket, const char* address, int port);

// can be called on the accept callback to accept an incoming connection
NET_API int netAccept(int serverSocket, char** ipAddress);

// close a socket
NET_API int netCloseSocket(int socket);

// wait for an event or timeout
NET_API int netWait(int millisecondsTimeout);

// write to a socket
NET_API int netWrite(int socket, const void* data, int size, int* sent);

// read from a socket
NET_API int netRead(int socket, void* data, int size, int* received);

// sleep for the specified time in seconds
NET_API void netSleep(int seconds);

#ifdef __cplusplus
}
#endif

#endif
