/*******************************************************
 Modification of source written originally by Matt Smith
 (mds1281@ritvax.isc.rit.edu). GTK Support is currently
 being added by Jeremy Wise, jwise@pathwaynet.com.

 If distribution of this source code conflicts with the
 ICQ, GNU or any other licenses, please let me know
 immediately, as I will cease the distribution.
*******************************************************/

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>

#include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/time.h>

#include <fcntl.h>
#include <time.h>
#include <stdarg.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>

#include <gdk/gdk.h>

#include "tcp.h"

#ifdef SOUND
#include "playsound.h"
#endif

#include "gtkicq.h"
#include "gtkfunc.h"

#include "pixmaps.h"
#include "msg_queue.h"

typedef struct
{
	gpointer data;
	int i;
} dataandint;
      
GtkWidget *found_list;

void display_url( GtkWidget *widget, char *url );
void add_user_from_info( GtkWidget *widget, dataandint *data );
void icq_allow_auth( GtkWidget *widget, int sock );
void icq_accept_chat( GtkWidget *widget, int cindex );
void icq_refuse_chat( GtkWidget *widget, int cindex );
void begin_search( GtkWidget *widget, gpointer *entries );
void icq_refresh_list( GtkWidget *widget, struct sokandlb *data );

void display_url( GtkWidget *widget, char *url )
{
	char *command;

#ifdef TRACE_FUNCTION
	printf( "display_url\n" );
#endif
	
	command = (char *)malloc( strlen( url ) + 45 );
	sprintf( command, "netscape -remote 'openURL(%s)'", url );
#if 0
/*	gnome_url_show( url );*/
#else
	pclose( popen( command, "r" ) );
#endif
}

void add_user_from_info( GtkWidget *widget, dataandint *data )
{
	char name[16];

#ifdef TRACE_FUNCTION
	printf( "add_user_from_info\n" );
#endif

	sprintf( name, "%d", data->i );
	Add_User( GPOINTER_TO_INT( data->data ), data->i, name );
}

void icq_allow_auth( GtkWidget *widget, int sock )
{
#ifdef TRACE_FUNCTION
	printf( "icq_allow_auth\n" );
#endif

	icq_sendauthmsg( sock, GPOINTER_TO_INT( gtk_object_get_data( GTK_OBJECT( widget ), "uin" ) ) );
}

void icq_accept_chat( GtkWidget *widget, int cindex )
{
	int sock = Contacts[ cindex ].sok;
	DWORD seq = Contacts[ cindex ].chat_seq;

#ifdef TRACE_FUNCTION
	printf( "icq_accept_chat\n" );
#endif

	TCPAcceptChat( sock, cindex, seq );
}

void icq_refuse_chat( GtkWidget *widget, int cindex )
{
	int sock = Contacts[ cindex ].sok;
	DWORD seq = Contacts[ cindex ].chat_seq;

#ifdef TRACE_FUNCTION
	printf( "icq_refuse_chat\n" );
#endif

	TCPRefuseChat( sock, cindex, seq );
}

void begin_search( GtkWidget *widget, gpointer *entries )
{
#ifdef TRACE_FUNCTION
	printf( "begin_search\n" );
#endif

	start_search( GPOINTER_TO_INT( entries[5] ),
	              gtk_entry_get_text( GTK_ENTRY( entries[4] ) ),
	              gtk_entry_get_text( GTK_ENTRY( entries[1] ) ),
	              gtk_entry_get_text( GTK_ENTRY( entries[2] ) ),
	              gtk_entry_get_text( GTK_ENTRY( entries[3] ) ),
	              atoi( gtk_entry_get_text( GTK_ENTRY( entries[0] ) ) ) );
	found_list = NULL;
}

void search_window( GtkWidget *widget, struct sokandlb *data )
{
	static GtkWidget *window = NULL;
	GtkWidget *table;
	GtkWidget *label;
	GtkWidget *box;

	static GtkWidget *uin;
	static GtkWidget *nick;
	static GtkWidget *fname;
	static GtkWidget *lname;
	static GtkWidget *email;
	static GtkWidget *search_entries[6];

	GtkWidget *search_button;
	GtkWidget *close_button;

#ifdef TRACE_FUNCTION
	printf( "search_window\n" );
#endif

	search_entries[ 5 ] = GINT_TO_POINTER( data->sok );

	window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
	gtk_container_border_width( GTK_CONTAINER( window ), 10 );
	gtk_window_set_title( GTK_WINDOW( window ), "GtkICQ: Add Contact" );
	gtk_widget_set_usize( window, 265, 215 );
	
	table = gtk_table_new( 6, 2, FALSE );
	gtk_container_add( GTK_CONTAINER( window ), table );
	gtk_widget_show( table );

	uin = gtk_entry_new();
	search_entries[ 0 ] = uin;
	gtk_table_attach( GTK_TABLE( table ), uin, 1, 2, 0, 1, 0, 0, 5, 5 );
	gtk_widget_show( uin );
	label = gtk_label_new( "UIN:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
	gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1, GTK_FILL, 0, 0, 5 );
	gtk_widget_show( label );

	nick = gtk_entry_new();
	search_entries[ 1 ] = nick;
	gtk_table_attach( GTK_TABLE( table ), nick, 1, 2, 1, 2, 0, 0, 5, 5 );
	gtk_widget_show( nick );
	label = gtk_label_new( "Nick Name:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
	gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2, GTK_FILL, 0, 0, 5 );
	gtk_widget_show( label );

	fname = gtk_entry_new();
	search_entries[ 2 ] = fname;
	gtk_table_attach( GTK_TABLE( table ), fname, 1, 2, 2, 3, 0, 0, 5, 5 );
	gtk_widget_show( fname );
	label = gtk_label_new( "First Name:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
	gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 2, 3, GTK_FILL, 0, 0, 5 );
	gtk_widget_show( label );

	lname = gtk_entry_new();
	search_entries[ 3 ] = lname;
	gtk_table_attach( GTK_TABLE( table ), lname, 1, 2, 3, 4, 0, 0, 5, 5 );
	gtk_widget_show( lname );
	label = gtk_label_new( "Last Name:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
	gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 3, 4, GTK_FILL, 0, 0, 5 );
	gtk_widget_show( label );

	email = gtk_entry_new();
	search_entries[ 4 ] = email;
	gtk_table_attach( GTK_TABLE( table ), email, 1, 2, 4, 5, 0, 0, 5, 5 );
	gtk_widget_show( email );
	label = gtk_label_new( "eMail:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 0.5 );
	gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 4, 5, GTK_FILL, 0, 0, 5 );
	gtk_widget_show( label );

	box = gtk_hbox_new( FALSE, 0 );
	search_button = gtk_button_new_with_label( "Search" );
	gtk_widget_set_usize( search_button, 35, 25 );
	gtk_signal_connect( GTK_OBJECT( search_button ), "clicked",
	                    GTK_SIGNAL_FUNC( begin_search ), search_entries );
	gtk_signal_connect_object( GTK_OBJECT( search_button ), "clicked",
	                           (GtkSignalFunc) gtk_widget_destroy,
	                           GTK_OBJECT( window ) );
	gtk_box_pack_start( GTK_BOX( box ), search_button, FALSE, FALSE, 5 );
	gtk_widget_set_usize( search_button, 80, 30 );
	gtk_widget_show( search_button );

	close_button = gtk_button_new_with_label( "Cancel" );
	gtk_widget_set_usize( close_button, 35, 25 );
	gtk_signal_connect_object( GTK_OBJECT( close_button ), "clicked",
	                           (GtkSignalFunc) gtk_widget_destroy,
	                           GTK_OBJECT( window ) );
	gtk_box_pack_start( GTK_BOX( box ), close_button, FALSE, FALSE, 5 );
	gtk_widget_set_usize( close_button, 80, 30 );
	gtk_widget_show( close_button );

	gtk_widget_show( box );
	gtk_table_attach( GTK_TABLE( table ), box, 1, 2, 5, 6, GTK_FILL, 0, 0, 0 );
	   
	gtk_widget_show( window );
}

void add_to_inv_list( GtkWidget *widget, struct sokandlb *data )
{
	int cx;
	GtkCList *clist = GTK_CLIST( data->lb_userwin );

#ifdef TRACE_FUNCTION
	printf( "add_to_inv_list\n" );
#endif

	for( cx = 0; cx < Num_Contacts; cx++ )
	{
		if( GPOINTER_TO_INT( clist->selection->data ) ==
		    Contacts[ cx ].lb_index )
			break;
	}

	Contacts[ cx ].invis_list = TRUE;
	Contacts[ cx ].vis_list = FALSE;
	snd_invis_list( data->sok );
}

void remove_from_inv_list( GtkWidget *widget, struct sokandlb *data )
{
	int cx;
	GtkCList *clist = GTK_CLIST( data->lb_userwin );

#ifdef TRACE_FUNCTION
	printf( "remove_from_inv_list\n" );
#endif

	for( cx = 0; cx < Num_Contacts; cx++ )
	{
		if( GPOINTER_TO_INT( clist->selection->data ) ==
		    Contacts[ cx ].lb_index )
			break;
	}

	Contacts[ cx ].invis_list = FALSE;
	snd_invis_list( data->sok );
}

void add_to_vis_list( GtkWidget *widget, struct sokandlb *data )
{
	int cx;
	GtkCList *clist = GTK_CLIST( data->lb_userwin );

#ifdef TRACE_FUNCTION
	printf( "add_to_vis_list\n" );
#endif

	for( cx = 0; cx < Num_Contacts; cx++ )
	{
		if( GPOINTER_TO_INT( clist->selection->data ) ==
		    Contacts[ cx ].lb_index )
			break;
	}

	Contacts[ cx ].vis_list = TRUE;
	Contacts[ cx ].invis_list = FALSE;
	snd_vis_list( data->sok );
}

void remove_from_vis_list( GtkWidget *widget, struct sokandlb *data )
{
	int cx;
	GtkCList *clist = GTK_CLIST( data->lb_userwin );

#ifdef TRACE_FUNCTION
	printf( "remove_from_vis_list\n" );
#endif

	for( cx = 0; cx < Num_Contacts; cx++ )
	{
		if( GPOINTER_TO_INT( clist->selection->data ) ==
		    Contacts[ cx ].lb_index )
			break;
	}

	Contacts[ cx ].vis_list = FALSE;
	snd_vis_list( data->sok );
}

