#include <gtk/gtk.h>
#include "account.h"
#include "service.h"
#include "chat_room.h"
#include "gtkhtml.h"
#include "util.h"
#include "pixmaps/tb_mail_send.xpm"
#include "pixmaps/cancel.xpm"
#include "pixmaps/ok.xpm"

GList * chat_rooms = NULL;

static void send_message( GtkWidget * widget, gpointer data )
{
	eb_chat_room * ecr = data;

	RUN_SERVICE(ecr->chat_room_account)->send_chat_room_message(ecr,
						gtk_entry_get_text(GTK_ENTRY(ecr->entry)));

	gtk_entry_set_text(GTK_ENTRY(ecr->entry), "");
}

static GList * chat_service_list()
{
	GList * list = NULL;
	int i;
	for(i = 0; i < NUM_SERVICES; i++ )
	{
		if(eb_services[i].group_chat)
		{
			list = g_list_append(list, eb_services[i].name);
		}
	}
	return list;
}

static void invite_callback( GtkWidget * widget, gpointer data )
{
	eb_chat_room * ecr = data;
	RUN_SERVICE(ecr->chat_room_account)->send_invite(
				ecr->chat_room_account, ecr,
				gtk_entry_get_text(GTK_ENTRY(ecr->invite_buddy)),
				gtk_entry_get_text(GTK_ENTRY(ecr->invite_message)));

	gtk_widget_destroy(ecr->invite_window);
}

static void destroy_invite( GtkWidget * widget, gpointer data )
{
	eb_chat_room * ecr = data;
	ecr->invite_window_is_open = 0;
}

void do_invite_window(eb_chat_room * room )
{
	GtkWidget * box;
	GtkWidget * box2;
	GtkWidget * label;

	if( !room || room->invite_window_is_open )
	{
		return;
	}

	room->invite_window = gtk_window_new(GTK_WINDOW_DIALOG);

	box = gtk_vbox_new(FALSE, 3);
	box2 = gtk_hbox_new(FALSE, 3);

	label = gtk_label_new("Handle:");
	gtk_container_add(GTK_CONTAINER(box2), label);
	gtk_widget_show(label);

	room->invite_buddy = gtk_entry_new();
	gtk_container_add(GTK_CONTAINER(box2), room->invite_buddy);
	gtk_widget_show(room->invite_buddy);

	gtk_container_add(GTK_CONTAINER(box), box2);
	gtk_widget_show(box2);

	box2 = gtk_hbox_new(FALSE,3);
	label = gtk_label_new("Message:");
	gtk_container_add(GTK_CONTAINER(box2), label);
	gtk_widget_show(label);

	room->invite_message = gtk_entry_new();
	gtk_container_add(GTK_CONTAINER(box2), room->invite_message );
	gtk_widget_show(room->invite_message );

	gtk_container_add(GTK_CONTAINER(box), box2);
	gtk_widget_show(box2);
	
	label = gtk_button_new_with_label("Invite");
	gtk_container_add(GTK_CONTAINER(box), label);
	gtk_widget_show(label);


	gtk_signal_connect(GTK_OBJECT(label), "clicked", invite_callback, room);

	gtk_container_add(GTK_CONTAINER(room->invite_window), box);
	gtk_widget_show(box);

	gtk_widget_show(room->invite_window);
	
	
	gtk_signal_connect( GTK_OBJECT(room->invite_window), "destroy",
						GTK_SIGNAL_FUNC(destroy_invite), room);

}

	

static gboolean join_service_is_open = 0;

static GtkWidget * chat_room_name;
static GtkWidget * chat_room_type;
static GtkWidget * join_chat_window;

static void join_chat_callback(GtkWidget * widget, gpointer data )
{
	int id = get_service_id(gtk_entry_get_text(
				GTK_ENTRY(GTK_COMBO(chat_room_type)->entry)));
											

	eb_start_chat_room(id, gtk_entry_get_text(GTK_ENTRY(chat_room_name)));
	gtk_widget_destroy(join_chat_window);
}

static void join_chat_destroy(GtkWidget * widget, gpointer data )
{
	join_service_is_open = 0;
}

/*
 *  Let's build ourselfs a nice little dialog window to
 *  ask us what chat window we want to join :)
 */

