/* ************************************************************************** */
/* ***************************** definitions ******************************** */
/* ************************************************************************** */

#if !defined(_MPSCLIENT_DEFS_H_INCLUDED_)
#define _MPSCLIENT_DEFS_H_INCLUDED_

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <sys/types.h>
#include <inttypes.h>
#include <signal.h>
#include "MPS_consts.h"
#include "MPSClient_lib.h"

#if defined(__MINGW32__)
	#include <winsock2.h>
	#include <ws2tcpip.h>
	#include <windef.h>

	#define SHUT_RD   SD_RECEIVE
	#define SHUT_WR   SD_SEND
	#define SHUT_RDWR SD_BOTH

	#undef USE_FORK
#else
	#include <sys/socket.h>
	#include <sys/select.h>
	#include <netinet/in.h>
	#include <netdb.h>

	#define closesocket(x) close(x)

	#define USE_FORK
#endif

#if !defined(USE_FORK)
	#include <process.h>
#endif

#define MIN(x,y) ( ( (x) <= (y) )?(x):(y) )

#undef WAIT_FOR_WRITE

typedef struct _thread_semaphore_ {
	pthread_t thread_id;
	sem_t semaphore;
	int is_waiting;

	struct _thread_semaphore_ *next, *prev;
} thread_semaphore;

typedef struct _td_buffer_struct_ {
	unsigned int pos, size;
	void *buf;
} td_buffer_struct;

/* pointer to thread for receiving messages from server */
extern void *client_thread(void *data);

/* thread semaphore functions */
extern thread_semaphore *create_thread_semaphore();
extern void delete_thread_semaphores();
extern int post_thread_semaphore(sem_t *sem);
extern void post_waiting_thread_semaphores();

/* functions for reading data from socket */
extern int td_read_char_array(int socket, char *data, u_long length);
extern int td_read_string(int socket, char *data, u_long length);
extern int td_read_u_char(int socket, u_char *data);
extern int td_read_u_long(int socket, u_long *data);

/* functions for writing data to socket */
extern int td_write_char_array(int socket, char *data, u_long length, td_buffer_struct *buffer);
extern int td_write_u_char(int socket, u_char *data, td_buffer_struct *buffer);
extern int td_write_u_long(int socket, u_long *data, td_buffer_struct *buffer);

extern int td_flush(int socket, td_buffer_struct *buffer);
#endif
