#ifndef __SOCKET_VIEW_RJ
#define __SOCKET_VIEW_RJ

#include "maqview.h"
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

typedef struct ViewServer {
	RefSeq **srcs;
	int v_max;
	int socket;
	int stop;
	int debug;
} ViewServer;

ViewServer* createViewServer(const char *map_file, const char *cns_file, int listen_port, int max_conns);

int runViewServer(ViewServer *server);

void stopViewServer(ViewServer *server);

void freeViewServer(ViewServer *server);

typedef struct {
	int n_ref;
	char **ref_names;
	int64_t *ref_lengths;
	
	int last_code;
	int ref_id;
	int64_t start, end;

	Read *reads;
	int rd_size;
	int rd_cap;

	cns_t *seqs;
	int cns_size;
	int cns_cap;
} ViewInfo;

typedef struct ViewClient {
	ViewInfo *info;
	int socket;
} ViewClient;

ViewClient* connectViewClient(char *server, int port);

void closeViewClient(ViewClient *client);

int fetch_maq_data(ViewClient *client, int ref_id, int64_t start, int64_t end);

#define VIEW_OP_CLOSE	0
#define VIEW_OP_INFO	1
#define VIEW_OP_GOTO	2
#define VIEW_OP_FETCH	3

#define VIEW_RES_ERROR	-1
#define VIEW_RES_OK		0

int request_view_basement_info(int socket);
int send_view_basement_info(int socket, RefSeq *src);
ViewInfo* recv_view_basement_info(int socket);

int request_maq_data(int socket, int last_code, int ref_id, int64_t start, int64_t end);
int send_maq_data(int socket, RefSeq *src, int code, int64_t start, int64_t end);
int recv_maq_data(int socket, ViewInfo *info);

#endif
