/* X-Chat
 * Copyright (C) 1998 Peter Zelezny.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include "../common/xchat.h"
#include "../common/fe.h"
#include "fe-gtk.h"
#include "gtkutil.h"
#include "menu.h"
#include "../common/util.h"
#include "xtext.h"

extern GSList *sess_list;
extern struct xchatprefs prefs;
extern GdkFont *dialog_font_normal;
extern GdkColor colors[];
extern GdkPixmap *dialogwin_pix;
extern GtkStyle *inputgad_style;
extern GtkWidget *main_window;
extern GtkWidget *main_book;
extern struct session *current_tab;
extern struct session *menu_sess;
extern GtkStyle *normaltab_style;
#ifdef USE_GNOME
extern GtkTargetEntry dnd_targets[];
#endif

extern void gui_create_standard_buttons (session *sess, GtkWidget *win, GtkWidget *tbox);
extern void gui_create_toolbox (session *sess, GtkWidget *box);
extern int auto_insert (char *dest, char *src, char *word[], char *word_eol[], char *a, char *c, char *d, char *h, char *n, char *s);
extern void maingui_configure (GtkWidget * unused);
extern int maingui_word_check (GtkXText * xtext, char *word);
extern void maingui_word_clicked (GtkXText * xtext, char *word,
											 GdkEventButton * even, session * sess);
extern void maingui_moveright (GtkWidget * wid);
extern void maingui_moveleft (GtkWidget * wid);
extern struct session *find_dialog (struct server *serv, char *nick);
extern void X_session (GtkWidget * button, struct session *sess);
extern int maingui_pagetofront (int page);
extern void show_and_unfocus (GtkWidget * wid);
extern void add_tip (GtkWidget * wid, char *text);
extern void maingui_panelize (GtkWidget * button, struct session *sess);
extern void maingui_unpanelize (GtkWidget * button, struct session *sess);
extern int handle_command (char *cmd, struct session *sess, int history, int);
extern int open_log_file (char *servname, char *channame);
struct session *new_dialog (struct session *sess);
extern void dcc_send (struct session *sess, char *tbuf, char *to, char *file);
extern int relink_window (GtkWidget * w, struct session *sess);
extern void handle_inputgad (GtkWidget * igad, struct session *sess);
extern gint gtk_kill_session_callback (GtkWidget * win, struct session *sess);
extern void focus_in (GtkWindow * win, GtkWidget * wid, struct session *sess);
int key_handle_key_press (GtkWidget, GdkEventKey, gpointer);


#ifdef USE_GNOME
static void
dialog_dnd_drop (GtkWidget * widget, GdkDragContext * context, gint x,
					  gint y, GtkSelectionData * selection_data, guint info,
					  guint32 time, struct session *sess)
{
	GList *list;
	char *file, tbuf[1024];

	if (!sess->channel[0])
		return;

	list = gnome_uri_list_extract_filenames (selection_data->data);
	while (list)
	{
		file = (char *) (list->data);
		dcc_send (sess, tbuf, sess->channel, file);
		list = list->next;
	}
	gnome_uri_list_free_strings (list);
}
#endif

void
fe_change_nick (struct server *serv, char *nick, char *newnick)
{
	struct session *sess = find_dialog (serv, nick);
	if (sess)
	{
		strcpy (sess->channel, newnick);
		if (!sess->is_tab)
			gtk_window_set_title (GTK_WINDOW (sess->gui->window), newnick);
	}
}

static void
dialog_button_cb (GtkWidget *wid, char *cmd)
{
	/* the longest cmd is 12, and the longest nickname is 64 */
	char buf[128];

	if (!menu_sess)
		return;

	auto_insert (buf, cmd, 0, 0, "", "", "", "", "", menu_sess->channel);

	handle_command (buf, menu_sess, FALSE, FALSE);
}

static void
dialog_button (GtkWidget *box, char *label, char *cmd)
{
	GtkWidget *wid;

	wid = gtk_button_new_with_label (label);
	gtk_box_pack_start (GTK_BOX (box), wid, FALSE, FALSE, 0);
	gtk_signal_connect (GTK_OBJECT (wid), "clicked",
							  GTK_SIGNAL_FUNC (dialog_button_cb), cmd);
	if (prefs.inputgad_superfocus)
		show_and_unfocus (wid);
	else
		gtk_widget_show (wid);
}