void display_mess_history( GtkWidget *widget, struct sokandlb *data )
{
	int cx;
	GtkCList *clist = GTK_CLIST( data->lb_userwin );
	char buf[256];
	GtkWidget *button;
	GtkWidget *table;
	GtkWidget *mainbox;
	GtkWidget *scrollbar;

	GdkColor black = { 0, 0, 0, 0 };

	char filename[ 256 ];
	FILE *file;

#ifdef TRACE_FUNCTION
	printf( "display_mess_history\n" );
#endif

	for( cx = 0; cx < Num_Contacts; cx++ )
	{
		if( GPOINTER_TO_INT( clist->selection->data ) ==
		    Contacts[ cx ].lb_index )
			break;
	}
	
	Contacts[ cx ].log_window = gtk_window_new( GTK_WINDOW_DIALOG );
	Contacts[ cx ].log_list = gtk_text_new( NULL, NULL );
	gdk_color_alloc( gtk_widget_get_colormap( Contacts[ cx ].log_list ), &black );
	gtk_container_border_width( GTK_CONTAINER( Contacts[ cx ].log_window ), 10 );
	gtk_widget_set_usize( Contacts[ cx ].log_window, 450, 400 );
	sprintf( buf, "Message History: %s", Contacts[ cx ].nick );
	gtk_window_set_title( GTK_WINDOW( Contacts[ cx ].log_window ), buf );
	gtk_signal_connect( GTK_OBJECT( Contacts[ cx ].log_window ), "destroy",
	                    GTK_SIGNAL_FUNC( gtk_widget_destroy ),
	                    &Contacts[ cx ].log_window );

	mainbox = gtk_vbox_new( FALSE, 0 );
	gtk_container_add( GTK_CONTAINER( Contacts[ cx ].log_window ), mainbox );
	gtk_widget_show( mainbox );
		
	table = gtk_table_new( 3, 2, FALSE );
	gtk_box_pack_start( GTK_BOX( mainbox ), table, TRUE, TRUE, 0 );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].log_list, 0, 1, 0, 1,
	                  GTK_EXPAND | GTK_SHRINK | GTK_FILL,
	                  GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 5 );
		
	scrollbar = gtk_vscrollbar_new( GTK_TEXT( Contacts[ cx ].log_list )->vadj );
	gtk_table_attach( GTK_TABLE( table ), scrollbar, 1, 2, 0, 1,
	                  GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 5 );
	gtk_widget_show( scrollbar );
	gtk_widget_show( Contacts[ cx ].log_list );
	gtk_widget_show( table );
	gtk_widget_show( Contacts[ cx ].log_window );

	button = gtk_button_new_with_label( "Close" );
	gtk_widget_set_usize( button, 45, 25 );
	gtk_table_attach( GTK_TABLE( table ), button, 0, 2, 2, 3, 0, 0, 0, 0 );
	gtk_signal_connect_object( GTK_OBJECT( button ), "clicked",
	                           GTK_SIGNAL_FUNC( gtk_widget_destroy ),
	                           GTK_OBJECT( Contacts[ cx ].log_window ) );
	gtk_widget_show( button );

	gtk_text_freeze( GTK_TEXT( Contacts[ cx ].log_list ) );
	sprintf( filename, "%s/.icq/history/%ld", getenv( "HOME" ),
	         Contacts[ cx ].uin );

	file = fopen( filename, "r" );

	if( file )
	{
		char buffer[1024];
		int nchars;
		
	while( 1 )
		{
			nchars = fread(buffer, 1, 1024, file );
			gtk_text_insert( GTK_TEXT( Contacts[ cx ].log_list ), NULL, &black, NULL,
			                 buffer, nchars );
			if( nchars < 1024 )
				break;
		}
	}			

	gtk_text_thaw( GTK_TEXT( Contacts[ cx ].log_list ) );
}

void send_url_window( GtkWidget *widget, struct sokandlb *data )
{
	int cx;
	GtkCList *clist = GTK_CLIST( data->lb_userwin );

	char title[64];

	GtkWidget *window;
	GtkWidget *table;
	GtkWidget *label;
	GtkWidget *button;
	GtkWidget *mainbox;
	GtkWidget *box;

	struct URLInfo *urlinfo = (struct URLInfo *)malloc( sizeof( struct URLInfo ) );

#ifdef TRACE_FUNCTION
	printf( "send_url_window\n" );
#endif
	
	for( cx = 0; cx < Num_Contacts; cx ++ )
	{
		if( GPOINTER_TO_INT( clist->selection->data ) ==
		    Contacts[ cx ].lb_index )
			break;
	}

	urlinfo->cindex = cx;

	sprintf( title, "Send URL to: %s", Contacts[ cx ].nick );

	window = gtk_window_new( GTK_WINDOW_DIALOG );
	gtk_window_set_title( GTK_WINDOW( window ), "GtkICQ: Send URL" );
	gtk_container_border_width( GTK_CONTAINER( window ), 10 );
	gtk_widget_set_usize( window, 340, 160 );

	mainbox = gtk_vbox_new( 0, FALSE );
	gtk_container_add( GTK_CONTAINER( window ), mainbox );
	gtk_widget_show( mainbox );

	label = gtk_label_new( title );
	gtk_box_pack_start( GTK_BOX( mainbox ), label, FALSE, FALSE, 0 );
	gtk_widget_show( label );

	table = gtk_table_new( 3, 2, FALSE );
	gtk_box_pack_start( GTK_BOX( mainbox ), table, FALSE, FALSE, 0 );

	label = gtk_label_new( "URL:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1.0, 1.0 );
	gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1,
	                  GTK_FILL, 0, 0, 10 );
	gtk_widget_show( label );
	
	label = gtk_label_new( "Description:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1.0, 1.0 );
	gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2,
	                  GTK_FILL, 0, 0, 10 );
	gtk_widget_show( label );
	
	urlinfo->data = data;
	
	urlinfo->url = gtk_entry_new();
	gtk_table_attach( GTK_TABLE( table ), urlinfo->url, 1, 2, 0, 1, 0, 0, 0, 10 );
	gtk_widget_show( urlinfo->url );
	
	urlinfo->desc = gtk_entry_new();
	gtk_table_attach( GTK_TABLE( table ), urlinfo->desc, 1, 2, 1, 2, 0, 0, 0, 10 );
	gtk_widget_show( urlinfo->desc );
	
	box = gtk_hbutton_box_new();
	gtk_button_box_set_layout(GTK_BUTTON_BOX(box), GTK_BUTTONBOX_SPREAD);
	gtk_table_attach( GTK_TABLE( table ), box, 0, 2, 2, 3, 0, 0, 0, 10 );
	gtk_widget_show( box );
	
	button = gtk_button_new_with_label( "Send" );
	gtk_widget_set_usize( button, 100, 30 );
	gtk_container_add( GTK_CONTAINER( box ), button );

	gtk_signal_connect( GTK_OBJECT( button ), "clicked",
	                    GTK_SIGNAL_FUNC( icq_sendurl ), urlinfo );

	gtk_signal_connect_object( GTK_OBJECT( button ), "clicked",
	                           GTK_SIGNAL_FUNC( gtk_widget_destroy ),
	                           GTK_OBJECT( window ) );

	gtk_widget_show( button );
	
	button = gtk_button_new_with_label( "Cancel" );
	gtk_widget_set_usize( button, 100, 30 );
	gtk_container_add( GTK_CONTAINER( box ), button );

	gtk_signal_connect_object( GTK_OBJECT( button ), "clicked",
	                           GTK_SIGNAL_FUNC( gtk_widget_destroy ),
	                           GTK_OBJECT( window ) );

	gtk_widget_show( button );

	gtk_widget_show( table );
	gtk_widget_show( window );
}

void request_chat( GtkWidget *widget, struct sokandlb *data )
{
	int cx;
	GtkCList *clist = GTK_CLIST( data->lb_userwin );

#ifdef TRACE_FUNCTION
	printf( "request_chat\n" );
#endif

	for( cx = 0; cx < Num_Contacts; cx ++ )
	{
		if( GPOINTER_TO_INT( clist->selection->data ) ==
		    Contacts[ cx ].lb_index )
			break;
	}

	TCPSendChatRequest( Contacts[ cx ].uin, "Chat", data );
}

void remove_user( GtkWidget *widget, struct sokandlb *data )
{
	int cindex, cx;
	int lb_index;
	GtkCList *clist = GTK_CLIST( data->lb_userwin );

#ifdef TRACE_FUNCTION
	printf( "remove_user\n" );
#endif

	for( cx = 0; cx < Num_Contacts; cx ++ )
	{
		if( GPOINTER_TO_INT( clist->selection->data ) ==
		    Contacts[ cx ].lb_index )
		{
			break;
		}
	}

	if( Contacts[ cx ].status == STATUS_OFFLINE )
		data->offline --;
	else
		data->online --;

	cindex = cx;
	lb_index = Contacts[ cx ].lb_index;

	for( cx = 0; cx < Num_Contacts; cx ++ )
	{
		if( Contacts[ cx ].lb_index > lb_index )
			Contacts[ cx ].lb_index --;
	}

	bzero( &Contacts[ cindex ], sizeof( Contact_Member ) );

	for( cx = cindex + 1; cx < Num_Contacts; cx ++ )
		memcpy( &Contacts[ cx - 1 ], &Contacts[ cx ], sizeof( Contact_Member ) );

	Num_Contacts --;
	gtk_clist_remove( GTK_CLIST( data->lb_userwin ), lb_index );
}

void retrieve_away_message( GtkWidget *widget, struct sokandlb *data )
{
	int cx;
	GtkCList *clist = GTK_CLIST( data->lb_userwin );

#ifdef TRACE_FUNCTION
	printf( "retreive_away_message\n" );
#endif

	for( cx = 0; cx < Num_Contacts; cx ++ )
	{
		if( GPOINTER_TO_INT( clist->selection->data ) ==
		    Contacts[ cx ].lb_index )
		{
			break;
		}
	}

	TCPRetrieveAwayMessage( cx, data );
}

