/*****
 NAME
 	casyncclient.m - source code for CAsyncClient
 VERSION
 	$Id$
 CHANGELOG
 	$Log$
 */

#include <coconut/gnet/casyncclient.h>
#include <coconut/gnet/casyncnet.h>
#include <coconut/ceventsystem.h>

static void gnet_async_connect(GTcpSocket * socket, GInetAddr * addr, 
  GTcpSocketConnectAsyncStatus status, gpointer data) ;

@implementation CAsyncClient

- init
{
	socket_id = NULL ;
	return [super init] ;
}

- (void) dealloc
{
	[self close] ;
	[super dealloc] ;
}

- (id <PError>) openToRead: (int) portnum server: (const char *) server
    output: (id <PStream>) output
{
	[super setStream: nil and: output] ;
	socket_id = gnet_tcp_socket_connect_async(server, portnum, 
	  &gnet_async_connect, self) ;
	return nil ;
}

- (id <PError>) openToWrite: (int) portnum server: (const char *) server
    input: (id <PStream>) input 
{
	[super setStream: input and: nil] ;
	socket_id = gnet_tcp_socket_connect_async(server, portnum, 
	  &gnet_async_connect, self) ;
	return nil ;
}

- (id <PError>) close
{
	if(socket_id){
		/* gnet_tcp_socket_connect_async_cancel(socket_id) ; */
		socket_id = NULL ;
	}
	return [super closeChannel] ;
}

- (void) asyncConnect: (GTcpSocket *) socket addr: (GInetAddr *) addr
    status: (GTcpSocketConnectAsyncStatus) status
{
	guint		mask ;
	GIOChannel *	channel ;

	/* g_message("client: asyncConnect\n") ; */
	if(status != GTCP_SOCKET_CONNECT_ASYNC_STATUS_OK){
		g_error("could not connect") ;
		return ;
	}
	[CEventSystem retainMainLoop] ;
	channel = gnet_tcp_socket_get_iochannel(socket) ;
	mask = G_IO_ERR | G_IO_HUP | G_IO_NVAL ;
	if(input_stream) mask |= G_IO_OUT ;
	if(output_stream) mask |= G_IO_IN ;
	g_io_add_watch(channel, mask, &gnet_async_io, self) ;
}

@end

static void gnet_async_connect(GTcpSocket * socket, GInetAddr * addr, 
  GTcpSocketConnectAsyncStatus status, gpointer data)
{
	CAsyncClient * client = (CAsyncClient *) data ;
	[client asyncConnect: socket addr: addr status: status] ;
}

