
#ifndef anet_h //don't include twice
#define anet_h

//the files are copied when publishing:
#define PRAGMA_BIND "ANet.dll"
#define PRAGMA_BIND "ANet.key"
#define PRAGMA_BIND "OpenAL32.dll"
#define PRAGMA_BIND "wrap_oal.dll"

#define ANET_ERROR -1
#define ANET_SUCCESS 1
#define ANET_HTTP_ERROR_CONNECTION -2
#define ANET_HTTP_ERROR_HOST -3
#define ANET_HTTP_ERROR_PROXY -4
#define ANET_HTTP_ERROR_TIMEDOUT -5
#define ANET_UPNP_NOTFOUND 0

#define BPS_OUT 1
#define BPS_IN 2
#define DONTSEND_Z 1
#define ONLYSEND_PAN 1
#define ANET_PROTOCOL_UDP 1
#define ANET_PROTOCOL_TCP 2
#define MY_GLOBPOINTER enet_ent_globpointer(my)
#define MY_CREATOR enet_ent_creator(enet_ent_globpointer(my))
#define MY_CLIENTID enet_get_clientid()
#define MY_CONNECTION enet_get_connection()

#define FTRANSFER_STATUS 1
#define FTRANSFER_RECEIVER 2
#define FTRANSFER_SENDER 3
#define FTRANSFER_RATE 4
#define FTRANSFER_TOTAL 5
#define FTRANSFER_SENT 6
#define FTRANSFER_SENDING 1
#define FTRANSFER_RECEIVING 2

#define VOIP_QUALITY 1
#define VOIP_COMPLEXITY 2
#define VOIP_ENABLE_VAD 3
#define VOIP_VAD_PROBSTART 4
#define VOIP_VAD_PROBCONTINUE 5
#define VOIP_ENABLE_DENOIS 6
#define VOIP_DENOIS_SUPPRESSION 7
#define VOIP_ENABLE_AGC 8
#define VOIP_AGC_LEVEL 9

//receivers:
#define SERVER -2
#define BROADCAST -1

//connection:
#define NO_CONNECTION 0
#define SERVER_MODE 1
#define CLIENT_MODE 2
#define CLIENT_SERVER_MODE 3

//systemevents:
#define EVENT_CONNECTED 1
#define EVENT_DISCONNECTED 2
#define EVENT_SYNCHRONIZED 3
#define EVENT_ENT_REMOVED 4
#define EVENT_PASSWORD 5
#define EVENT_LEVEL 6
#define EVENT_FTRANSFER_STARTED 7
#define EVENT_FTRANSFER_COMPLETED 8
#define EVENT_FTRANSFER_ABORTED 9
#define EVENT_SERVERFULL 10
#define EVENT_PLAYERNAME 11
#define EVENT_VERSION 12
#define EVENT_DATA_CHANGED 13

/////////////////////
//general functions//
/////////////////////

void anet_set_warning(var mode);

var anet_get_version(STRING* version);

////////////////////////
//management functions//
////////////////////////

void enet_use_handles(var mode);

void enet_reg_mem(char* data, var size);
void enet_reg_mem(char* data)
{
	enet_reg_mem(data, sizeof(char));
}
void enet_reg_mem(var* data)
{
	enet_reg_mem(data, sizeof(var));
}
void enet_reg_mem(short* data)
{
	enet_reg_mem(data, sizeof(short));
}
void enet_reg_mem(int* data)
{
	enet_reg_mem(data, sizeof(int));
}
void enet_reg_mem(float* data)
{
	enet_reg_mem(data, sizeof(float));
}
void enet_reg_mem(double* data)
{
	enet_reg_mem(data, sizeof(double));
}
void enet_reg_mem(STRING* data)
{
	enet_reg_mem(data, 1);
}

var enet_init();

void enet_deinit();

void enet_set_gameversion(STRING* version_str);

var enet_init_server(var port, var max_player, STRING* password);

var enet_init_client(STRING* ip, var port, STRING* password);

void enet_disconnect_client(var ClientID, STRING* msg);

void enet_destroy_host();

void enet_set_level(STRING* levelname);

void enet_set_encryption(var mode, STRING* key);

void enet_set_unreliable(var mode);

//////////////////
//info functions//
//////////////////

var enet_get_clientid();

var enet_get_connection();

var enet_connected_clients();

var enet_check_client(var clientid);

var enet_get_myip(STRING* ip1,STRING* ip2,STRING* ip3,STRING* ip4);
var enet_get_myip(STRING* ip1)
{
	return enet_get_myip(ip1, NULL, NULL, NULL);
}
var enet_get_myip(STRING* ip1, STRING* ip2)
{
	return enet_get_myip(ip1, ip2, NULL, NULL);
}
var enet_get_myip(STRING* ip1, STRING* ip2, STRING* ip3)
{
	return enet_get_myip(ip1, ip2, ip3, NULL);
}

STRING* enet_get_clientip(var clientid);

STRING* enet_get_serverip();

var enet_get_ping();

var enet_get_bps(var type);

var enet_get_time();

///////////////////
//event functions//
///////////////////

var enet_svset_event(var type, void* pfunc);

var enet_clset_event(var type, void* pfunc);

