/*-*-linux-c-*-*/

#ifndef CONNECTION_H
#define CONNECTION_H

#include <stdio.h>
#include <time.h>

#include <gtk/gtk.h>

#include "global.h"

#define QUEUE_FULL 20              /* maximum pending outgoing packets */

/* connection type */
typedef enum { CT_INCOMING, CT_OUTGOING, CT_DOWNLOAD, CT_UPLOAD } con_type;

typedef enum {
	GS_WAITINGCONNECT, GS_CONNECTED, GS_FAILED, GS_BUSY, GS_TIMEOUT,
	GS_STOPPED, GS_COMPLETE, GS_WAITINGPUSH, GS_HANDSHAKE, GS_HOSTFEED,
	GS_NOTFOUND, GS_RESUME
} con_state;

struct gpacket {
	gchar  *data;
	gchar   from_us;
	guint16 len;
	guint32 _time;
};

struct newtella_connection {

	con_state state;
	con_type  type;

	/* statistics */
	guint32 total_sent, total_dropped_to_send;
	guint32 total_handled, total_received_dropped, total_bad_received;
	guint32 handled, sent;

	guint32 speed;

	time_t last_time;
	guint32 s;
	uint8_t ip[16];
	guint16 port;

	GList *queue;

	gchar buffer[MAX_PACKET_LENGTH];
	guint buffer_len;
	gchar *b;

	gint read_tag, write_tag;

	struct file_found *fi;

	/* 1 if handshake has been sent */
	gchar hs_sent;

	guint32 u_file_size;
};


int bytes_avail(int s);

int  con_recv_packet(struct newtella_connection *con, gint len);
void con_send_packet(struct newtella_connection *con, gchar *buf, gint len, gint maydrop);
int  con_send_ex_one(struct newtella_connection *con, gchar *buf, gint len, gint maydrop);
int  con_send_to_all(gchar *buf, gint len, gint maydrop);

int con_add(uint8_t *ip, guint16 port);
int con_activate(void);
int con_mark(struct newtella_connection *con, con_state statet);
int con_remove(struct newtella_connection *con);

int  con_reset_buffer(struct newtella_connection *con);
void con_zero_stats(struct newtella_connection *con);
void con_init_queue(struct newtella_connection *con);
#endif
