/*
 *	This file was originally part of Matt Smith's
 *	mICQ, and is now included in GTK-ICQ.  Below
 *	are the original authors and contributors:
 *	
 *	Original Author:
 *		Matthew Smith		04/23/1998
 *
 *	Contributors:
 *
 *		Nicolas Sahlqvist	04/27/1998
 *		Michael Ivey		05/04/1998
 *		Michael Holzt		05/05/1998
 *		Ulf Hedlund
 */

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

#include "gtkicq.h"
#include "datatype.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netdb.h>

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

#include <gtk/gtk.h>
#include "gtkfunc.h"

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

#include "pixmaps.h"

#define UIN_DELIMS ":|/" /* add space if you don't want your nick names to have spaces */

int Show_Quick_Status( struct sokandlb *data )
{
	char statusbuf_editable[2][32];
	char *statusbuf[2];

	static GdkColor *white = NULL;
	static GdkColor *black = NULL;
	static GdkColor *blue = NULL;
	static GdkColor *green = NULL;

	static GtkStyle *style = NULL;

	static int preshown = 0;

#ifdef SOUND
	#define PlayOnline 1
	#define PlayOffline 2
	int play_sound = FALSE;
#endif

	int i;
	int j;
	int row;

	int message_clear;

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

	statusbuf[0] = statusbuf_editable[0];
	statusbuf[1] = statusbuf_editable[1];

	if( black == NULL )
		black = (GdkColor *)malloc( sizeof( GdkColor ) );
	if( white == NULL )
		white = (GdkColor *)malloc( sizeof( GdkColor ) );
	if( blue == NULL )
		blue = (GdkColor *)malloc( sizeof( GdkColor ) );
	if( green == NULL )
		green = (GdkColor *)malloc( sizeof( GdkColor ) );

	white->red = 65535;
	white->green = 65535;
	white->blue = 65535;
	white->pixel = (gulong)(255*65536 + 255*256 + 255);

	black->red = 0;
	black->green = 0;
	black->blue = 0;
	black->pixel = (gulong)0;

	blue->red = 0;
	blue->green = 0;
	blue->blue = 65535;
	blue->pixel = 255;

	green->red = 0;
	green->green = 65535;
	green->blue = 0;
	green->pixel = 255*256;

	gdk_color_alloc( gtk_widget_get_colormap( data->lb_userwin ), black );
	gdk_color_alloc( gtk_widget_get_colormap( data->lb_userwin ), white );
	gdk_color_alloc( gtk_widget_get_colormap( data->lb_userwin ), blue );
	gdk_color_alloc( gtk_widget_get_colormap( data->lb_userwin ), green );

	gtk_clist_freeze( GTK_CLIST( data->lb_userwin ) );

	if( style == NULL )
	{
		style = gtk_style_new();
		style->fg[GTK_STATE_PRELIGHT] = *black;
		memcpy( &style->bg[GTK_STATE_PRELIGHT],
		        &data->lb_userwin->style->bg[GTK_STATE_PRELIGHT],
		        sizeof( GdkColor ) );

		gdk_font_unref( style->font );
		style->font = gdk_font_load( "-adobe-helvetica-bold-r-*-*-*-140-*-*-*-*-*-*");
	}

	if( !preshown )
	{
		strcpy( statusbuf_editable[0], "" );
		strcpy( statusbuf_editable[1], "Online" );
		gtk_clist_insert( GTK_CLIST( data->lb_userwin ), 0,
		                  statusbuf );
		gtk_clist_set_row_style( GTK_CLIST( data->lb_userwin ), 0, style );
		gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
		                          0, black );
		gtk_clist_set_background( GTK_CLIST( data->lb_userwin ),
		                          0,
		                          &( gtk_clist_get_row_style(
		                             GTK_CLIST( data->lb_userwin ),
		                             0 ) )->bg[ GTK_STATE_PRELIGHT ] );
	}

#ifdef SOUND
	play_sound = FALSE;
