/*
 * Gnophone: A client for the Asterisk PBX
 *
 * Copyright (C) 2000-2005, Digium, Inc.
 *
 * Written by Mark Spencer
 *
 * Linux/UNIX version distributed under the terms of
 * the GNU General Public License
 *
 * browser.c: Browser notebook code.
 *
 */

#define _BROWSER_C_

#define ICON_BACK
#define ICON_FORWARD
#define ICON_RELOAD
#define ICON_HOME
#define ICON_STOP
#define ICON_LOGO1
#define ICON_LOGO2
#define ICON_LOGO3
#define ICON_LOGO4
#define ICON_LOGO5

#include "gnophone.h"

extern GtkWidget *mw;
extern GtkWidget *nb;

extern GtkWidget *mk_image(char *filename);

struct html_engine *engine=NULL, *engines=NULL;
struct browser *pbrowser = NULL;

static GdkPixmap *spinner_pm[5];
static GdkBitmap *spinner_bm[5];

static void about() { }
static GtkWidget *mk_pixmap(struct browser *b, char **data)
{
	/* TODO: if (b->nographics) return NULL; */
	GdkPixmap *pm;
	GdkBitmap *bm;
	pm = gdk_pixmap_create_from_xpm_d(mw->window, &bm, NULL, data);
	return gtk_pixmap_new(pm, bm);
}


static void init_spinner()
{
	spinner_pm[0] = gdk_pixmap_create_from_xpm_d(mw->window, spinner_bm, NULL, logo_1_xpm);
	spinner_pm[1] = gdk_pixmap_create_from_xpm_d(mw->window, spinner_bm + 1, NULL, logo_2_xpm);
	spinner_pm[2] = gdk_pixmap_create_from_xpm_d(mw->window, spinner_bm + 2, NULL, logo_3_xpm);
	spinner_pm[3] = gdk_pixmap_create_from_xpm_d(mw->window, spinner_bm + 3, NULL, logo_4_xpm);
	spinner_pm[4] = gdk_pixmap_create_from_xpm_d(mw->window, spinner_bm + 4, NULL, logo_5_xpm);
}

static int spinner_cb(void *v)
{
	struct browser *b = v;
	b->spinnerpos++;
	if (b->spinnerpos > 4)
		b->spinnerpos = 0;
	gtk_pixmap_set(GTK_PIXMAP(b->spinner), spinner_pm[b->spinnerpos], spinner_bm[b->spinnerpos]);
	return TRUE;
}

static int stop_spinner(struct browser *b)
{
	b->spinnerpos = 0;
	gtk_timeout_remove(b->spinnerid);
	gtk_pixmap_set(GTK_PIXMAP(b->spinner), spinner_pm[0], spinner_bm[0]);
	b->spinnerpos = 0;
	return 0;
}

static int start_spinner(struct browser *b)
{
	b->spinnerpos = 0;
	b->spinnerid = gtk_timeout_add(200, spinner_cb, b);
	return 0;
}



int html_register_engine(struct html_engine *e)
{
	static struct html_engine *last = NULL;
	printf("Registering %s\n", e->name);
	e->next = NULL;

	if (last)
		last->next = e;
	else
		engines = e;

	last = e;
	return 0;
}

int html_select_engine(struct html_engine *e)
{
	char *s=NULL;
	if (engine) {
		engine = e;
		if (pbrowser) {
			if (pbrowser && pbrowser->location)
				s = (char*)gtk_entry_get_text(GTK_ENTRY(pbrowser->location));
			/* Destroy the old widget */
			gtk_widget_destroy(pbrowser->html);
			pbrowser->html = engine->new_engine(pbrowser);
			/* Add it to the frame */
			gtk_container_add(GTK_CONTAINER(pbrowser->frame), pbrowser->html);
			/* Show it */
			gtk_widget_show_all(pbrowser->html);
			pbrowser->engine = engine;
			if (s && strlen(s))
				pbrowser->engine->loadurl(pbrowser, s);
		}
	} else
		engine = e;
	return 0;
}

void html_display_new_location(struct browser *b, char *s)
{
	gtk_entry_set_text(GTK_ENTRY(b->location), s);
}

void html_display_new_title(struct browser *b, char *s)
{
	char buf[1024];
	snprintf(buf, sizeof(buf),"Gnophone: %s", s);
	gtk_window_set_title(GTK_WINDOW(mw), buf);
}	

void html_display_load_started(struct browser *b)
{
	gtk_widget_set_sensitive(b->stop, TRUE);
	gtk_widget_show(b->progress);
	gtk_progress_set_format_string(GTK_PROGRESS(b->progress), "%p%%");
	gtk_progress_set_show_text(GTK_PROGRESS(b->progress), TRUE);
	gtk_progress_configure(GTK_PROGRESS(b->progress), 0, 0, 1);
	start_spinner(b);
}