void show_personal_info( GtkWidget *widget, struct sokandlb *data )
{
	int cx;
	char buf[32];
	GtkCList *clist = GTK_CLIST( data->lb_userwin );
	GtkWidget *window;
	GtkWidget *table;
	GtkWidget *label;
	GtkWidget *button;

#ifdef TRACE_FUNCTION
	printf( "show_personal_info\n" );
#endif

	for( cx = 0; cx < Num_Contacts; cx ++ )
	{
		if( GPOINTER_TO_INT( clist->selection->data ) ==
		    Contacts[ cx ].lb_index )
		{
			break;
		}
	}

	Contacts[ cx ].info_uin = gtk_entry_new();
	Contacts[ cx ].info_ip = gtk_entry_new();
	Contacts[ cx ].info_nick = gtk_entry_new();
	Contacts[ cx ].info_city = gtk_entry_new();
	Contacts[ cx ].info_state = gtk_entry_new();
	Contacts[ cx ].info_sex = gtk_entry_new();
	Contacts[ cx ].info_phone = gtk_entry_new();
	Contacts[ cx ].info_homepage = gtk_entry_new();
	Contacts[ cx ].info_about = gtk_entry_new();
	Contacts[ cx ].info_fname = gtk_entry_new();
	Contacts[ cx ].info_lname = gtk_entry_new();
	Contacts[ cx ].info_email = gtk_entry_new();
	Contacts[ cx ].info_auth = gtk_entry_new();

	send_info_req( data->sok, Contacts[ cx ].uin );
	send_ext_info_req( data->sok, Contacts[ cx ].uin );

	sprintf( buf, "%u.%u.%u.%u",
	         (BYTE) (Contacts[ cx ].current_ip >> 24),
	         (BYTE) (Contacts[ cx ].current_ip >> 16),
	         (BYTE) (Contacts[ cx ].current_ip >> 8),
	         (BYTE) (Contacts[ cx ].current_ip) );
	gtk_entry_set_text( GTK_ENTRY( Contacts[ cx ].info_ip ), buf );
		
	window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
	gtk_container_border_width( GTK_CONTAINER( window ), 10 );
	gtk_window_set_title( GTK_WINDOW( window ), "GtkICQ: User Information" );
		
	table = gtk_table_new( 8, 6, FALSE );
	gtk_container_add( GTK_CONTAINER( window ), table );

	label = gtk_label_new( "UIN:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );

	label = gtk_label_new( "Nick:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 0, 1, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );
		
	label = gtk_label_new( "IP:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 4, 5, 0, 1, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );

	label = gtk_label_new( "F. Name:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );

	label = gtk_label_new( "L. Name:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 1, 2, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );
		
	label = gtk_label_new( "Sex:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 4, 5, 1, 2, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );

	label = gtk_label_new( "City:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 2, 3, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );

	label = gtk_label_new( "State:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 2, 3, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );
		
	label = gtk_label_new( "Phone:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 4, 5, 2, 3, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );

	label = gtk_label_new( "Email:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 3, 4, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );

	label = gtk_label_new( "Home Page:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 4, 5, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );

	label = gtk_label_new( "Authorization:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 5, 6, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );

	label = gtk_label_new( "About:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 6, 7, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_uin,
	                  1, 2, 0, 1, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_widget_set_usize( Contacts[ cx ].info_uin, 75, 22 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_uin ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_uin );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_nick,
	                  3, 4, 0, 1, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_widget_set_usize( Contacts[ cx ].info_nick, 75, 22 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_nick ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_nick );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_ip,
	                  5, 6, 0, 1, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_widget_set_usize( Contacts[ cx ].info_ip, 100, 22 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_ip ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_ip );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_fname,
	                  1, 2, 1, 2, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_widget_set_usize( Contacts[ cx ].info_fname, 75, 22 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_fname ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_fname );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_lname,
	                  3, 4, 1, 2, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_widget_set_usize( Contacts[ cx ].info_lname, 75, 22 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_lname ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_lname );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_sex,
	                  5, 6, 1, 2, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_widget_set_usize( Contacts[ cx ].info_sex, 100, 22 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_sex ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_sex );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_city,
	                  1, 2, 2, 3, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_widget_set_usize( Contacts[ cx ].info_city, 75, 22 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_city ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_city );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_state,
	                  3, 4, 2, 3, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_widget_set_usize( Contacts[ cx ].info_state, 75, 22 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_state ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_state );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_phone,
	                  5, 6, 2, 3, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_widget_set_usize( Contacts[ cx ].info_phone, 100, 22 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_phone ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_phone );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_email,
	                  1, 6, 3, 4, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_email ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_email );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_homepage,
	                  1, 6, 4, 5, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_homepage ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_homepage );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_auth,
	                  1, 6, 5, 6, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_auth ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_auth );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_about,
	                  1, 6, 6, 7, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_about ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_about );

	button = gtk_button_new_with_label( "Close" );
	gtk_widget_set_usize( button, 55, 30 );
	gtk_table_attach( GTK_TABLE( table ), button, 0, 6, 7, 8, 0, 0, 0, 10 );
	gtk_signal_connect_object( GTK_OBJECT( button ), "clicked",
	                    (GtkSignalFunc) gtk_widget_destroy,
	                    GTK_OBJECT( window ) );
	gtk_widget_show( button );

	gtk_widget_show( table );
	gtk_widget_show( window );
}

void show_info_new( SOK_T sok, int uin )
{
	int cx;
	GtkWidget *box;
	GtkWidget *window;
	GtkWidget *table;
	GtkWidget *label;
	GtkWidget *button;
	static dataandint data;

#ifdef TRACE_FUNCTION
	printf( "show_info_new\n" );
#endif

	for( cx = 0; cx < Num_Contacts; cx ++ )
	{
		if( uin == Contacts[ cx ].uin )
			break;
	}

	Contacts[ cx ].info_uin = gtk_entry_new();
	Contacts[ cx ].info_ip = gtk_entry_new();
	Contacts[ cx ].info_nick = gtk_entry_new();
	Contacts[ cx ].info_city = gtk_entry_new();
	Contacts[ cx ].info_state = gtk_entry_new();
	Contacts[ cx ].info_sex = gtk_entry_new();
	Contacts[ cx ].info_phone = gtk_entry_new();
	Contacts[ cx ].info_homepage = gtk_entry_new();
	Contacts[ cx ].info_about = gtk_entry_new();
	Contacts[ cx ].info_fname = gtk_entry_new();
	Contacts[ cx ].info_lname = gtk_entry_new();
	Contacts[ cx ].info_email = gtk_entry_new();
	Contacts[ cx ].info_auth = gtk_entry_new();

	window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
	gtk_container_border_width( GTK_CONTAINER( window ), 10 );
	gtk_window_set_title( GTK_WINDOW( window ), "GtkICQ: User Information" );
		
	table = gtk_table_new( 8, 6, FALSE );
	gtk_container_add( GTK_CONTAINER( window ), table );

	label = gtk_label_new( "UIN:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 0, 1, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );

	label = gtk_label_new( "Nick:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 0, 1, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );
		
	label = gtk_label_new( "IP:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 4, 5, 0, 1, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );

	label = gtk_label_new( "F. Name:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 1, 2, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );

	label = gtk_label_new( "L. Name:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 1, 2, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );
		
	label = gtk_label_new( "Sex:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 4, 5, 1, 2, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );

	label = gtk_label_new( "City:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 2, 3, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );

	label = gtk_label_new( "State:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 2, 3, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );
		
	label = gtk_label_new( "Phone:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 4, 5, 2, 3, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );

	label = gtk_label_new( "Email:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 3, 4, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );

	label = gtk_label_new( "Home Page:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 4, 5, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );

	label = gtk_label_new( "Authorization:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 5, 6, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );

	label = gtk_label_new( "About:" );
	gtk_misc_set_alignment( GTK_MISC( label ), 1, 1 );
	gtk_table_attach( GTK_TABLE( table ), label, 0, 1, 6, 7, GTK_FILL, 0, 0, 0 );
	gtk_widget_show( label );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_uin,
	                  1, 2, 0, 1, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_widget_set_usize( Contacts[ cx ].info_uin, 75, 22 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_uin ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_uin );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_nick,
	                  3, 4, 0, 1, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_widget_set_usize( Contacts[ cx ].info_nick, 75, 22 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_nick ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_nick );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_ip,
	                  5, 6, 0, 1, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_widget_set_usize( Contacts[ cx ].info_ip, 100, 22 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_ip ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_ip );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_fname,
	                  1, 2, 1, 2, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_widget_set_usize( Contacts[ cx ].info_fname, 75, 22 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_fname ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_fname );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_lname,
	                  3, 4, 1, 2, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_widget_set_usize( Contacts[ cx ].info_lname, 75, 22 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_lname ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_lname );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_sex,
	                  5, 6, 1, 2, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_widget_set_usize( Contacts[ cx ].info_sex, 100, 22 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_sex ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_sex );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_city,
	                  1, 2, 2, 3, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_widget_set_usize( Contacts[ cx ].info_city, 75, 22 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_city ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_city );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_state,
	                  3, 4, 2, 3, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_widget_set_usize( Contacts[ cx ].info_state, 75, 22 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_state ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_state );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_phone,
	                  5, 6, 2, 3, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_widget_set_usize( Contacts[ cx ].info_phone, 100, 22 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_phone ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_phone );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_email,
	                  1, 6, 3, 4, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_email ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_email );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_homepage,
	                  1, 6, 4, 5, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_homepage ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_homepage );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_auth,
	                  1, 6, 5, 6, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_auth ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_auth );

	gtk_table_attach( GTK_TABLE( table ), Contacts[ cx ].info_about,
	                  1, 6, 6, 7, GTK_FILL, GTK_FILL, 5, 5 );
	gtk_entry_set_editable( GTK_ENTRY( Contacts[ cx ].info_about ), FALSE );
	gtk_widget_show( Contacts[ cx ].info_about );

	box = gtk_hbox_new( FALSE, 0 );
	gtk_table_attach( GTK_TABLE( table ), box, 0, 6, 7, 8, 0, 0, 0, 10 );
	gtk_widget_show( box );

	data.i = uin;
	data.data = GINT_TO_POINTER( sok );

	button = gtk_button_new_with_label( "Add User" );
	gtk_widget_set_usize( button, 75, 30 );
	gtk_box_pack_start( GTK_BOX( box ), button, FALSE, FALSE, 5 );
	gtk_signal_connect( GTK_OBJECT( button ), "clicked",
	                    GTK_SIGNAL_FUNC( add_user_from_info ), &data );
	gtk_widget_show( button );

	button = gtk_button_new_with_label( "Close" );
	gtk_widget_set_usize( button, 75, 30 );
	gtk_box_pack_start( GTK_BOX( box ), button, FALSE, FALSE, 5 );
	gtk_signal_connect_object( GTK_OBJECT( button ), "clicked",
	                    (GtkSignalFunc) gtk_widget_destroy,
	                    GTK_OBJECT( window ) );
	gtk_widget_show( button );

	gtk_widget_show( table );
	gtk_widget_show( window );

	send_info_req( sok, uin );
	send_ext_info_req( sok, uin );
}

void icq_refresh_list( GtkWidget *widget, struct sokandlb *data )
{
#ifdef TRACE_FUNCTION
	printf( "icq_refresh_list\n" );
#endif

	Show_Quick_Status( data );
}

void icq_quit( GtkWidget *widget, struct sokandlb *data )
{
	int cx;

#ifdef TRACE_FUNCTION
	printf( "icq_quit\n" );
#endif

	for( cx = 0; cx < Num_Contacts; cx ++ )
	{
		if( Contacts[ cx ].sok > 0 )
			close( Contacts[ cx ].sok );
		if( Contacts[ cx ].chat_sok > 0 )
			close( Contacts[ cx ].chat_sok );
	}

	if( data->window != NULL && GTK_WIDGET_VISIBLE( data->window ) )
		gdk_window_get_size( GTK_WIDGET( data->window )->window,
		                     &WindowWidth,
		                     &WindowHeight );

	Save_RC();
	gtk_main_quit();
}

void icq_quit_object( struct sokandlb *data  )
{
	int cx;

#ifdef TRACE_FUNCTION
	printf( "icq_quit_object\n" );
#endif

	for( cx = 0; cx < Num_Contacts; cx ++ )
	{
		if( Contacts[ cx ].sok > 0 )
			close( Contacts[ cx ].sok );
		if( Contacts[ cx ].chat_sok > 0 )
			close( Contacts[ cx ].chat_sok );
	}

	if( data->window != NULL && GTK_WIDGET_VISIBLE( data->window ) )
		gdk_window_get_size( GTK_WIDGET( data->window )->window,
		                     &WindowWidth,
		                     &WindowHeight );

	Save_RC();
	gtk_main_quit();
}

void icq_refresh( struct sokandlb *data, int sok, GdkInputCondition cond )
{
	static struct timeval tv;
	static fd_set readfds;
	static int next, time_delay = 120;
	int status;

	tv.tv_sec = 2;
	tv.tv_usec = 500000;

#ifdef TRACE_FUNCTION
	printf( "icq_refresh\n" );
#endif

	FD_ZERO(&readfds);
	FD_SET(data->sok, &readfds);

	FD_SET(STDIN, &readfds);

	/* Don't care about writefds and exceptfds: */
	select(data->sok+1, &readfds, NULL, NULL, &tv);

	if (FD_ISSET(data->sok, &readfds))
	{
		Handle_Server_Response( data );
	}

	if ( time( NULL ) > next )
	{
		next = time( NULL ) + time_delay;
		Keep_Alive( data->sok );
	}

#ifdef SOUND
	if( ( status = Show_Quick_Status( data ) ) > 0 && sound_toggle )
	{
		if( UserOnline && status == 1 )
			playsound( UserOnlineSound );
		if( UserOffline && status == 2 )
			playsound( UserOfflineSound );
	}
#else
	Show_Quick_Status( data );
#endif
}

void icq_msgbox(char *message_text, char *sender, struct sokandlb *data )
{
	GtkWidget *window;
	GtkWidget *message;
	GtkWidget *button;
	GtkWidget *table;
	GtkWidget *mainbox;
	GtkWidget *box;
	GtkWidget *text;
	GtkWidget *scrollbar;

	static GtkWidget *allow_button;
	GtkWidget *respond_text;
	GtkWidget *respond_button;
	GtkWidget *force_respond_button;
	GtkWidget *respond_scrollbar;

	GtkWidget *readnext_button;

	GdkColor black = {1.0, 1.0, 1.0, 1.0};
	int cx, cy, cz;
	char buf[100];
	char nick[64];
	int cindex = 0;

#ifdef TRACE_FUNCTION
	printf( "icq_msgbox\n" );
#endif
	
	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

	sscanf( sender, "Message from %[^:]:", nick );

	if( message_text[ 0 ] == 'c' )
		sprintf( sender, "Chat Request from %s:", nick );

	if( message_text[ 0 ] == 'u' )
		sprintf( sender, "URL from %s:", nick );

	if( message_text[ 0 ] == 'a' )
		sprintf( sender, "Auth Request from %s:", nick );

	if( message_text[ 0 ] == 'n' )
		sprintf( sender, "%s has added you to his/her list", nick );

	for( cx = 0; cx < Num_Contacts; cx ++ )
	{
		if( !strcmp( nick, Contacts[ cx ].nick ) )
		{
			cindex = cx;
			Contacts[ cx ].messages --;
			if( Contacts[ cx ].messages == 0 )
			{
				Contacts[ cx ].icon_p = GetIcon_p( Contacts[ cx ].status );
				Contacts[ cx ].icon_b = GetIcon_b( Contacts[ cx ].status );
				Contacts[ cx ].need_update = 1;
			}
		}
	}

	gtk_container_border_width( GTK_CONTAINER( window ), 10 );
	if( message_text[ 0 ] == 'c' )
	{
		gtk_window_set_title( GTK_WINDOW( window ), "GtkICQ: Chat Request" );
		gtk_widget_set_usize( window, 350, 100 );
	}
	else if( message_text[ 0 ] == 'm' )
	{
		gtk_window_set_title(GTK_WINDOW( window ), "GtkICQ: Message" );
/*		gtk_widget_set_usize( window, 450, 400 );*/
	}
	else if( message_text[ 0 ] == 'u' )
	{
		gtk_window_set_title( GTK_WINDOW( window ), "GtkICQ: URL" );
		gtk_widget_set_usize( window, 350, 145 );
	}
	else if( message_text[ 0 ] == 'a' )
	{
		gtk_window_set_title( GTK_WINDOW( window ), "GtkICQ: Authorization Request" );
		gtk_widget_set_usize( window, 350, 100 );
	}
	else if( message_text[ 0 ] == 'n' )
	{
		gtk_window_set_title( GTK_WINDOW( window ), "GtkICQ: User Added You to List" );
		gtk_widget_set_usize( window, 350, 100 );
	}

	mainbox = gtk_vbox_new( FALSE, 0 );
	gtk_container_add( GTK_CONTAINER( window ), mainbox );
	gtk_widget_show( mainbox );

	message = gtk_label_new( sender );

	gtk_box_pack_start( GTK_BOX( mainbox ), message, FALSE, FALSE, 0 );
	gtk_widget_show( message );

	if( message_text[ 0 ] == 'm' )
	{
		table = gtk_table_new(3, 2, FALSE);
		gtk_box_pack_start( GTK_BOX( mainbox ), table, TRUE, TRUE, 0);
	
		text = gtk_text_new( NULL, NULL );
		gtk_text_set_word_wrap( GTK_TEXT( text ), TRUE );
		gtk_table_attach( GTK_TABLE( table ), text, 0, 1, 0, 1,
		                  GTK_EXPAND | GTK_SHRINK | GTK_FILL,
		                  GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 5 );
		gtk_text_set_editable( GTK_TEXT( text ), FALSE );

		scrollbar = gtk_vscrollbar_new( GTK_TEXT( text )->vadj );
		gtk_table_attach( GTK_TABLE( table ), scrollbar, 1, 2, 0, 1,
		                  GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 5 );
		gtk_widget_show( scrollbar );

		respond_text = gtk_text_new( NULL, NULL );
		gtk_text_set_word_wrap( GTK_TEXT( respond_text ), TRUE );
		gtk_table_attach( GTK_TABLE( table ), respond_text, 0, 1, 1, 2,
		                  GTK_EXPAND | GTK_SHRINK | GTK_FILL,
		                  GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 5 );
		gtk_text_set_editable( GTK_TEXT( respond_text ), TRUE );

		respond_scrollbar = gtk_vscrollbar_new( GTK_TEXT( respond_text )->vadj );
		gtk_table_attach( GTK_TABLE( table ), respond_scrollbar, 1, 2, 1, 2,
		                  GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 5 );
		gtk_widget_show( respond_scrollbar );

		gtk_widget_show( text );
		gtk_widget_show( respond_text );
		gtk_widget_show( table );
		gtk_widget_show( window );

		gtk_widget_grab_focus( respond_text );

		gdk_color_alloc( gtk_widget_get_colormap( text ), &black );

		strcpy( buf, "" );
		cy = 0;
		cz = 1;
		for( cx = 1; cx < strlen( message_text ); cx ++ )
		{
			cy ++;
			if( message_text[cx] == '\n' || cy == 70 ||
			    ( cy >= 60 && message_text[cx] == ' ' ) )
			{
				gtk_text_insert( GTK_TEXT( text ), NULL, &black, NULL,
				                 ( message_text + cz ), cy );
				if( cy >= 60 && cy != 70 )
				{
					gtk_text_insert( GTK_TEXT( text ), NULL, &black, NULL,
					                 "\n", 1 );
				}
				if( cy == 70 )
				{
					gtk_text_insert( GTK_TEXT( text ), NULL, &black, NULL,
					                 "-\n", 2 );
				}
				cz += cy;
				cy = 0;
			}
		}			

		if( cz != strlen( message_text ) )
		{
			gtk_text_insert( GTK_TEXT( text ), NULL, &black, NULL,
			                 ( message_text + cz ), strlen( message_text ) - cz );
		}

		box = gtk_hbutton_box_new();
		gtk_button_box_set_layout(GTK_BUTTON_BOX(box), GTK_BUTTONBOX_SPREAD);
		button = gtk_button_new_with_label( "Close" );
		gtk_widget_set_usize(button, 35, 25);
		gtk_table_attach(GTK_TABLE(table), box, 0, 1, 2, 3, GTK_FILL, 0, 0, 0);
		gtk_signal_connect( GTK_OBJECT( button ), "clicked",
		                    GTK_SIGNAL_FUNC( icq_refresh_list ), data );

		gtk_signal_connect_object(GTK_OBJECT (button), "clicked",
		                          (GtkSignalFunc) gtk_widget_destroy, 
	                             GTK_OBJECT(window));

		readnext_button = gtk_button_new_with_label( "Read Next" );
		Contacts[ cindex ].read_next = readnext_button;
		gtk_signal_connect( GTK_OBJECT( readnext_button ), "destroy",
		                    GTK_SIGNAL_FUNC( gtk_widget_destroyed ),
		                    &Contacts[ cindex ].read_next );
		if( Contacts[ cindex ].messages < 1 ||
		    ( Contacts[ cindex ].messages && Contacts[ cindex ].message[ 1 ][ 0 ] == 'c' ) )
			gtk_widget_set_sensitive( readnext_button, FALSE );
		gtk_widget_set_usize( readnext_button, 35, 25 );
		gtk_object_set_data( GTK_OBJECT( readnext_button ), "nick", Contacts[ cindex ].nick );
		gtk_object_set_data( GTK_OBJECT( readnext_button ), "text", text );
		gtk_signal_connect( GTK_OBJECT( readnext_button ), "clicked",
		                    GTK_SIGNAL_FUNC( read_next ), data );

		respond_button = gtk_button_new_with_label( "Reply" );
		gtk_widget_set_usize(respond_button, 35, 25 );

		force_respond_button = gtk_button_new_with_label( "Via Server" );
		gtk_widget_set_usize( force_respond_button, 35, 25 );

		gtk_container_add(GTK_CONTAINER( box ), respond_button );
		gtk_container_add( GTK_CONTAINER( box ), force_respond_button );
		gtk_container_add( GTK_CONTAINER( box ), readnext_button );
		gtk_container_add(GTK_CONTAINER( box ), button);
		gtk_object_set_data( GTK_OBJECT( respond_button ), "nick", Contacts[ cindex ].nick );
		gtk_object_set_data( GTK_OBJECT( respond_button ), "text", respond_text );
		gtk_object_set_data( GTK_OBJECT( respond_button ), "force", NULL );
		gtk_signal_connect( GTK_OBJECT( respond_button ), "clicked",
		                    GTK_SIGNAL_FUNC( icq_sendmessage ), data );
		gtk_signal_connect( GTK_OBJECT( button ), "clicked",
		                    GTK_SIGNAL_FUNC( icq_refresh_list ), data );

		gtk_signal_connect_object(GTK_OBJECT ( respond_button ), "clicked",
		                          (GtkSignalFunc) gtk_widget_destroy, 
		                          GTK_OBJECT(window));
		gtk_widget_show( respond_button );

		gtk_object_set_data( GTK_OBJECT( force_respond_button ), "nick", Contacts[ cindex ].nick );
		gtk_object_set_data( GTK_OBJECT( force_respond_button ), "text", respond_text );
		gtk_object_set_data( GTK_OBJECT( force_respond_button ), "force", "1" );
		gtk_signal_connect( GTK_OBJECT( force_respond_button ), "clicked",
		                    GTK_SIGNAL_FUNC( icq_sendmessage ), data );

		gtk_signal_connect_object(GTK_OBJECT ( force_respond_button ), "clicked",
		                          (GtkSignalFunc) gtk_widget_destroy, 
		                          GTK_OBJECT(window));
		gtk_widget_show( force_respond_button );
		gtk_widget_show( button );
		gtk_widget_show( readnext_button );

		gtk_widget_show(box);
	}
	if( message_text[ 0 ] == 'n' )
	{
		OK_Box( sender, "" );
	}
	if( message_text[ 0 ] == 'c' )
	{
		box = gtk_hbutton_box_new();
		gtk_button_box_set_layout(GTK_BUTTON_BOX(box), GTK_BUTTONBOX_SPREAD);
		button = gtk_button_new_with_label( "Accept" );
		gtk_widget_set_usize(button, 35, 25);
		gtk_container_add(GTK_CONTAINER( box ), button);
		gtk_box_pack_start( GTK_BOX( mainbox ), box, FALSE, FALSE, 20 );
		gtk_signal_connect( GTK_OBJECT( button ), "clicked",
		                    GTK_SIGNAL_FUNC( icq_accept_chat ),
				    GINT_TO_POINTER( cindex ) );

		gtk_signal_connect_object(GTK_OBJECT (button), "clicked",
		                          (GtkSignalFunc) gtk_widget_destroy, 
	                             GTK_OBJECT(window));
		gtk_widget_show(button);

		button = gtk_button_new_with_label( "Refuse" );
		gtk_widget_set_usize(button, 35, 25);
		gtk_container_add(GTK_CONTAINER( box ), button);
		gtk_signal_connect( GTK_OBJECT( button ), "clicked",
		                    GTK_SIGNAL_FUNC( icq_refuse_chat ),
				    GINT_TO_POINTER( cindex ) );

		gtk_signal_connect_object(GTK_OBJECT (button), "clicked",
		                          (GtkSignalFunc) gtk_widget_destroy, 
	                             GTK_OBJECT(window));
		gtk_widget_show( button );
		gtk_widget_show( box );
		gtk_widget_show( window );
	}
	if( message_text[ 0 ] == 'a' )
	{
		box = gtk_hbutton_box_new();
		gtk_button_box_set_layout(GTK_BUTTON_BOX(box), GTK_BUTTONBOX_SPREAD);
		allow_button = gtk_button_new_with_label( "Allow" );
		gtk_widget_set_usize( allow_button, 35, 25 );
		gtk_container_add( GTK_CONTAINER( box ), allow_button );
		gtk_box_pack_start( GTK_BOX( mainbox ), box, FALSE, FALSE, 20 );
		gtk_object_set_data( GTK_OBJECT( allow_button ), "uin", (gpointer)Contacts[ cindex ].uin );
		gtk_signal_connect( GTK_OBJECT( allow_button ), "clicked",
		                    GTK_SIGNAL_FUNC( icq_allow_auth ), GINT_TO_POINTER( data->sok ) );

		gtk_signal_connect_object(GTK_OBJECT( allow_button ), "clicked",
		                          (GtkSignalFunc) gtk_widget_destroy, 
	                             GTK_OBJECT( window ) );
		gtk_widget_show( allow_button );

		button = gtk_button_new_with_label( "Refuse" );
		gtk_widget_set_usize(button, 35, 25);
		gtk_container_add(GTK_CONTAINER( box ), button);

		gtk_signal_connect_object(GTK_OBJECT (button), "clicked",
		                          (GtkSignalFunc) gtk_widget_destroy, 
	                             GTK_OBJECT(window));
		gtk_widget_show( button );
		gtk_widget_show( box );
		gtk_widget_show( window );
	}
	if( message_text[ 0 ] == 'u' )
	{
		int url_len = 0, desc_len = 0;
		GtkWidget *url = gtk_entry_new();
		GtkWidget *desc = gtk_entry_new();

		char *curl = (char *)malloc( strlen( message_text ) );
		char *cdesc = (char *)malloc( strlen( message_text ) );

		gtk_misc_set_alignment( GTK_MISC( message ), 0.0, 0.5 );

		gtk_widget_set_usize( url, 250, 0 );
		gtk_widget_set_usize( desc, 250, 0 );

		for( cx = 1; ; cx ++ )
		{
			if( message_text[ cx ] == '\xFE' || message_text[ cx ] == 0x00 )
			{
				if( message_text[ cx ] == 0x00 )
				{
					url_len = cx - 2 - desc_len;
					break;
				}
				else
					desc_len = cx - 1;
			}
		}

		memcpy( cdesc, message_text + 1, desc_len );
		cdesc[ desc_len ] = 0x00;
		memcpy( curl, message_text + 2 + desc_len, url_len );
		curl[ url_len ]  = 0x00;
/*		sscanf( message_text + 1, "%[^\xFE]\xFE%[^\xFE]", cdesc, curl );*/
		
		gtk_entry_set_text( GTK_ENTRY( url ), curl );
		gtk_entry_set_text( GTK_ENTRY( desc ), cdesc );

		message = gtk_label_new( "Description:" );
		gtk_misc_set_alignment( GTK_MISC( message ), 0.0, 0.5 );
		gtk_widget_show( message );

		gtk_box_pack_start( GTK_BOX( mainbox ), url, FALSE, FALSE, 5 );
		gtk_box_pack_start( GTK_BOX( mainbox ), message, FALSE, FALSE, 0 );
		gtk_box_pack_start( GTK_BOX( mainbox ), desc, FALSE, FALSE, 5 );

		box = gtk_hbutton_box_new();
		gtk_button_box_set_layout( GTK_BUTTON_BOX( box ),
		                           GTK_BUTTONBOX_SPREAD );
		gtk_box_pack_start( GTK_BOX( mainbox ), box, FALSE, FALSE, 0 );
		gtk_widget_show( box );

		button = gtk_button_new_with_label( "Display" );
		gtk_widget_set_usize( button, 100, 30 );
		gtk_container_add( GTK_CONTAINER( box ), button );

		gtk_signal_connect( GTK_OBJECT( button ), "clicked",
		                    GTK_SIGNAL_FUNC( display_url ),
		                    curl );
		
		gtk_signal_connect_object( GTK_OBJECT( button ), "clicked",
		                           GTK_SIGNAL_FUNC( gtk_widget_destroy ),
		                           GTK_OBJECT( window ) );
		gtk_widget_show( button );

		button = gtk_button_new_with_label( "Close" );
		gtk_widget_set_usize( button, 100, 30 );
		gtk_container_add( GTK_CONTAINER( box ), button );

		gtk_signal_connect_object( GTK_OBJECT( button ), "clicked",
		                           GTK_SIGNAL_FUNC( gtk_widget_destroy ),
		                           GTK_OBJECT( window ) );
		gtk_widget_show( button );

		gtk_widget_show( url );
		gtk_widget_show( desc );
		gtk_widget_show( window );
	}
}

void icq_set_status_online( GtkWidget *widget, struct sokandlb *data )
{
	ProgressData *pdata = NULL;

#ifdef TRACE_FUNCTION
	printf( "icq_set_status_online\n" );
#endif

	if( Current_Status == STATUS_OFFLINE )
	{
		Current_Status = STATUS_ONLINE;
		Done_Login = FALSE;
		data->sok = Connect_Remote( server, remote_port, STDERR );
		udp_gdk_input = gdk_input_add( data->sok, GDK_INPUT_READ, (GdkInputFunction) icq_refresh, data );
		Connected = TRUE;
		connecting = show_wait( "Connecting to Server", pdata );
		gtk_statusbar_push( GTK_STATUSBAR( statusbar ), 1, " Connecting to Server..." );

		Login( data->sok, UIN, &passwd[0], our_ip, our_port );
	}
	else
	{
		icq_change_status( data->sok, STATUS_ONLINE, data );
	}
}

void icq_set_status_offline( GtkWidget *widget, struct sokandlb *data )
{
	int cx;

#ifdef TRACE_FUNCTION
	printf( "icq_set_status_offline\n" );
#endif

	Current_Status = STATUS_OFFLINE;
	Quit_ICQ( data->sok );
	gdk_input_remove( udp_gdk_input );
	for( cx = 0; cx < Num_Contacts; cx ++ )
	{
		Contacts[ cx ].last_status = Contacts[ cx ].status;
		Contacts[ cx ].status = STATUS_OFFLINE;
	}
	Show_Quick_Status( data );
	seq_num = 0;
	memset( serv_mess, FALSE, 1024 );
	close( data->sok );

	Connected = FALSE;
	msg_queue_clear();

	ready_set();

}

void icq_set_status_away( GtkWidget *widget, struct sokandlb *data )
{
	ProgressData *pdata = NULL;

#ifdef TRACE_FUNCTION
	printf( "icq_set_status_away\n" );
#endif

	if( Current_Status == STATUS_OFFLINE )
	{
		Current_Status = STATUS_AWAY;
		Done_Login = FALSE;
		data->sok = Connect_Remote( server, remote_port, STDERR );
		udp_gdk_input = gdk_input_add( data->sok, GDK_INPUT_READ, (GdkInputFunction) icq_refresh, data );
		Connected = TRUE;
		connecting = show_wait( "Connecting to Server", pdata );
		gtk_statusbar_push( GTK_STATUSBAR( statusbar ), 1, " Connecting to Server..." );

		Login( data->sok, UIN, &passwd[0], our_ip, our_port );
	}
	else
	{
		icq_change_status( data->sok, STATUS_AWAY, data );
		change_away_window( NULL, NULL );
	}
}

void icq_set_status_na( GtkWidget *widget, struct sokandlb *data )
{
	ProgressData *pdata = NULL;

#ifdef TRACE_FUNCTION
	printf( "icq_set_status_na\n" );
#endif

	if( Current_Status == STATUS_OFFLINE )
	{
		Current_Status = STATUS_NA;
		Done_Login = FALSE;
		data->sok = Connect_Remote( server, remote_port, STDERR );
		udp_gdk_input = gdk_input_add( data->sok, GDK_INPUT_READ, (GdkInputFunction) icq_refresh, data );
		Connected = TRUE;
		connecting = show_wait( "Connecting to Server", pdata );
		gtk_statusbar_push( GTK_STATUSBAR( statusbar ), 1, " Connecting to Server..." );

		Login( data->sok, UIN, &passwd[0], our_ip, our_port );
	}
	else
	{
		icq_change_status( data->sok, STATUS_NA, data );
		change_away_window( NULL, NULL );
	}
}

void icq_set_status_invisible( GtkWidget *widget, struct sokandlb *data )
{
	ProgressData *pdata = NULL;

#ifdef TRACE_FUNCTION
	printf( "icq_set_status_invisible\n" );
#endif

	if( Current_Status == STATUS_OFFLINE )
	{
		Current_Status = STATUS_INVISIBLE;
		Done_Login = FALSE;
		data->sok = Connect_Remote( server, remote_port, STDERR );
		udp_gdk_input = gdk_input_add( data->sok, GDK_INPUT_READ, (GdkInputFunction) icq_refresh, data );
		Connected = TRUE;
		connecting = show_wait( "Connecting to Server", pdata );
		gtk_statusbar_push( GTK_STATUSBAR( statusbar ), 1, " Connecting to Server..." );

		Login( data->sok, UIN, &passwd[0], our_ip, our_port );
	}
	else
	{
		icq_change_status( data->sok, STATUS_INVISIBLE, data );
	}
}

void icq_set_status_ffc( GtkWidget *widget, struct sokandlb *data )
{
	ProgressData *pdata = NULL;

#ifdef TRACE_FUNCTION
	printf( "icq_set_status_ffc\n" );
#endif

	if( Current_Status == STATUS_OFFLINE )
	{
		Current_Status = STATUS_FREE_CHAT;
		Done_Login = FALSE;
		data->sok = Connect_Remote( server, remote_port, STDERR );
		udp_gdk_input = gdk_input_add( data->sok, GDK_INPUT_READ, (GdkInputFunction) icq_refresh, data );
		Connected = TRUE;
		connecting = show_wait( "Connecting to Server", pdata );
		gtk_statusbar_push( GTK_STATUSBAR( statusbar ), 1, " Connecting to Server..." );

		Login( data->sok, UIN, &passwd[0], our_ip, our_port );
	}
	else
	{
		icq_change_status( data->sok, STATUS_FREE_CHAT, data );
	}
}

void icq_set_status_occ( GtkWidget *widget, struct sokandlb *data )
{
	ProgressData *pdata = NULL;

#ifdef TRACE_FUNCTION
	printf( "icq_set_status_occ\n" );
#endif

	if( Current_Status == STATUS_OCCUPIED )
		return;

	if( Current_Status == STATUS_OFFLINE )
	{
		Current_Status = STATUS_OCCUPIED;
		Done_Login = FALSE;
		data->sok = Connect_Remote( server, remote_port, STDERR );
		udp_gdk_input = gdk_input_add( data->sok, GDK_INPUT_READ, (GdkInputFunction) icq_refresh, data );
		Connected = TRUE;
		connecting = show_wait( "Connecting to Server", pdata );
		gtk_statusbar_push( GTK_STATUSBAR( statusbar ), 1, " Connecting to Server..." );

		Login( data->sok, UIN, &passwd[0], our_ip, our_port );
	}
	else
	{
		icq_change_status( data->sok, STATUS_OCCUPIED, data );
		change_away_window( NULL, NULL );
	}
}

void icq_set_status_dnd( GtkWidget *widget, struct sokandlb *data )
{
	ProgressData *pdata = NULL;

#ifdef TRACE_FUNCTION
	printf( "icq_set_status_dnd\n" );
#endif

	if( Current_Status == STATUS_DND )
		return;

	if( Current_Status == STATUS_OFFLINE )
	{
		Current_Status = STATUS_DND;
		Done_Login = FALSE;
		data->sok = Connect_Remote( server, remote_port, STDERR );
		udp_gdk_input = gdk_input_add( data->sok, GDK_INPUT_READ, (GdkInputFunction) icq_refresh, data );
		Connected = TRUE;
		connecting = show_wait( "Connecting to Server", pdata );
		gtk_statusbar_push( GTK_STATUSBAR( statusbar ), 1, " Connecting to Server..." );

		Login( data->sok, UIN, &passwd[0], our_ip, our_port );
	}
	else
	{
		icq_change_status( data->sok, STATUS_DND, data );
		change_away_window( NULL, NULL );
	}
}


GtkWidget *create_menu ( struct sokandlb *data )
{ 
	GtkWidget *item;
	GtkWidget *menu;

#ifdef TRACE_FUNCTION
	printf( "create_menu\n" );
#endif

	menu = gtk_menu_new();

	item = gtk_menu_item_new_with_label ( "Online" );

	gtk_menu_append( GTK_MENU ( menu ), item );
	gtk_widget_show( item );

	gtk_signal_connect(GTK_OBJECT( item ), "activate",
	                   GTK_SIGNAL_FUNC(icq_set_status_online), data );

	item = gtk_menu_item_new_with_label ( "Offline" );

	gtk_menu_append( GTK_MENU ( menu ), item );
	gtk_widget_show( item );

	gtk_signal_connect(GTK_OBJECT( item ), "activate",
	                   GTK_SIGNAL_FUNC(icq_set_status_offline), data );

	item = gtk_menu_item_new_with_label ( "Away" );

	gtk_menu_append( GTK_MENU ( menu ), item );
	gtk_widget_show( item );

	gtk_signal_connect(GTK_OBJECT( item ), "activate",
	                   GTK_SIGNAL_FUNC(icq_set_status_away), data );

	item = gtk_menu_item_new_with_label ( "Not Available" );

	gtk_menu_append( GTK_MENU ( menu ), item );
	gtk_widget_show( item );

	gtk_signal_connect(GTK_OBJECT( item ), "activate",
	                   GTK_SIGNAL_FUNC(icq_set_status_na), data );

	item = gtk_menu_item_new_with_label ( "Free for Chat" );

	gtk_menu_append( GTK_MENU ( menu ), item );
	gtk_widget_show( item );

	gtk_signal_connect(GTK_OBJECT( item ), "activate",
	                   GTK_SIGNAL_FUNC(icq_set_status_ffc), data );

	item = gtk_menu_item_new_with_label ( "Occupied" );

	gtk_menu_append( GTK_MENU ( menu ), item );
	gtk_widget_show( item );

	gtk_signal_connect(GTK_OBJECT( item ), "activate",
	                   GTK_SIGNAL_FUNC(icq_set_status_occ), data );

	item = gtk_menu_item_new_with_label ( "Do Not Disturb" );

	gtk_menu_append( GTK_MENU ( menu ), item );
	gtk_widget_show( item );

	gtk_signal_connect(GTK_OBJECT( item ), "activate",
	                   GTK_SIGNAL_FUNC(icq_set_status_dnd), data );

	item = gtk_menu_item_new_with_label ( "Invisible" );

	gtk_menu_append( GTK_MENU ( menu ), item );
	gtk_widget_show( item );

	gtk_signal_connect(GTK_OBJECT( item ), "activate",
	                   GTK_SIGNAL_FUNC(icq_set_status_invisible), data );

	return menu;
}

void icq_sendmessage( GtkWidget *button, struct sokandlb *data )
{
	char buf[1024];
	gchar *nick;
	GtkWidget *entry;
	gpointer forced;

#ifdef TRACE_FUNCTION
	printf( "icq_sendmessage\n" );
#endif

	nick = gtk_object_get_data( GTK_OBJECT( button ), "nick" );
	entry = gtk_object_get_data( GTK_OBJECT( button ), "text" );
	forced = gtk_object_get_data( GTK_OBJECT( button ), "force" );

	strncpy( buf, gtk_editable_get_chars( GTK_EDITABLE( entry ),
			                                     0, -1 ), 1023 );
	icq_sendmsg( data->sok, nick2uin( nick ), buf, data,
	             ( forced == NULL ? 0 : 1 ) );
}

#if 0
void icq_sysmessage_window( GtkWidget *clist, GdkEventButton *event, struct sokandlb *data )
{
	int row, column;
	char buf[64];

	int cx;

#ifdef TRACE_FUNCTION
	printf( "icq_sysmessage_window\n" );
#endif

	if( event == NULL )
		return;

	if( event->type != GDK_2BUTTON_PRESS && event->button == 1 )
		return;

	if( event->button != 1 )
		return;

	gtk_clist_get_selection_info( GTK_CLIST( clist ), event->x, event->y,
	                              &row, &column );

	gtk_clist_unselect_row( GTK_CLIST( clist ), row, column );

	if( system_messages )
	{
		sprintf( buf, "Message from System:" );
		icq_msgbox( system_message[ 0 ], buf, data );
		system_messages --;
		free( system_message[ 0 ] );
		for( cx = 0; cx < system_messages; cx ++ )
			system_message[ cx ] = system_message[ cx + 1 ];
		system_message[ system_messages ] = NULL;
		if( system_messages == 0 )
		{
			gtk_clist_set_pixmap( GTK_CLIST( data->lb_syswin ), 0, 0,
			                      icon_online_pixmap,
			                      icon_online_bitmap );
		}
		return;
	}
}
#endif

gint icq_sendmessage_window( GtkWidget *clist, GdkEventButton *event, struct sokandlb *data )
{
	int row, column;
	GtkWidget *window;
	GtkWidget *message;
	GtkWidget *mainbox;
	GtkWidget *button;
	GtkWidget *text;
	GtkWidget *table;
	GtkWidget *box;
	GtkWidget *scrollbar;
	GtkWidget *cancel;
	GtkWidget *force_button;
	char buf[64];

	int cx, cy, t;
	int cindex;

	char label_str[64];
	gchar *nick;

	int key_select = FALSE;

#ifdef TRACE_FUNCTION
	printf( "icq_sendmessage_window\n" );
#endif

	if( event == NULL )
		return FALSE;

/*
	if( event->type == GDK_KEY_PRESS )
	{
 		if( ((GdkEventKey*)event)->keyval != GDK_Return && ((GdkEventKey*)event)->keyval != ' ' )
			return FALSE;
		key_select = TRUE;
	}
*/
	gtk_clist_get_selection_info( GTK_CLIST( clist ), event->x, event->y,
	                              &row, &column );

	if( !GTK_IS_SCROLLBAR( clist ) )
		gtk_clist_select_row( GTK_CLIST( clist ), row, column );

	if( key_select == FALSE )
	{
		if(  event->type != GDK_2BUTTON_PRESS && event->button == 1 )
			return FALSE;

		if( event->type != GDK_BUTTON_PRESS && event->button == 3 )
			return FALSE;

		if( event->button == 2 )
			return FALSE;
	}

	nick = gtk_clist_get_row_data( GTK_CLIST( clist ), row );

	if( nick == NULL )
		return FALSE;

	/* This is VERY BAD, because if you have two people with the same
	   nick, you'll send the message to the first on the list - BAD! */

	for( cx = 0; cx < Num_Contacts; cx ++ )
	{
		if( !strcmp( Contacts[ cx ].nick, nick ) )
			break;
	}

	cindex = cx;

	if( event->button == 3 )
	{
	
		if( cx == Num_Contacts )
		{
			g_print( "Nick %s not found\n", nick );
		}
		else
		{
			GtkWidget *personal_menu;
			GdkEventButton *bevent = (GdkEventButton *) event;

			GtkWidget *pm, *item_box, *item_label;
			GtkWidget *item;
			personal_menu = gtk_menu_new();

			item_box = gtk_hbox_new( FALSE, 0 );
			pm = gtk_pixmap_new( icon_message_pixmap, icon_message_bitmap );
			gtk_box_pack_start( GTK_BOX( item_box ), pm, FALSE, FALSE, 0 );
			gtk_widget_show( pm );
			item = gtk_menu_item_new();
			item_label = gtk_label_new( "  Send Message..." );
			gtk_box_pack_start( GTK_BOX( item_box ), item_label, FALSE, FALSE, 0 );
			gtk_widget_show( item_label );
			gtk_container_add( GTK_CONTAINER( item ), item_box );
			gtk_widget_show( item_box );
			gtk_menu_append( GTK_MENU( personal_menu ), item );
			gtk_signal_connect( GTK_OBJECT( item ), "activate",
			                    GTK_SIGNAL_FUNC( icq_sendmessage_window_from_menu ),
			                    data );
			gtk_widget_show( item );

			item_box = gtk_hbox_new( FALSE, 0 );
			pm = gtk_pixmap_new( icon_url_pixmap, icon_url_bitmap );
			gtk_box_pack_start( GTK_BOX( item_box ), pm, FALSE, FALSE, 0 );
			gtk_widget_show( pm );
			item = gtk_menu_item_new();
			item_label = gtk_label_new( "  Send URL..." );
			gtk_box_pack_start( GTK_BOX( item_box ), item_label, FALSE, FALSE, 0 );
			gtk_widget_show( item_label );
			gtk_container_add( GTK_CONTAINER( item ), item_box );
			gtk_widget_show( item_box );
			gtk_menu_append( GTK_MENU( personal_menu ), item );
			gtk_signal_connect( GTK_OBJECT( item ), "activate",
			                    GTK_SIGNAL_FUNC( send_url_window ),
			                    data );
			gtk_widget_show( item );

			item_box = gtk_hbox_new( FALSE, 0 );
			pm = gtk_pixmap_new( icon_chat_pixmap, icon_chat_bitmap );
			gtk_box_pack_start( GTK_BOX( item_box ), pm, FALSE, FALSE, 0 );
			gtk_widget_show( pm );
			item = gtk_menu_item_new();
			item_label = gtk_label_new( "  Send Chat Request..." );
			gtk_box_pack_start( GTK_BOX( item_box ), item_label, FALSE, FALSE, 0 );
			gtk_widget_show( item_label );
			gtk_container_add( GTK_CONTAINER( item ), item_box );
			gtk_widget_show( item_box );
			gtk_menu_append( GTK_MENU( personal_menu ), item );
			gtk_signal_connect( GTK_OBJECT( item ), "activate",
			                    GTK_SIGNAL_FUNC( request_chat ),
			                    data );
			gtk_widget_show( item );

			item = gtk_menu_item_new();
			gtk_menu_append( GTK_MENU( personal_menu ), item );
			gtk_widget_show( item );

			item = gtk_menu_item_new_with_label( "User Info" );
			gtk_menu_append( GTK_MENU( personal_menu ), item );
			gtk_signal_connect( GTK_OBJECT( item ), "activate",
			                    GTK_SIGNAL_FUNC( show_personal_info ), data );
			gtk_widget_show( item );

			item = gtk_menu_item_new_with_label( "Read Away Message" );
			gtk_menu_append( GTK_MENU( personal_menu ), item );
			gtk_signal_connect( GTK_OBJECT( item ), "activate",
			                    GTK_SIGNAL_FUNC( retrieve_away_message ), data );
			gtk_widget_show( item );

			item = gtk_menu_item_new_with_label( "Message History" );
			gtk_menu_append( GTK_MENU( personal_menu ), item );
			gtk_signal_connect( GTK_OBJECT( item ), "activate",
			                    GTK_SIGNAL_FUNC( display_mess_history ), data );
			gtk_widget_show( item );

			item = gtk_menu_item_new();
			gtk_menu_append( GTK_MENU( personal_menu ), item );
			gtk_widget_show( item );

			item = gtk_menu_item_new_with_label( "Add to Invisible List" );
			gtk_menu_append( GTK_MENU( personal_menu ), item );
			gtk_signal_connect( GTK_OBJECT( item ), "activate",
			                    GTK_SIGNAL_FUNC( add_to_inv_list ), data );
			if( Contacts[ cx ].invis_list )
				gtk_widget_set_sensitive( item, FALSE );
			gtk_widget_show( item );

			item = gtk_menu_item_new_with_label( "Remove from Invisible List" );
			gtk_menu_append( GTK_MENU( personal_menu ), item );
			gtk_signal_connect( GTK_OBJECT( item ), "activate",
			                    GTK_SIGNAL_FUNC( remove_from_inv_list ), data );
			if( !Contacts[ cx ].invis_list )
				gtk_widget_set_sensitive( item, FALSE );
			gtk_widget_show( item );

			item = gtk_menu_item_new();
			gtk_menu_append( GTK_MENU( personal_menu ), item );
			gtk_widget_show( item );

			item = gtk_menu_item_new_with_label( "Add to Visible List" );
			gtk_menu_append( GTK_MENU( personal_menu ), item );
			gtk_signal_connect( GTK_OBJECT( item ), "activate",
			                    GTK_SIGNAL_FUNC( add_to_vis_list ), data );
			if( Contacts[ cx ].vis_list )
				gtk_widget_set_sensitive( item, FALSE );
			gtk_widget_show( item );

			item = gtk_menu_item_new_with_label( "Remove from Visible List" );
			gtk_menu_append( GTK_MENU( personal_menu ), item );
			gtk_signal_connect( GTK_OBJECT( item ), "activate",
			                    GTK_SIGNAL_FUNC( remove_from_vis_list ), data );
			if( !Contacts[ cx ].vis_list )
				gtk_widget_set_sensitive( item, FALSE );
			gtk_widget_show( item );

			item = gtk_menu_item_new();
			gtk_menu_append( GTK_MENU( personal_menu ), item );
			gtk_widget_show( item );

			item = gtk_menu_item_new_with_label( "Rename User" );
			gtk_menu_append( GTK_MENU( personal_menu ), item );
			gtk_signal_connect( GTK_OBJECT( item ), "activate",
			                    GTK_SIGNAL_FUNC( change_nick_window ), data );
			gtk_widget_show( item );

			item = gtk_menu_item_new_with_label( "Remove User" );
			gtk_menu_append( GTK_MENU( personal_menu ), item );
			gtk_signal_connect( GTK_OBJECT( item ), "activate",
			                    GTK_SIGNAL_FUNC( remove_user ),
			                    data );
			gtk_widget_show( item );

			item = gtk_menu_item_new();
			gtk_menu_append( GTK_MENU( personal_menu ), item );
			gtk_widget_show( item );

			t = Contacts[ cx ].current_ip;
			if( t != 0xffffffff )
				sprintf( label_str, "IP: %u.%u.%u.%u",(BYTE) (t>>24),(BYTE) (t>>16),(BYTE) (t>>8),(BYTE) (t) );
			else
				sprintf( label_str, "IP: N/A" );
			item = gtk_menu_item_new_with_label( label_str );
			gtk_menu_append( GTK_MENU( personal_menu ), item );
			gtk_widget_set_sensitive( item, FALSE );
			gtk_widget_show( item );

			sprintf( label_str, "Port: %ld", Contacts[ cx ].port );
			item = gtk_menu_item_new_with_label( label_str );
			gtk_menu_append( GTK_MENU( personal_menu ), item );
			gtk_widget_set_sensitive( item, FALSE );
			gtk_widget_show( item );

			sprintf( label_str, "Status: 0x%04X", (unsigned int)Contacts[ cx ].status );
			item = gtk_menu_item_new_with_label( label_str );
			gtk_menu_append( GTK_MENU( personal_menu ), item );
			gtk_widget_set_sensitive( item, FALSE );
			gtk_widget_show( item );

			sprintf( label_str, "True Status: 0x%04X", (unsigned int)Contacts[ cx ].true_status );
			item = gtk_menu_item_new_with_label( label_str );
			gtk_menu_append( GTK_MENU( personal_menu ), item );
			gtk_widget_set_sensitive( item, FALSE );
			gtk_widget_show( item );

			gtk_menu_popup( GTK_MENU( personal_menu ), NULL, NULL, NULL, NULL,
			                bevent->button, bevent->time );
		}
		return FALSE;
	}


	if( Contacts[ cx ].messages )
	{
		sprintf( buf, "Message from %s:", nick );
		icq_msgbox( Contacts[ cx ].message[ 0 ], buf, data );
		free( Contacts[ cx ].message[ 0 ] );
		for( cy = 0; cy < Contacts[ cx ].messages; cy ++ )
			Contacts[ cx ].message[ cy ] = Contacts[ cx ].message[ cy + 1 ];
		Contacts[ cx ].message[ Contacts[ cx ].messages ] = NULL;
		if( Contacts[ cx ].messages == 0 )
		{
			Contacts[ cx ].icon_p = GetIcon_p( Contacts[ cx ].status );
			Contacts[ cx ].icon_b = GetIcon_b( Contacts[ cx ].status );
			Contacts[ cx ].need_update = 1;
		}
	
		Show_Quick_Status( data );
		return FALSE;
	}

	sprintf(label_str, "Send Message to: %s", nick );

	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

	gtk_container_border_width( GTK_CONTAINER(window), 10 );
	gtk_window_set_title(GTK_WINDOW(window), "GtkICQ: Send Message");
	gtk_widget_set_usize( window, 450, 230 );

	mainbox = gtk_vbox_new( FALSE, 0 );
	gtk_container_add( GTK_CONTAINER( window ), mainbox );
	gtk_widget_show( mainbox );

	message = gtk_label_new( label_str );

	gtk_box_pack_start( GTK_BOX( mainbox ), message, TRUE, TRUE, 0 );
	gtk_widget_show( message );

	table = gtk_table_new(3, 2, FALSE);
	gtk_box_pack_start( GTK_BOX( mainbox ), table, TRUE, TRUE, 0);
	
	text = gtk_text_new( NULL, NULL );
	gtk_text_set_word_wrap( GTK_TEXT( text ), TRUE );
	gtk_table_attach( GTK_TABLE( table ), text, 0, 1, 0, 1,
	                  GTK_EXPAND | GTK_SHRINK | GTK_FILL,
	                  GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 5 );

	gtk_text_set_editable( GTK_TEXT( text ), TRUE );

	scrollbar = gtk_vscrollbar_new( GTK_TEXT( text )->vadj );
	gtk_table_attach( GTK_TABLE( table ), scrollbar, 1, 2, 0, 1,
	                  GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 5 );
	gtk_widget_show( scrollbar );

	gtk_widget_show( text );
	gtk_widget_show( table );
	gtk_widget_show( window );

	gtk_widget_grab_focus( text );

	box = gtk_hbutton_box_new();
	gtk_button_box_set_layout(GTK_BUTTON_BOX( box ),
	                          GTK_BUTTONBOX_SPREAD);
	button = gtk_button_new_with_label( "Send" );
	gtk_widget_set_usize(button, 35, 25);
	gtk_container_add(GTK_CONTAINER( box ), button);
	force_button = gtk_button_new_with_label( "Via Server" );
	gtk_widget_set_usize( force_button, 75, 25 );
	gtk_container_add( GTK_CONTAINER( box ), force_button );
	cancel = gtk_button_new_with_label( "Cancel" );
	gtk_widget_set_usize( cancel, 35, 25 );
	gtk_container_add( GTK_CONTAINER( box ), cancel );
	gtk_signal_connect_object( GTK_OBJECT( cancel ), "clicked",
	                    (GtkSignalFunc) gtk_widget_destroy,
	                    GTK_OBJECT( window ) );
	gtk_widget_show( cancel );
	gtk_table_attach(GTK_TABLE(table), box,
	                 0, 1, 1, 2, GTK_FILL, 0, 0, 0);
	gtk_object_set_data( GTK_OBJECT( button ), "nick", Contacts[ cindex ].nick );
	gtk_object_set_data( GTK_OBJECT( button ), "text", text );
	gtk_object_set_data( GTK_OBJECT( button ), "force", NULL );
	gtk_signal_connect( GTK_OBJECT( button ), "clicked",
	                    GTK_SIGNAL_FUNC( icq_sendmessage ), data );
	gtk_signal_connect_object(GTK_OBJECT (button), "clicked",
	                          (GtkSignalFunc) gtk_widget_destroy, 
                             GTK_OBJECT(window));
	gtk_widget_show(button);
	gtk_object_set_data( GTK_OBJECT( force_button ), "nick", Contacts[ cindex ].nick );
	gtk_object_set_data( GTK_OBJECT( force_button ), "text", text );
	gtk_object_set_data( GTK_OBJECT( force_button ), "force", "1" );
	gtk_signal_connect( GTK_OBJECT( force_button ), "clicked",
	                    GTK_SIGNAL_FUNC( icq_sendmessage ), data );
	gtk_signal_connect_object(GTK_OBJECT ( force_button ), "clicked",
	                          (GtkSignalFunc) gtk_widget_destroy, 
                             GTK_OBJECT(window));
	gtk_widget_show( force_button );
	gtk_widget_show( box );

	return FALSE;
}

void icq_sendmessage_window_from_menu( GtkWidget *widget, struct sokandlb *data )
{
	GtkWidget *window;
	GtkWidget *message;
	GtkWidget *mainbox;
	GtkWidget *button;
	GtkWidget *force_button;
	static GtkWidget *text;
	GtkWidget *table;
	GtkWidget *box;
	GtkWidget *scrollbar;
	GtkWidget *cancel;
	GtkCList *clist = GTK_CLIST( data->lb_userwin );

	int cx;

	char label_str[64];

#ifdef TRACE_FUNCTION
	printf( "icq_sendmessage_window_from_menu\n" );
#endif

	for( cx = 0; cx < Num_Contacts; cx ++ )
	{
		if( GPOINTER_TO_INT( clist->selection->data ) ==
		    Contacts[ cx ].lb_index )
			break;
	}

	sprintf(label_str, "Send Message to: %s", Contacts[ cx ].nick );

	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

	gtk_container_border_width( GTK_CONTAINER(window), 10 );
	gtk_window_set_title(GTK_WINDOW(window), "GtkICQ: Send Message");
	gtk_widget_set_usize( window, 450, 230 );

	mainbox = gtk_vbox_new( FALSE, 0 );
	gtk_container_add( GTK_CONTAINER( window ), mainbox );
	gtk_widget_show( mainbox );

	message = gtk_label_new( label_str );

	gtk_box_pack_start( GTK_BOX( mainbox ), message, TRUE, TRUE, 0 );
	gtk_widget_show( message );

	table = gtk_table_new(3, 2, FALSE);
	gtk_box_pack_start( GTK_BOX( mainbox ), table, TRUE, TRUE, 0);
	
	text = gtk_text_new( NULL, NULL );
	gtk_text_set_word_wrap( GTK_TEXT( text ), TRUE );
	gtk_table_attach( GTK_TABLE( table ), text, 0, 1, 0, 1,
	                  GTK_EXPAND | GTK_SHRINK | GTK_FILL,
	                  GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 5 );

	gtk_text_set_editable( GTK_TEXT( text ), TRUE );

	scrollbar = gtk_vscrollbar_new( GTK_TEXT( text )->vadj );
	gtk_table_attach( GTK_TABLE( table ), scrollbar, 1, 2, 0, 1,
	                  GTK_FILL, GTK_EXPAND | GTK_SHRINK | GTK_FILL, 0, 5 );
	gtk_widget_show( scrollbar );

	gtk_widget_show( text );
	gtk_widget_show( table );
	gtk_widget_show( window );

	box = gtk_hbutton_box_new();
	gtk_button_box_set_layout(GTK_BUTTON_BOX( box ),
	                          GTK_BUTTONBOX_SPREAD);
	button = gtk_button_new_with_label( "Send" );
	gtk_widget_set_usize(button, 35, 25);
	gtk_container_add(GTK_CONTAINER( box ), button);
	force_button = gtk_button_new_with_label( "Via Server" );
	gtk_widget_set_usize( force_button, 75, 25 );
	gtk_container_add( GTK_CONTAINER( box ), force_button );
	cancel = gtk_button_new_with_label( "Cancel" );
	gtk_widget_set_usize( cancel, 35, 25 );
	gtk_container_add( GTK_CONTAINER( box ), cancel );
	gtk_signal_connect_object( GTK_OBJECT( cancel ), "clicked",
	                    (GtkSignalFunc) gtk_widget_destroy,
	                    GTK_OBJECT( window ) );
	gtk_widget_show( cancel );
	gtk_table_attach(GTK_TABLE(table), box,
	                 0, 1, 1, 2, GTK_FILL, 0, 0, 0);
	gtk_object_set_data( GTK_OBJECT( button ), "nick", Contacts[ cx ].nick );
	gtk_object_set_data( GTK_OBJECT( button ), "text", text );
	gtk_signal_connect( GTK_OBJECT( button ), "clicked",
	                    GTK_SIGNAL_FUNC( icq_sendmessage ), data );
	gtk_signal_connect_object(GTK_OBJECT (button), "clicked",
	                          (GtkSignalFunc) gtk_widget_destroy, 
                             GTK_OBJECT(window));
	gtk_widget_show(button);
	gtk_object_set_data( GTK_OBJECT( force_button ), "nick", Contacts[ cx ].nick );
	gtk_object_set_data( GTK_OBJECT( force_button ), "text", text );
	gtk_object_set_data( GTK_OBJECT( force_button ), "force", "1" );
	gtk_signal_connect( GTK_OBJECT( force_button ), "clicked",
	                    GTK_SIGNAL_FUNC( icq_sendmessage ), data );
	gtk_signal_connect_object(GTK_OBJECT ( force_button ), "clicked",
	                          (GtkSignalFunc) gtk_widget_destroy, 
                             GTK_OBJECT(window));
	gtk_widget_show( force_button );
	gtk_widget_show( box );

	return;
}

int stay_connected( struct sokandlb *data )
{
#ifdef TRACE_FUNCTION
	printf( "stay_connected\n" );
#endif

	Keep_Alive( data->sok );
	return TRUE;
}

void read_next( GtkWidget *widget, struct sokandlb *data )
{
	GtkWidget *text;
	char buf[100];

	int i, cx, cy, cz;

	gchar *nick;

	GdkColor black = { 0, 0, 0, 0 };

#ifdef TRACE_FUNCTION
	printf( "read_next\n" );
#endif

	nick = gtk_object_get_data( GTK_OBJECT( widget ), "nick" );
	text = gtk_object_get_data( GTK_OBJECT( widget ), "text" );

	gdk_color_alloc( gtk_widget_get_colormap( text ), &black );

	if( nick == NULL )
		return;

	for( i = 0; i < Num_Contacts; i ++ )
	{
		if( !strcmp( Contacts[ i ].nick, nick ) )
			break;
	}

	if( Contacts[ i ].messages > 0 )
	{
		sprintf( buf, "Message from %s:", nick );
		gtk_text_set_point( GTK_TEXT( text ), 0 );
		gtk_text_forward_delete( GTK_TEXT( text ),
		                         gtk_text_get_length( GTK_TEXT( text ) ) );

		strcpy( buf, "" );
		cy = 0;
		cz = 1;
		for( cx = 1; cx < strlen( Contacts[ i ].message[ 0 ] ); cx ++ )
		{
			cy ++;
			if( Contacts[ i ].message[ 0 ][ cx ] == '\n' || cy == 70 ||
			    ( cy >= 60 && Contacts[ i ].message[ 0 ][ cx ] == ' ' ) )
			{
				gtk_text_insert( GTK_TEXT( text ), NULL, &black, NULL,
				                 ( Contacts[ i ].message[ 0 ] + cz ), cy );
				if( cy >= 60 && cy != 70 )
				{
					gtk_text_insert( GTK_TEXT( text ), NULL, &black, NULL,
					                 "\n", 1 );
				}
				if( cy == 70 )
				{
					gtk_text_insert( GTK_TEXT( text ), NULL, &black, NULL,
					                 "-\n", 2 );
				}
				cz += cy;
				cy = 0;
			}
		}
		
		if( cz != strlen( Contacts[ i ].message[ 0 ] ) )
		{
			gtk_text_insert( GTK_TEXT( text ), NULL, &black, NULL,
			                 ( Contacts[ i ].message[ 0 ] + cz ),
			                 strlen( Contacts[ i ].message[ 0 ] ) - cz );
		}

		if( Contacts[ i ].messages <= 1 ||
		    ( Contacts[ i ].messages && Contacts[ i ].message[ 1 ][ 0 ] == 'c' ) )
			gtk_widget_set_sensitive( Contacts[ i ].read_next, FALSE );

		free( Contacts[ i ].message[ 0 ] );
		for( cy = 0; cy < Contacts[ i ].messages; cy ++ )
			Contacts[ i ].message[ cy ] = Contacts[ i ].message[ cy + 1 ];
		Contacts[ i ].message[ Contacts[ i ].messages ] = NULL;
		Contacts[ i ].messages --;
		if( Contacts[ i ].messages == 0 )
		{
			Contacts[ i ].icon_p = GetIcon_p( Contacts[ i ].status );
			Contacts[ i ].icon_b = GetIcon_b( Contacts[ i ].status );
			Contacts[ i ].need_update = 1;
		}
		Show_Quick_Status( data );
	}

	return;
}

GtkWidget*
create_about_window (void)
{
  GtkWidget *about_window;
  GtkWidget *dialog_vbox2;
  GtkWidget *pixmap1;
  GtkWidget *about_info;
  GtkWidget *dialog_action_area2;
  GtkWidget *close;
  char *about;

  about_window = gtk_dialog_new ();
  gtk_object_set_data (GTK_OBJECT (about_window), "about_window", about_window);
  gtk_container_set_border_width (GTK_CONTAINER (about_window), 10);
  gtk_window_set_title (GTK_WINDOW (about_window), "About...");
  GTK_WINDOW (about_window)->type = GTK_WINDOW_DIALOG;
  gtk_window_set_position (GTK_WINDOW (about_window), GTK_WIN_POS_CENTER);
  gtk_window_set_modal (GTK_WINDOW (about_window), TRUE);
  gtk_window_set_policy (GTK_WINDOW (about_window), FALSE, FALSE, FALSE);

  dialog_vbox2 = GTK_DIALOG (about_window)->vbox;
  gtk_object_set_data (GTK_OBJECT (about_window), "dialog_vbox2", dialog_vbox2);
  gtk_widget_show (dialog_vbox2);
  pixmap1  = gtk_pixmap_new( gtkicq_logo_pixmap, NULL );
  gtk_widget_ref (pixmap1);
  gtk_object_set_data_full (GTK_OBJECT (about_window), "pixmap1", pixmap1,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (pixmap1);
  gtk_box_pack_start (GTK_BOX (dialog_vbox2), pixmap1, TRUE, FALSE, 0);
  gtk_misc_set_alignment (GTK_MISC (pixmap1), 0.61, 0.5);
  gtk_misc_set_padding (GTK_MISC (pixmap1), 17, 0);

	about = (char *)malloc(512);
  	sprintf(about, "Version %s\nhttp://gtkicq.pn.org\n\nGtkICQ is a GUI written in C,\nusing the GTK library wrapped around\nthe original code from Matt Smith's mICQ.\n\nJeremy Wise <jwise@pathwaynet.com>\nJordan Nelson <jordan@pathwaynet.com>\nProject Leader: Ryan Azcueta Krenzischek <rkrenzis@ureach.com>", VERSION);
	about_info = gtk_label_new( about );

  	gtk_widget_ref (about_info);
  	gtk_object_set_data_full (GTK_OBJECT (about_window), "about_info", about_info,
                            (GtkDestroyNotify) gtk_widget_unref);
  	gtk_widget_show (about_info);
  	gtk_box_pack_start (GTK_BOX (dialog_vbox2), about_info, FALSE, FALSE, 0);
  	gtk_label_set_justify (GTK_LABEL (about_info), GTK_JUSTIFY_FILL);
  	gtk_misc_set_padding (GTK_MISC (about_info), 0, 5);


  dialog_action_area2 = GTK_DIALOG (about_window)->action_area;
  gtk_object_set_data (GTK_OBJECT (about_window), "dialog_action_area2", dialog_action_area2);
  gtk_widget_show (dialog_action_area2);
  gtk_container_set_border_width (GTK_CONTAINER (dialog_action_area2), 10);

  close = gtk_button_new_with_label ("Close");
  gtk_widget_ref (close);
  gtk_object_set_data_full (GTK_OBJECT (about_window), "close", close,
                            (GtkDestroyNotify) gtk_widget_unref);
  gtk_widget_show (close);
  gtk_box_pack_start (GTK_BOX (dialog_action_area2), close, FALSE, FALSE, 0);

  gtk_signal_connect_object_after (GTK_OBJECT (close), "button_release_event",
                                   GTK_SIGNAL_FUNC (gtk_widget_destroy),
                                   GTK_OBJECT (about_window));

  gtk_widget_show (about_window);

	return about_window;
}