#endif

	for ( i=0; i< Num_Contacts; i++ )
	{
		if ( ( S_DWORD )Contacts[ i ].uin > 0 )
		{
			if( Contacts[ i ].status == STATUS_OCCUPIED_MAC )
				Contacts[ i ].status = STATUS_OCCUPIED;
			if( Contacts[ i ].status == STATUS_NA_99A )
				Contacts[ i ].status = STATUS_NA;

			message_clear = 0;
			if ( ( Contacts[ i ].status ) != STATUS_OFFLINE )
			{
				if( Contacts[ i ].icon_p != icon_message_pixmap && Contacts[ i ].messages == 0 )
				{
					message_clear = 0;
				}

				if( Contacts[ i ].icon_p == icon_message_pixmap || Contacts[ i ].messages == 0 )
				{
					Contacts[ i ].icon_p = GetIcon_p( Contacts[ i ].status );
					Contacts[ i ].icon_b = GetIcon_b( Contacts[ i ].status );
				}
				sprintf( statusbuf_editable[0], "%s", "" );
				sprintf( statusbuf_editable[1], "%s", Contacts[ i ].nick );

				if( !preshown )
				{
					row = gtk_clist_append( GTK_CLIST( data->lb_userwin ),
					                        statusbuf );
					gtk_clist_set_row_data( GTK_CLIST( data->lb_userwin ),
					                        row, Contacts[ i ].nick );
					gtk_clist_set_pixmap( GTK_CLIST( data->lb_userwin ), row, 0,
					                      Contacts[ i ].icon_p, Contacts[ i ].icon_b );
					data->online ++;
					Contacts[ i ].lb_index = data->online;
				}
				else if( ( Contacts[ i ].last_status ) != ( Contacts[ i ].status ) ||
				         Contacts[ i ].icon_p == icon_message_pixmap ||
				         Contacts[ i ].need_update )
				{
					Contacts[ i ].need_update = 0;
					if( ( Contacts[ i ].last_status ) == STATUS_OFFLINE )
					{
						gtk_clist_remove( GTK_CLIST( data->lb_userwin ),
						                  Contacts[ i ].lb_index );
						data->offline --;
						gtk_clist_insert( GTK_CLIST( data->lb_userwin ),
						                  1 + data->online, statusbuf);
						gtk_clist_set_row_data( GTK_CLIST( data->lb_userwin ),
		   				                     1 + data->online, Contacts[ i ].nick );
						gtk_clist_set_pixmap( GTK_CLIST( data->lb_userwin ),
						                      1 + data->online, 0,
						                      Contacts[ i ].icon_p, Contacts[ i ].icon_b );

						if( ( Contacts[ i ].status & 0xffff ) == STATUS_ONLINE )
						{
							gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
							                          1 + data->online, &color_online );
						}
						else if( ( Contacts[ i ].status & 0xffff ) == STATUS_FREE_CHAT )
						{
							gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
							                          1 + data->online, &color_ffc );
						}
						else if( ( Contacts[ i ].status & 0xffff ) == STATUS_AWAY )
						{
							gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
							                          1 + data->online, &color_away );
						}
						else if( ( Contacts[ i ].status & 0xffff ) == STATUS_NA )
						{
							gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
							                          1 + data->online, &color_na );
						}
						else if( ( Contacts[ i ].status & 0xffff ) == STATUS_OCCUPIED )
						{
							gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
							                          1 + data->online, &color_occ );
						}
						else if( ( Contacts[ i ].status & 0xffff ) == STATUS_DND )
						{
							gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
							                          1 + data->online, &color_dnd );
						}
						else
						{
							gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
										  1 + data->online, black );
						}
						if( ( Contacts[ i ].true_status & 0x0100 ) == STATUS_INVISIBLE )
						{
							gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
							                          1 + data->online, &color_inv );
						}

						for( j = 0; j < Num_Contacts; j ++ )
						{
							if( i != j && Contacts[ j ].lb_index >= 1 + data->online && Contacts[ j ].lb_index <= Contacts[ i ].lb_index )
							{
								Contacts[ j ].lb_index ++;
							}
						}
 						Contacts[ i ].lb_index = 1 + data->online;
						data->online ++;
					}
					else
					{
						gtk_clist_set_row_data( GTK_CLIST( data->lb_userwin ),
		   				                     Contacts[ i ].lb_index,
		   				                     Contacts[ i ].nick );
						gtk_clist_set_pixmap( GTK_CLIST( data->lb_userwin ),
						                      Contacts[ i ].lb_index, 0,
						                      Contacts[ i ].icon_p, Contacts[ i ].icon_b );
						gtk_clist_set_text( GTK_CLIST( data->lb_userwin ),
						                    Contacts[ i ].lb_index, 1,
						                    statusbuf[ 1 ] );
						if( ( Contacts[ i ].status & 0xffff ) == STATUS_ONLINE )
						{
							gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
							                          Contacts[ i ].lb_index, &color_online );
						}
						else if( ( Contacts[ i ].status & 0xffff ) == STATUS_FREE_CHAT )
						{
							gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
							                          Contacts[ i ].lb_index, &color_ffc );
						}
						else if( ( Contacts[ i ].status & 0xffff ) == STATUS_AWAY )
						{
							gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
							                          Contacts[ i ].lb_index, &color_away );
						}
						else if( ( Contacts[ i ].status & 0xffff ) == STATUS_NA )
						{
							gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
										                 Contacts[ i ].lb_index, &color_na );
						}
						else if( ( Contacts[ i ].status & 0xffff ) == STATUS_OCCUPIED )
						{
							gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
										                 Contacts[ i ].lb_index, &color_occ );
						}
						else if( ( Contacts[ i ].status & 0xffff ) == STATUS_DND )
						{
							gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
										                 Contacts[ i ].lb_index, &color_dnd );
						}
						else if( ( Contacts[ i ].status & 0xffff ) == STATUS_INVISIBLE )
						{
							gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
										                 Contacts[ i ].lb_index, &color_inv );
						}
						else
						{
							gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
										                 Contacts[ i ].lb_index, black );
						}
					}