static void
open_dialog_window (struct session *sess)
{
	GtkWidget *hbox, *vbox, *bbox;
	int page = prefs.privmsgtab;
	struct User *user;

	if (!main_book)
		page = 0;
	if (!page)
	{
#ifdef USE_GNOME
		sess->gui->window = gnome_app_new ("X-Chat", sess->channel);
		gtk_signal_connect ((GtkObject *) sess->gui->window, "destroy",
								  GTK_SIGNAL_FUNC (gtk_kill_session_callback), sess);
#else
		sess->gui->window =
			gtkutil_window_new (sess->channel, "X-Chat", 300, 100,
									  gtk_kill_session_callback, sess, FALSE);
#endif
		gtk_signal_connect ((GtkObject *) sess->gui->window, "focus_in_event",
								  GTK_SIGNAL_FUNC (focus_in), sess);
		gtk_window_set_policy ((GtkWindow *) sess->gui->window, TRUE, TRUE,
									  FALSE);
		sess->is_tab = FALSE;
	} else
	{
		sess->gui->window = gtk_hbox_new (0, 0);
		sess->is_tab = TRUE;
	}
	vbox = gtk_vbox_new (0, 0);
	sess->gui->vbox = vbox;
	gtk_container_set_border_width (GTK_CONTAINER (vbox), 0);

	if (!page)
	{
#ifdef USE_GNOME
		gnome_app_set_contents (GNOME_APP (sess->gui->window), vbox);
#else
		gtk_container_add (GTK_CONTAINER (sess->gui->window), vbox);
#endif
	} else
		gtk_container_add (GTK_CONTAINER (sess->gui->window), vbox);
	if (page)
	{
		sess->gui->changad = gtk_label_new (sess->channel);
		gtk_notebook_append_page (GTK_NOTEBOOK (main_book), sess->gui->window,
										  sess->gui->changad);
	} else
		sess->gui->changad = NULL;
	gtk_widget_show (vbox);

	if (page)
	{
		gtk_signal_connect ((GtkObject *) sess->gui->window, "destroy",
								  GTK_SIGNAL_FUNC (gtk_kill_session_callback), sess);
	}
	sess->gui->tbox = hbox = gtk_hbox_new (FALSE, 0);
	gtk_container_set_border_width (GTK_CONTAINER (hbox), 0);
	gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 2);
	gtk_widget_show (hbox);

	/* create the X ^ < > buttons */
	gui_create_standard_buttons (sess, sess->gui->window, hbox);

	sess->gui->topicgad = gtk_entry_new ();
	gtk_entry_set_editable ((GtkEntry *) sess->gui->topicgad, FALSE);
	gtk_container_add (GTK_CONTAINER (hbox), sess->gui->topicgad);
	if (prefs.inputgad_superfocus)
		show_and_unfocus (sess->gui->topicgad);
	else
		gtk_widget_show (sess->gui->topicgad);

	dialog_button (hbox, "WhoIs", "/whois %s");
	dialog_button (hbox, "Send", "/dcc send %s");
	dialog_button (hbox, "Chat", "/dcc chat %s");
	dialog_button (hbox, "Ping", "/ping %s");
	dialog_button (hbox, "Clear", "/clear");

	hbox = gtk_hbox_new (FALSE, 0);
	sess->gui->leftpane = hbox;
	gtk_container_add (GTK_CONTAINER (vbox), hbox);
	gtk_widget_show (hbox);

	sess->gui->textgad =
		gtk_xtext_new (prefs.dialog_indent_pixels * prefs.dialog_indent_nicks,
							prefs.dialog_show_separator);

	gtk_object_set_user_data (GTK_OBJECT (sess->gui->textgad), sess);

	((GtkXText *) sess->gui->textgad)->double_buffer = prefs.double_buffer;
	((GtkXText *) sess->gui->textgad)->wordwrap = prefs.dialog_wordwrap;
	((GtkXText *) sess->gui->textgad)->max_auto_indent = prefs.max_auto_indent;
	((GtkXText *) sess->gui->textgad)->auto_indent = prefs.auto_indent;
	((GtkXText *) sess->gui->textgad)->thinline = prefs.thin_separator;
	((GtkXText *) sess->gui->textgad)->max_lines = prefs.max_lines;
	((GtkXText *) sess->gui->textgad)->error_function = gtkutil_simpledialog;
	((GtkXText *) sess->gui->textgad)->urlcheck_function = maingui_word_check;

	((GtkXText *) sess->gui->textgad)->tint_red = prefs.dialog_tint_red;
	((GtkXText *) sess->gui->textgad)->tint_green = prefs.dialog_tint_green;
	((GtkXText *) sess->gui->textgad)->tint_blue = prefs.dialog_tint_blue;

	if (prefs.timestamp && prefs.dialog_indent_nicks)
		((GtkXText *) sess->gui->textgad)->time_stamp = TRUE;

	gtk_xtext_set_palette (GTK_XTEXT (sess->gui->textgad), colors);
	gtk_xtext_set_font (GTK_XTEXT (sess->gui->textgad), dialog_font_normal, 0);
	gtk_xtext_set_background (GTK_XTEXT (sess->gui->textgad),
									  dialogwin_pix,
									  prefs.dialog_transparent, prefs.dialog_tint);

	gtk_container_add (GTK_CONTAINER (hbox), sess->gui->textgad);
	show_and_unfocus (sess->gui->textgad);