void open_join_chat_window()
{
	GtkWidget * label;
	GtkWidget * frame;
	GtkWidget * table;
	GtkWidget * vbox;
	GtkWidget * hbox;
	GtkWidget * hbox2;
	GtkWidget * button;
	GtkWidget * iconwid;
	GtkWidget * separator;
	GdkPixmap * icon;
	GdkBitmap * mask;
	GList * list;

	if(join_service_is_open)
	{
		return;
	}
	join_service_is_open = 1;

	join_chat_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

	gtk_widget_realize(join_chat_window);
	
	vbox = gtk_vbox_new(FALSE, 5);
	
	gtk_container_add(GTK_CONTAINER(join_chat_window), vbox);
	
	table = gtk_table_new(2, 2, FALSE);
	
	label = gtk_label_new("Chat Room Name:");
	gtk_table_attach_defaults (GTK_TABLE(table), label, 0, 1, 0, 1);
	gtk_widget_show(label);

	chat_room_name = gtk_entry_new();
	gtk_table_attach_defaults (GTK_TABLE(table), chat_room_name, 1, 2, 0, 1);
	gtk_widget_show(chat_room_name);

	label = gtk_label_new("Service Type:");
	gtk_table_attach_defaults (GTK_TABLE(table), label, 0, 1, 1, 2);
	gtk_widget_show(label);

	chat_room_type = gtk_combo_new();
	list = chat_service_list();
	gtk_combo_set_popdown_strings(GTK_COMBO(chat_room_type), list);
	g_list_free(list);
	gtk_table_attach_defaults (GTK_TABLE(table), chat_room_type, 1, 2, 1, 2);
	gtk_widget_show(chat_room_type);

	/* set up a frame (hopefully) */

	frame = gtk_frame_new(NULL);
	gtk_frame_set_label(GTK_FRAME(frame), "Join a Chat Room");

	gtk_container_add(GTK_CONTAINER(frame), table);
	gtk_widget_show(table);

	gtk_table_set_row_spacings (GTK_TABLE(table), 5);
	gtk_table_set_col_spacings (GTK_TABLE(table), 5);
	
	/* This is a test to see if I can make some padding action happen */

	gtk_container_set_border_width(GTK_CONTAINER(join_chat_window), 5);
	gtk_container_set_border_width(GTK_CONTAINER(table), 5);
	
	gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
	
	/* Window resize BAD, Same size GOOD */

	gtk_window_set_policy (GTK_WINDOW(join_chat_window), FALSE, FALSE, TRUE);
	
	/* Show the frame and window */
	
	gtk_widget_show(frame);
	
	/* add in that nice separator */
	
	separator = gtk_hseparator_new();
	gtk_box_pack_start(GTK_BOX(vbox), separator, FALSE, FALSE, 5);
	gtk_widget_show(separator);
	
	/* Add in the pretty buttons with pixmaps on them */

	hbox = gtk_hbox_new(FALSE, 5);
	hbox2 = gtk_hbox_new(TRUE, 5);

	gtk_widget_set_usize(hbox2, 200, 25);
	
	/* stuff for the join button */
	
	icon = gdk_pixmap_create_from_xpm_d(join_chat_window->window, &mask, NULL, ok_xpm);
	iconwid = gtk_pixmap_new(icon, mask);
	label = gtk_label_new("Join");
						        
	gtk_box_pack_start(GTK_BOX(hbox), iconwid, FALSE, FALSE, 2); 
	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);
	
	gtk_widget_show(iconwid);
	gtk_widget_show(label);

	button = gtk_button_new();

	gtk_signal_connect(GTK_OBJECT(button), "clicked",
					GTK_SIGNAL_FUNC(join_chat_callback),
					NULL);
	gtk_widget_show(hbox);

	gtk_container_add(GTK_CONTAINER(button), hbox);
	gtk_box_pack_start(GTK_BOX(hbox2), button, TRUE, TRUE, 0);
	gtk_widget_show(button);
	
	
	/* stuff for the cancel button */

	hbox = gtk_hbox_new(FALSE, 5);
	
	icon = gdk_pixmap_create_from_xpm_d(join_chat_window->window, &mask, NULL, cancel_xpm);
	iconwid = gtk_pixmap_new(icon, mask);
	label = gtk_label_new("Cancel");

	gtk_box_pack_start(GTK_BOX(hbox), iconwid, FALSE, FALSE, 2); 
	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2);

	gtk_widget_show(iconwid);
	gtk_widget_show(label);

	button = gtk_button_new();
	
	gtk_signal_connect_object(GTK_OBJECT(button), "clicked",
						GTK_SIGNAL_FUNC(gtk_widget_destroy),
						GTK_OBJECT(join_chat_window));
	gtk_widget_show(hbox);

	gtk_container_add(GTK_CONTAINER(button), hbox);

	gtk_box_pack_start(GTK_BOX(hbox2), button, TRUE, TRUE, 0);
	gtk_widget_show(button);

	/* now put the hbox with all the buttons into the vbox? */

	hbox = gtk_hbox_new(FALSE, 0);
	
	gtk_box_pack_end(GTK_BOX(hbox), hbox2, FALSE, FALSE, 0);
	gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);

	gtk_widget_show(hbox);
	gtk_widget_show(hbox2);
	gtk_widget_show(vbox);
	
	/* show the window */
	
	gtk_widget_show(join_chat_window);

	gtk_signal_connect( GTK_OBJECT(join_chat_window), "destroy",
				GTK_SIGNAL_FUNC(join_chat_destroy), NULL );
}
	

	