#ifdef SOUND
					if( ( Contacts[ i ].last_status ) == STATUS_OFFLINE )
					{
						play_sound = PlayOnline;
					}
#endif
				}
				Contacts[ i ].last_status = Contacts[ i ].status;
			}
		}
	}

	if( !preshown )
	{
		strcpy(statusbuf_editable[0], "" );
		strcpy(statusbuf_editable[1], "Offline" );
		row = gtk_clist_append( GTK_CLIST( data->lb_userwin ),
		                        statusbuf );
		
      gtk_clist_set_row_style( GTK_CLIST( data->lb_userwin ), row, style );
  		gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
		                          row, black );
	}

	for ( i = 0; i < Num_Contacts; i ++ )
	{
		if ( ( S_DWORD )Contacts[ i ].uin > 0 )
		{
			message_clear = 0;
			if ( ( Contacts[ i ].status ) == STATUS_OFFLINE )
			{
				if( Contacts[ i ].icon_p != icon_message_pixmap && Contacts[ i ].messages == 0 )
				{
					message_clear = 0;
				}
				if( Contacts[ i ].icon_p == icon_message_pixmap || Contacts[ i ].messages == 0 )
				{
					Contacts[ i ].icon_p = GetIcon_p( Contacts[ i ].status );
					Contacts[ i ].icon_b = GetIcon_b( Contacts[ i ].status );
				}
				sprintf( statusbuf_editable[0], "%s", "" );
				sprintf( statusbuf_editable[1], "%s", Contacts[ i ].nick );
				if( !preshown )
				{
					row = gtk_clist_append( GTK_CLIST( data->lb_userwin ),
					                        statusbuf );
					gtk_clist_set_row_data( GTK_CLIST( data->lb_userwin ), row, Contacts[ i ].nick );
					gtk_clist_set_pixmap( GTK_CLIST( data->lb_userwin ), row, 0,
					                      Contacts[ i ].icon_p, Contacts[ i ].icon_b );

					gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
					                          row, &color_offline );
					data->offline ++;
					Contacts[ i ].lb_index = 1 + data->online + data->offline;
				}
				else if( ( Contacts[ i ].last_status ) != ( Contacts[ i ].status ) ||
				         Contacts[ i ].need_update )
				{
					Contacts[ i ].need_update = 0;
					gtk_clist_remove( GTK_CLIST( data->lb_userwin ),
					                  Contacts[ i ].lb_index );
					for( j = 0; j < Num_Contacts; j ++ )
					{
						if( Contacts[ j ].lb_index > Contacts[ i ].lb_index )
							Contacts[ j ].lb_index --;
					}

					if( ( Contacts[ i ].last_status ) != STATUS_OFFLINE )
					{
						data->online --;
#ifdef SOUND
						play_sound = PlayOffline;
#endif
					}

		         gtk_clist_insert( GTK_CLIST( data->lb_userwin ),
		                           2 + data->online, statusbuf );

					gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
					                          2 + data->online, &color_offline );

					gtk_clist_set_row_data( GTK_CLIST( data->lb_userwin ),
					                        2 + data->online, Contacts[ i ].nick );
					gtk_clist_set_pixmap( GTK_CLIST( data->lb_userwin ),
					                      2 + data->online, 0, Contacts[ i ].icon_p,
					                      Contacts[ i ].icon_b );

					for( j = 0; j < Num_Contacts; j ++ )
					{
						if( i != j && Contacts[ j ].lb_index >= 2 + data->online )
							Contacts[ j ].lb_index ++;
					}

					Contacts[ i ].lb_index = 2 + data->online;
					data->offline ++;
				}
				Contacts[ i ].last_status = STATUS_OFFLINE;
			}
		}
	}

	if( !preshown )
	{
		preshown = 1;
	}

	gtk_clist_thaw( GTK_CLIST( data->lb_userwin ) );