#ifdef USE_GNOME
	gtk_drag_dest_set (sess->gui->textgad, GTK_DEST_DEFAULT_ALL, dnd_targets,
							 1, GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK);
	gtk_signal_connect (GTK_OBJECT (sess->gui->textgad), "drag_data_received",
							  GTK_SIGNAL_FUNC (dialog_dnd_drop), sess);
#endif

	sess->gui->vscrollbar =
		gtk_vscrollbar_new (GTK_XTEXT (sess->gui->textgad)->adj);
	gtk_box_pack_start (GTK_BOX (hbox), sess->gui->vscrollbar, FALSE, FALSE,
							  1);
	show_and_unfocus (sess->gui->vscrollbar);

	if (!sess->is_tab)
		gtk_signal_connect_object (GTK_OBJECT (sess->gui->window),
											"configure_event",
											GTK_SIGNAL_FUNC (maingui_configure),
											GTK_OBJECT (sess->gui->textgad));

	bbox = gtk_hbox_new (FALSE, 0);
	gtk_container_set_border_width (GTK_CONTAINER (bbox), 0);
	gtk_box_pack_end (GTK_BOX (vbox), bbox, FALSE, TRUE, 2);
	gtk_widget_show (bbox);

	gtk_signal_connect (GTK_OBJECT (sess->gui->textgad), "word_click",
							  GTK_SIGNAL_FUNC (maingui_word_clicked), sess);

	sess->gui->inputgad = gtk_entry_new_with_max_length (2048);
	gtk_container_add (GTK_CONTAINER (bbox), sess->gui->inputgad);
	/*gtk_signal_connect (GTK_OBJECT (sess->gui->inputgad), "activate",
							  GTK_SIGNAL_FUNC (handle_inputgad), sess);*/
	gtk_signal_connect (GTK_OBJECT (sess->gui->inputgad), "key_press_event",
							  GTK_SIGNAL_FUNC (key_handle_key_press), sess);
	if (prefs.style_inputbox)
		gtk_widget_set_style (sess->gui->inputgad, inputgad_style);
	gtk_widget_show (sess->gui->inputgad);

	/* create the < ^ buttons on the bottom right (maingui.c) */
	gui_create_toolbox (sess, bbox);

	gtk_widget_show (sess->gui->window);

	if (page)
	{
		if (prefs.newtabstofront)
		{
			page =
				gtk_notebook_page_num (GTK_NOTEBOOK (main_book),
											  sess->gui->window);
			maingui_pagetofront (page);

			gtk_widget_grab_focus (sess->gui->inputgad);
			current_tab = sess;
			menu_sess = sess;
			if (!prefs.use_server_tab)
				sess->server->front_session = sess;
			sess->nick_said = FALSE;
			sess->new_data = FALSE;
			gtk_widget_set_style (sess->gui->changad, normaltab_style);
		} else
			sess->new_data = TRUE;
	}

	fe_set_title (sess);

	user = find_name_global (sess->server, sess->channel);
	if (user)
	{
		if (user->hostname)
			gtk_entry_set_text (GTK_ENTRY (sess->gui->topicgad), user->hostname);
	}
}

struct session *
new_dialog (struct session *sess)
{
	if (prefs.logging)
		sess->logfd = open_log_file (sess->server->servername, sess->channel);
	else
		sess->logfd = -1;
	open_dialog_window (sess);
	sess->new_data = FALSE;

	return (sess);
}