void html_display_load_finished(struct browser *b)
{
	gtk_widget_set_sensitive(b->stop, FALSE);	
/*	if (iaxloading && urlpeer && (urlpeer->pcid > -1))
		pc_load_complete(urlpeer->pcid);
	iaxloading = 0;*/
	stop_spinner(b);
/*	update_toolbar(b);*/
	gtk_widget_hide(b->progress);
}

void html_setstatus(struct browser *b, char *text)
{
	if (b) {
		gtk_statusbar_pop(GTK_STATUSBAR(b->statusbar), 1);
		gtk_statusbar_push(GTK_STATUSBAR(b->statusbar), 1, text);
	}
}

void html_update_progress(struct browser *b, int cur, int max)
{
	if (max > 1048576) {
		gtk_progress_set_format_string(GTK_PROGRESS(b->progress), "%p%% of %v megs");
		cur /= 1048576;
		max /= 1048576;
	} else if (max > 1024) {
		gtk_progress_set_format_string(GTK_PROGRESS(b->progress), "%p%% of %v kbytes");
		cur /= 1024;
		max /= 1024;
	} else {
		gtk_progress_set_format_string(GTK_PROGRESS(b->progress), "%p%% of %v bytes");
	}
	/* Fake it if we don't know how big the document is */
	if (max < 0)
		max = cur * 20;

	if (max)
		gtk_progress_configure(GTK_PROGRESS(b->progress), cur, 0, max);
}

void html_display_link(struct browser *b, char *s)
{
	html_setstatus(b, s);
}

static void back_cb(GtkWidget *w, struct browser *b)
{
	b->engine->go_back(b);
}

static void forward_cb(GtkWidget *w, struct browser *b)
{
	b->engine->go_forward(b);
}

static void reload_cb(GtkWidget *w, struct browser *b)
{
	b->engine->reload(b, 1);
}

static void home_cb(GtkWidget *w, struct browser *b)
{
	b->engine->loadurl(b, home_page);
}

static void stop_cb(GtkWidget *w, struct browser *b)
{
	b->engine->stop(b);
}

static void entry_cb(GtkWidget *w, struct browser *b)
{
	char *text = (char*)gtk_entry_get_text(GTK_ENTRY(b->location));	
	if (text) {
		interpret_call(text);

		if (link_pcid != -1) {
			printf("I got here yo.\n");
/*			pc_send_linked_url(link_pcid, text);*/
		}
	}
}

int _start_load_url(struct browser *b, char *url)
{
	gtk_notebook_set_page(GTK_NOTEBOOK(nb), 0);
	b->engine->loadurl(b, url);

	return 0;
}

struct browser *build_browser(void)
{
	struct browser *b;
	GtkWidget *hbox;
	GtkWidget *label;

	if (!engine)
		return NULL;

	/* Initialize spinner pixmaps */
	init_spinner();

	/* Create a browser structure */
	b = g_new0(struct browser, 1);
	
	b->engine = engine;
	
	/* Create an browser widget */
	b->html = b->engine->new_engine(b);
	
	
	/* Put it in a frame */
	b->frame = gtk_frame_new(NULL);
	gtk_container_add(GTK_CONTAINER(b->frame), b->html);

	/* Create a toolbar */
	b->toolbar = gtk_toolbar_new();
	gtk_toolbar_set_orientation(GTK_TOOLBAR(b->toolbar), GTK_ORIENTATION_HORIZONTAL);
	gtk_toolbar_set_style(GTK_TOOLBAR(b->toolbar), GTK_TOOLBAR_BOTH);
/*	gtk_toolbar_set_space_size(GTK_TOOLBAR(b->toolbar), 10);*/

	/* Create the main buttons with space between all of them */
	b->back = gtk_toolbar_append_item(GTK_TOOLBAR(b->toolbar), "Back", 
		"Return to previous page", "back", mk_pixmap(b, back), GTK_SIGNAL_FUNC(back_cb), b);
	gtk_toolbar_append_space(GTK_TOOLBAR(b->toolbar));
	b->forward = gtk_toolbar_append_item(GTK_TOOLBAR(b->toolbar), "Forward", 
		"Go forward", "forward", mk_pixmap(b, forward), GTK_SIGNAL_FUNC(forward_cb), b);
	gtk_toolbar_append_space(GTK_TOOLBAR(b->toolbar));
	b->reload = gtk_toolbar_append_item(GTK_TOOLBAR(b->toolbar), "Reload", 
		"Reload current page", "reload", mk_pixmap(b, reload), GTK_SIGNAL_FUNC(reload_cb), b);
	gtk_toolbar_append_space(GTK_TOOLBAR(b->toolbar));
	gtk_toolbar_append_space(GTK_TOOLBAR(b->toolbar));
	b->home = gtk_toolbar_append_item(GTK_TOOLBAR(b->toolbar), "Home", 
		"Go To Home Page", "home", mk_pixmap(b, home), GTK_SIGNAL_FUNC(home_cb), b);
	gtk_toolbar_append_space(GTK_TOOLBAR(b->toolbar));
	gtk_toolbar_append_space(GTK_TOOLBAR(b->toolbar));
	b->stop = gtk_toolbar_append_item(GTK_TOOLBAR(b->toolbar), "Stop", 
		"Stop loading page", "stop", mk_pixmap(b, stop), GTK_SIGNAL_FUNC(stop_cb), b);