//////////////////
//send functions//
//////////////////

void enet_sendto(void* data, var size, var receiver);

void enet_send_str(STRING* str, var receiver);
void enet_sendto(STRING* data, var receiver)
{
	enet_send_str(data, receiver);
}

void enet_svsend_event(var type, char* msg, var length, var receiver);
void enet_svsend_event(var type, STRING* msg, var receiver)
{
	enet_svsend_event(type, _chr(msg), str_len(msg) + 1, receiver);
}

void enet_clsend_event(var type, char* msg, var length, var receiver);
void enet_clsend_event(var type, STRING* msg, var receiver)
{
	enet_clsend_event(type, _chr(msg), str_len(msg) + 1, receiver);
}

void enet_send_skills(var entity,var from,var to,var receiver);

void enet_send_flags(var entity,var from,var to,var receiver);

void enet_send_pos(var glob_pointer, var receiver, var mode);

void enet_send_angle(var glob_pointer, var receiver, var mode);

////////////////////
//entity functions//
////////////////////

void enet_reg_ent(var id, STRING* filename, void* pfunc);

ENTITY* enet_svent_create(var id, VECTOR* position);

ENTITY* enet_clent_create(var id, VECTOR* position);

void enet_ent_morph(var glob_pointer, var id);

void enet_svent_remove(var glob_pointer);

void enet_clent_remove(var glob_pointer);

var enet_ent_globpointer(ENTITY* entity);

ENTITY* enet_ent_locpointer(var globalpointer);

var enet_ent_creator(var globalpointer);

void enet_ent_sync();

////////////////////
//player functions//
////////////////////

void enet_set_playername(STRING* playername);

STRING* enet_get_playername(var clientid);

//////////////////
//file functions//
//////////////////

typedef void FTransfer;

void enet_set_frate(var rate);

void enet_set_fpath(STRING* path);

FTransfer* enet_clsend_file(STRING* filename);

FTransfer* enet_svsend_file(STRING* filename, var receiver);

void enet_abort_fsending(FTransfer* transfer);

STRING* enet_get_fname(FTransfer* transfer);

long enet_get_finfo(FTransfer* transfer, var info);

////////////////////
//socket functions//
////////////////////

typedef void* SOCKET;

SOCKET sock_tcp_server(var port);

SOCKET sock_tcp_client(STRING* ip, var port);

SOCKET sock_udp(var port);

void sock_close(SOCKET socket);

SOCKET sock_tcp_accept(SOCKET socket, STRING* ip);

var sock_udp_sendto(SOCKET socket, char* data, var size, STRING* ip, var port);
var sock_udp_sendto(SOCKET socket, STRING* data, STRING* ip, var port)
{
	return sock_udp_sendto(socket, _chr(data), str_len(data) + 1, ip, port);
}

var sock_tcp_send(SOCKET socket, char* data, var size);
var sock_tcp_send(SOCKET socket, STRING* data)
{
	return sock_tcp_send(socket, _chr(data), str_len(data) + 1);
}

var sock_recv(SOCKET socket, char** data, STRING* ip, var* port);

void sock_free_buffer(char* data);

//////////////////
//http functions//
//////////////////

typedef void httpPost;

void http_set_proxy(STRING* proxy, var port);

httpPost* http_post(STRING* url, STRING* data);

var http_get_status(httpPost* post);

STRING* http_get_result(httpPost* post);

void http_cleanup(httpPost* post);

/////////////////
//ftp functions//
/////////////////

var ftp_get(STRING* url, STRING* path, STRING* username, STRING* password);

var ftp_put(STRING* url, STRING* path, STRING* username, STRING* password);

var ftp_get_date(STRING* url, STRING* username, STRING* password);

void ftp_stop_transfer();

double ftp_get_size(var mode);

var ftp_get_progress();

long ftp_get_timestamp();

var ftp_get_status();

void ftp_debug_transfer(var mode);

/////////////////
//Voice over IP//
/////////////////

var voip_init(var port, var sps);

var voip_get_connected(var clientid);

var voip_record();

void voip_set_receiver(var* rcv_list, var num_rcv);

void voip_set_volume(var volume, var input_gain);

void voip_set_threshold(var threshold, var delay);

var voip_get_volume();

var voip_get_playing(var clientid);

void voip_set_encoption(var option, var value);

void voip_close();

//////////////////
//upnp functions//
//////////////////

var upnp_open_port(STRING* loc_ip, var port_in, var port_out, var protocol, STRING* description);

var upnp_close_port(STRING* loc_ip, var port_out, var protocol);

////////////////////////////////////////
//Internal stuff (do not change this!)//
////////////////////////////////////////

#ifndef windows_h

#define WINAPI __stdcall
long WINAPI GetModuleHandle(long lpModuleName);
#define PRAGMA_API GetModuleHandle;kernel32!GetModuleHandleA

#endif

void anet_callback();

function anet_main_loop_startup()
{
	if(GetModuleHandle("ANet.dll") == 0)
		error("Couldn't load ANet.dll!\n\nReinstalling the game or installing the Visual Studio 2008 Redistributable Package will solve the problem.");
	
	while(1)
	{
		anet_callback();
		wait(1);
	}
}

#endif