#ifdef SOUND
	return play_sound;
#else
	return TRUE;
#endif
}

int Build_Main_Window( struct sokandlb *data )
{
	char statusbuf_editable[2][32];
	char *statusbuf[2];

	static GdkColor *black;


#ifdef SOUND
	#define PlayOnline 1
	#define PlayOffline 2
#endif

	int i;

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

	statusbuf[0] = statusbuf_editable[0];
	statusbuf[1] = statusbuf_editable[1];

	black = (GdkColor *)malloc(sizeof(GdkColor));

	black->red = 0;
	black->green = 0;
	black->blue = 0;
	black->pixel = (gulong)0;

	gdk_color_alloc( gtk_widget_get_colormap( data->lb_userwin ), black );
	gdk_color_alloc( gtk_widget_get_colormap( data->lb_userwin ), &color_online );
	gdk_color_alloc( gtk_widget_get_colormap( data->lb_userwin ), &color_offline );
	gdk_color_alloc( gtk_widget_get_colormap( data->lb_userwin ), &color_away );
	gdk_color_alloc( gtk_widget_get_colormap( data->lb_userwin ), &color_na );
	gdk_color_alloc( gtk_widget_get_colormap( data->lb_userwin ), &color_ffc );
	gdk_color_alloc( gtk_widget_get_colormap( data->lb_userwin ), &color_occ );
	gdk_color_alloc( gtk_widget_get_colormap( data->lb_userwin ), &color_dnd );
	gdk_color_alloc( gtk_widget_get_colormap( data->lb_userwin ), &color_inv );

	gtk_clist_freeze( GTK_CLIST( data->lb_userwin ) );

	for ( i=1; i< Num_Contacts; i++ )
	{
		if( ( Contacts[ i ].status & 0xffff ) == STATUS_ONLINE )
		{
			gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
			                          Contacts[ i ].lb_index, &color_online );
		}
		else if( ( Contacts[ i ].status & 0xffff ) == STATUS_FREE_CHAT )
		{
			gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
			                          Contacts[ i ].lb_index, &color_ffc );
		}
		else if( ( Contacts[ i ].status & 0xffff ) == STATUS_AWAY )
		{
			gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
			                          Contacts[ i ].lb_index, &color_away );
		}
		else if( ( Contacts[ i ].status & 0xffff ) == STATUS_NA )
		{
			gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
						                 Contacts[ i ].lb_index, &color_na );
		}
		else if( ( Contacts[ i ].status & 0xffff ) == STATUS_OCCUPIED )
		{
			gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
						                 Contacts[ i ].lb_index, &color_occ );
		}
		else if( ( Contacts[ i ].status & 0xffff ) == STATUS_DND )
		{
			gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
						                 Contacts[ i ].lb_index, &color_dnd );
		}
		else if( ( Contacts[ i ].status & 0xffff ) == STATUS_INVISIBLE )
		{
			gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
						                 Contacts[ i ].lb_index, &color_inv );
		}
		else
		{
			gtk_clist_set_foreground( GTK_CLIST( data->lb_userwin ),
						                 Contacts[ i ].lb_index, &color_offline );
		}
	}

	gtk_clist_thaw( GTK_CLIST( data->lb_userwin ) );

	free(black);

	return FALSE;
}