	gtk_toolbar_append_space(GTK_TOOLBAR(b->toolbar));
	gtk_toolbar_append_space(GTK_TOOLBAR(b->toolbar));
	
/* #if 0 */
	b->spinner = gtk_pixmap_new(spinner_pm[0], spinner_bm[0]);
	b->spinnerb = gtk_button_new();
	gtk_button_set_relief(GTK_BUTTON(b->spinnerb), GTK_RELIEF_NONE);
	gtk_button_set_focus_on_click(GTK_BUTTON(b->spinnerb), 0);

	gtk_container_add(GTK_CONTAINER(b->spinnerb), b->spinner);
	gtk_toolbar_append_element(GTK_TOOLBAR(b->toolbar), GTK_TOOLBAR_CHILD_WIDGET, b->spinnerb, "", "Fancy Spinner Thing", "spinner", NULL, GTK_SIGNAL_FUNC(about), b);

/*#else
	b->spinnerb = gtk_button_new();
	gtk_toolbar_append_element(GTK_TOOLBAR(b->toolbar), GTK_TOOLBAR_CHILD_WIDGET, b->spinner, "", "Fancy Spinner Thing", "spinner", NULL, GTK_SIGNAL_FUNC(about), b);
	
 #endif */
	
	/* Create a horizontal box and put the locator in it */
	b->location = gtk_entry_new();
	gtk_signal_connect(GTK_OBJECT(b->location), "activate", GTK_SIGNAL_FUNC(entry_cb), b);
	
	hbox = gtk_hbox_new(FALSE, 0);
	label = gtk_label_new("Location:");
	gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 5);
	gtk_box_pack_start(GTK_BOX(hbox), b->location, TRUE, TRUE, 0);


	/* Pack stuff in the box */
	b->outerbox = gtk_vbox_new(FALSE, 0);
	gtk_container_set_border_width(GTK_CONTAINER(b->outerbox), 5);
	gtk_box_pack_start(GTK_BOX(b->outerbox), b->toolbar, FALSE, FALSE, 5);
	gtk_box_pack_start(GTK_BOX(b->outerbox), hbox, FALSE, FALSE, 5);
	gtk_box_pack_start(GTK_BOX(b->outerbox), b->frame, TRUE, TRUE, 5);

	/* And we should have a status bar at the bottom */
	b->statusbar = gtk_statusbar_new();
	html_setstatus(b, "Ready.");

	/* Make an h-box for the status bar */
	hbox = gtk_hbox_new(FALSE, 0);
	gtk_box_pack_start(GTK_BOX(hbox), b->statusbar, TRUE, TRUE, 0);
	
	/* And a progress bar */
	b->progress = gtk_progress_bar_new();
	gtk_box_pack_start(GTK_BOX(hbox), b->progress, FALSE, FALSE, 0);
	
	gtk_box_pack_start(GTK_BOX(b->outerbox), hbox, FALSE, FALSE, 0);

	/* Make sure the window is NULL */
	b->window = NULL;

	gtk_widget_set_sensitive(b->stop, FALSE);	
	
	/* Create a box container */
#ifdef ENABLE_HANDLE
	b->box = gtk_handle_box_new();
	gtk_handle_box_set_shadow_type(GTK_HANDLE_BOX(b->box), GTK_SHADOW_NONE);
	gtk_signal_connect(GTK_OBJECT(b->box), "child-detached", detached_cb, b);
	gtk_signal_connect(GTK_OBJECT(b->box), "child-attached", attached_cb, b);
#else
	b->box = gtk_frame_new(NULL);
	gtk_frame_set_shadow_type(GTK_FRAME(b->box), GTK_SHADOW_NONE);
#endif
	gtk_container_add(GTK_CONTAINER(b->box), b->outerbox);
	
	/* Update the toolbar */
/*	update_toolbar(b);	*/
		
	return b;
}

int start_load_url(char *url)
{
	if (pbrowser)
		return _start_load_url(pbrowser, url);
	return 0;
}