static void destroy(GtkWidget * widget, gpointer data)
{
	eb_chat_room * ecr = data;
	RUN_SERVICE(ecr->chat_room_account)->leave_chat_room(ecr);
	chat_rooms = g_list_remove(chat_rooms, data);
	g_free(ecr);
}

static GList * find_chat_room_buddy( eb_chat_room * room, gchar * user )
{
	GList * node;
	for( node = room->fellows; node; node = node->next)
	{
		eb_chat_room_buddy * ecrb = node->data;
		if( !strcmp(user, ecrb->handle) )
		{
			return node;
		}
	}
	return NULL;
}
		
static void eb_chat_room_refresh_list(eb_chat_room * room )
{
	GList * node;
	gtk_clist_clear(GTK_CLIST(room->online));

	for( node = room->fellows; node; node = node->next )
	{
		eb_chat_room_buddy * ecrb = node->data;
		gchar * list[1] = {ecrb->alias};
		gtk_clist_append(GTK_CLIST(room->online), list);
	}
}

void eb_chat_room_buddy_arrive( eb_chat_room * room, gchar * alias, gchar * handle )
{
	eb_chat_room_buddy * ecrb = g_new0(eb_chat_room_buddy, 1 );

	strcpy( ecrb->alias, alias);
	strcpy( ecrb->handle, handle );

	room->fellows = g_list_append(room->fellows, ecrb);

	eb_chat_room_refresh_list(room);
}

void eb_chat_room_buddy_leave( eb_chat_room * room, gchar * handle )
{
	GList * node = find_chat_room_buddy(room, handle);

	if(node)
	{
		eb_chat_room_buddy * ecrb = node->data;
		room->fellows = g_list_remove_link(room->fellows, node);
		g_free(ecrb);
	}
	eb_chat_room_refresh_list(room);
}

			
						
void eb_start_chat_room( gint service, gchar * name )
{
	eb_local_account * ela =  find_suitable_local_account(NULL, service);
	eb_chat_room * ecb = NULL;
	
	/* if we don't have a working account just bail right now */
	
	if( !ela )
		return;

	ecb = RUN_SERVICE(ela)->make_chat_room(name, ela);
	

	if( ecb )
	{
		chat_rooms = g_list_append(chat_rooms, ecb);
	}
}



void eb_chat_room_show_message( eb_chat_room * chat_room, 
								gchar * user, gchar * message )
{
	gchar buff[2048];
	if(!strcmp(chat_room->chat_room_account->handle, user))
	{
		g_snprintf(buff, 2048, "<FONT COLOR=\"#0000FF\"><B>%s: </B></FONT>%s\n",
				   user, message);
	}
	else
	{

		g_snprintf(buff, 2048, "<FONT COLOR=\"#FF0000\"><B>%s: </B></FONT>%s\n",
				   user, message);
	}
	gtk_html_append_text(GTK_HTML(chat_room->conversation), buff,0 );
}

static void invite_button_callback( GtkWidget * widget, gpointer data )
{
	do_invite_window(data);
}

static void destroy_chat_window(GtkWidget * widget, gpointer data)
{
	eb_chat_room * ecr = data;
	gtk_widget_destroy(ecr->window);
}

void eb_join_chat_room( eb_chat_room * chat_room )
{
	GtkWidget * vbox;
	GtkWidget * vbox2;
	GtkWidget * hbox;
	GtkWidget * hbox2;
	GtkWidget * label;
	GtkWidget * scrollwindow = gtk_scrolled_window_new(NULL, NULL);
	GtkWidget * toolbar;
	GdkPixmap * icon;
	GdkBitmap * mask;
	GtkWidget * iconwid;
	GtkWidget * send_button;
	GtkWidget * close_button;
	
	/*if we are already here, just leave*/
	if(chat_room->connected)
		return;
	
	/*otherwise we are going to make ourselves a gui right here*/

	vbox = gtk_vbox_new(FALSE, 1);
	hbox = gtk_hpaned_new();

	gtk_paned_set_gutter_size(GTK_PANED(hbox), 20);
	
	chat_room->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
	chat_room->online = gtk_clist_new(1);
	gtk_clist_set_column_title(GTK_CLIST(chat_room->online), 0, "Online");
	gtk_widget_set_usize(chat_room->online, 100, 20 );
	chat_room->conversation = gtk_html_new(NULL, NULL);
	gtk_widget_set_usize(chat_room->conversation, 400, 200);
	gtk_html_set_editable(GTK_HTML(chat_room->conversation), FALSE);
	gtk_html_set_transparent(GTK_HTML(chat_room->conversation), FALSE);
	gtk_container_add(GTK_CONTAINER(scrollwindow), chat_room->conversation);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwindow), 
								   GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);

	/*make ourselves something to type into*/
	chat_room->entry = gtk_entry_new();

	gtk_signal_connect(GTK_OBJECT(chat_room->entry), "activate",
						GTK_SIGNAL_FUNC(send_message), chat_room );
	

	/*
	gtk_box_pack_start(GTK_BOX(hbox), scrollwindow, TRUE, TRUE, 3);
	gtk_box_pack_start(GTK_BOX(hbox), chat_room->online, FALSE, FALSE, 3);
	*/
	gtk_paned_add1(GTK_PANED(hbox), scrollwindow);
	gtk_widget_show(scrollwindow);

	vbox2 = gtk_vbox_new(FALSE, 5);

	scrollwindow = gtk_scrolled_window_new(NULL, NULL);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwindow), 
								   GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);

	gtk_container_add(GTK_CONTAINER(scrollwindow), chat_room->online );
	gtk_widget_show(chat_room->online);
	

	gtk_box_pack_start(GTK_BOX(vbox2), scrollwindow, TRUE, TRUE, 3 );
	gtk_widget_show(scrollwindow);

	label = gtk_button_new_with_label("Invite User");
	gtk_signal_connect(GTK_OBJECT(label), "clicked", invite_button_callback, 
						chat_room);

	gtk_box_pack_start(GTK_BOX(vbox2), label, FALSE, FALSE, 3);
	gtk_widget_show(label);

	gtk_paned_add2(GTK_PANED(hbox), vbox2);
	gtk_widget_show(vbox2);


	gtk_paned_add2(GTK_PANED(hbox), chat_room->online);
	gtk_widget_show(chat_room->conversation);

	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwindow),GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
	gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE,TRUE, 3);
	gtk_box_pack_start(GTK_BOX(vbox), chat_room->entry, FALSE, FALSE, 1);
	gtk_widget_show(hbox);
	gtk_widget_show(chat_room->entry);

	gtk_widget_realize(chat_room->window);
	gtk_window_set_title(GTK_WINDOW(chat_room->window), chat_room->room_name);
	gtk_signal_connect(GTK_OBJECT(chat_room->window), "destroy",
					   GTK_SIGNAL_FUNC(destroy), chat_room );

	
	/* start a toolbar here */
	
	hbox2 = gtk_hbox_new(FALSE, 0);
	gtk_widget_set_usize(hbox2, 200, 25);
	
	toolbar = gtk_toolbar_new(GTK_ORIENTATION_HORIZONTAL, GTK_TOOLBAR_ICONS);
	gtk_toolbar_set_button_relief(GTK_TOOLBAR(toolbar), GTK_RELIEF_NONE);
	gtk_container_set_border_width(GTK_CONTAINER(toolbar), 0);
	gtk_toolbar_set_space_size(GTK_TOOLBAR(toolbar), 5);
	
	icon = gdk_pixmap_create_from_xpm_d(chat_room->window->window, &mask, NULL, tb_mail_send_xpm);
	iconwid = gtk_pixmap_new(icon, mask);
	gtk_widget_show(iconwid);
	
	send_button = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar), 
				"send",
				"Send Message",
				"send",
				iconwid,
				GTK_SIGNAL_FUNC(send_message),
				chat_room);

	icon = gdk_pixmap_create_from_xpm_d(chat_room->window->window, &mask, NULL, cancel_xpm);
	iconwid = gtk_pixmap_new(icon, mask);
	gtk_widget_show(iconwid);
	
	close_button = gtk_toolbar_append_item(GTK_TOOLBAR(toolbar),
				"close",
				"Close",
				"close",
				iconwid,
				GTK_SIGNAL_FUNC(destroy_chat_window),
				chat_room);
	
	gtk_box_pack_end(GTK_BOX(hbox2), toolbar, FALSE, FALSE, 0);
	gtk_widget_show(toolbar);
	
	gtk_box_pack_start(GTK_BOX(vbox), hbox2, FALSE, FALSE, 5);
	gtk_widget_show(hbox2);
	
	gtk_container_add(GTK_CONTAINER(chat_room->window), vbox);
	gtk_widget_show(vbox);

	gtk_container_set_border_width(GTK_CONTAINER(chat_room->window), 5);
	
	gtk_widget_show(chat_room->window);


	/*then mark the fact that we have joined that room*/
	chat_room->connected = 1;
}

	
