/* A SkipStone Zoomer plugin by Maher <muhri@muhri.net> */
#include "../../src/skipstone.h"
#define PLUGIN_NAME "Zoomer"

extern gboolean mozilla_set_zoom(GtkMozEmbed *m, float ZoomValue);
extern gchar *home;

typedef struct {
    gchar *url;
    gint  zoom;
}
ZoomHistory;

static void create_plugin(SkipStone *skipstone);
static void spinner_spinned(GtkWidget *spinner, SkipStone *ss);
static void zoomer_loaded(GtkMozEmbed *embed,SkipStone *skipstone);
static void write_zoom_history(void);
static void read_zoom_history(void);
static void add_zoom_history(gchar *url,gint zl);
static void zoom_remember(GtkWidget *m, SkipStone *ss);
static void zoom_unremember(GtkWidget *m, SkipStone *ss);

static gboolean zoom_history_exists(gchar *url, gint zl);
static gboolean zoomer_buttonpress(GtkWidget *spinner, GdkEventButton *ev, SkipStone *ss);
static ZoomHistory *get_zoom_history(gchar *url);

static GSList *zoom_history = NULL;
static GtkWidget *popup_menu = NULL;

static SkipStonePlugin plugin =
{
	PLUGIN_NAME, /* plugin name */
       	PLUGIN_IN_TOOLBAR, /* position in toolbar */
       	create_plugin,/* create plugin function */
       	NULL,
       	NULL,
	  1 /* do we create this plugin for each window */
};




static void spinner_spinned(GtkWidget *spinner, SkipStone *ss)  
{
     gchar *location;
     gboolean result;
     gint num;

     /* arg checks */
     g_return_if_fail(spinner != NULL);
     g_return_if_fail(ss != NULL);
     

     num = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spinner));
     result = mozilla_set_zoom(ss->embed,(float) num / 100);
     location = gtk_moz_embed_get_location(ss->embed);
	
     if (location)  {
	  zoom_history_exists(location, num);
	  g_free(location);
     }

     if (!result)
       	g_message("SkipStone Zoom Plugin: Zoom Failed!!\n");

}

static void zoomer_loaded(GtkMozEmbed *embed,SkipStone *skipstone)
{
	gchar *location=NULL;
	ZoomHistory *zh=NULL;
     	GtkWidget *spinner=NULL;
	D_ENTER;

     	g_return_if_fail(skipstone->embed !=NULL);
     
     	location = gtk_moz_embed_get_location(skipstone->embed);
     
     	if (location) {
	     zh = get_zoom_history(location);
	     spinner = gtk_object_get_data(GTK_OBJECT(embed),"zoomerPlugin");
	     if (!zh) {
		  gint value = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spinner));
		  if (value < 100 || value > 100) {
			  gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinner),(float)100);
			  mozilla_set_zoom(embed, (float) 100/100);
		  }
		  g_free(location);
		  return;
	     }
	     spinner = gtk_object_get_data(GTK_OBJECT(embed),"zoomerPlugin");
	     mozilla_set_zoom(embed,(float) zh->zoom/100);
	     if(NULL!=spinner)
	       	gtk_spin_button_set_value(GTK_SPIN_BUTTON(spinner),(float)zh->zoom);
	     g_free(location);	     			
	}

	D_RETURN;
}
  

static void create_plugin(SkipStone *skipstone)
{
     GtkWidget *spinner;
     GtkObject *adj;
     adj = gtk_adjustment_new(100, 1, 999, 10, 25, 10);
     spinner = gtk_spin_button_new(GTK_ADJUSTMENT(adj), 1, 0);
     gtk_entry_set_editable(GTK_ENTRY(spinner), FALSE);
     gtk_signal_connect (GTK_OBJECT(spinner), "changed", 
			 GTK_SIGNAL_FUNC(spinner_spinned),
			 skipstone);
     gtk_widget_show(spinner);
     gtk_signal_connect(GTK_OBJECT(skipstone->embed), "net_stop", 
			GTK_SIGNAL_FUNC(zoomer_loaded), 
			skipstone);
     gtk_signal_connect(GTK_OBJECT(spinner), "button_press_event",
			GTK_SIGNAL_FUNC(zoomer_buttonpress),
			skipstone);
     skipstone_add_plugin_to_toolbar(skipstone,spinner,"Zoom current page");
     gtk_object_set_data(GTK_OBJECT(skipstone->embed), "zoomerPlugin", spinner);
     return;
}

SkipStonePlugin *init_plugin(void)
{
	zoom_history = NULL;
	read_zoom_history();
	return &plugin;
}

static void read_zoom_history(void) {
	FILE *hist_file;
	gchar *file;
	gchar line[1024];
	ZoomHistory *zh;
	
	file = g_strconcat(home,"/.skipstone/zoom",NULL);
	hist_file = fopen(file,"r");
	if (hist_file == NULL) {
		printf(_("No Zoom History file to read!\n"));
	     	g_free(file);
		return ;
	}

	while(fgets(line,1023,hist_file) != NULL) {
		gchar **split = g_strsplit(line, "^^^", -1);
		zh = g_new0(ZoomHistory,1);
		zh->url = g_strdup(split[0]);
		zh->zoom = atoi(split[1]);
		zoom_history = g_slist_append(zoom_history,zh);
	     	g_strfreev(split);
	}

	fclose(hist_file);
	g_free(file);
	return ;
}

static void write_zoom_history(void) {
	FILE *hist_file;
	gchar *file;
       	GSList *list;
     
     	D_ENTER;
     
	file = g_strconcat(home,"/.skipstone/zoom",NULL);
	hist_file = fopen(file,"w");
	if (hist_file == NULL) {
		printf(_("Couldn't open Zoom History file for writing!\n"));
	     	g_free(file);
		D_RETURN;
	}

	for (list = zoom_history; list ; list = list->next) {
		ZoomHistory *zh = (ZoomHistory*)list->data;
		fprintf(hist_file,"%s^^^%d\n",zh->url,zh->zoom); 
	}
	fclose(hist_file);
	g_free(file);	
	D_RETURN;
}


static gboolean zoom_history_exists(gchar *url, gint zl)
{
     GSList *list;
     
     for(list = zoom_history;list;list = list->next) {
	   ZoomHistory *zh = (ZoomHistory*)list->data;
	   if(!strcmp(url,zh->url)) {
		zh->zoom = zl;
		write_zoom_history();
		return TRUE;
	   }
      }
     	
     return FALSE;
}

static ZoomHistory *get_zoom_history(gchar *url)
{
     GSList *list;
     
     for (list = zoom_history; list; list = list->next) {
	  ZoomHistory *zh = (ZoomHistory *)list->data;
	  if (!strcmp(zh->url,url)) return zh;
     }
     
     return NULL;
}
	      
static void add_zoom_history(gchar *url,gint zl)
{
	ZoomHistory *zh;

	if (zoom_history_exists(url, zl)) return;     

     	zh = g_new0(ZoomHistory, 1);
     	zh->zoom = zl;
     	zh->url = g_strdup(url);
     	zoom_history = g_slist_append(zoom_history, zh);
      
	write_zoom_history();
}

static gboolean zoomer_buttonpress(GtkWidget *spinner, GdkEventButton *ev, SkipStone *ss)
{
     GtkWidget *m1, *m2;
     gchar *location;
     ZoomHistory *zh = NULL;
     if (ev->button != 3) return FALSE;
     if (popup_menu != NULL) gtk_widget_destroy(popup_menu);
     popup_menu = gtk_menu_new();
     m1 = gtk_menu_item_new_with_label("Remember Zoom value for this url");
     gtk_signal_connect(GTK_OBJECT(m1), "activate",
			GTK_SIGNAL_FUNC(zoom_remember), ss);
     gtk_menu_append(GTK_MENU(popup_menu), m1);
     m2 = gtk_menu_item_new_with_label("Unremember Zoom value for this url");
     gtk_signal_connect(GTK_OBJECT(m2), "activate",
			GTK_SIGNAL_FUNC(zoom_unremember), ss);
     gtk_menu_append(GTK_MENU(popup_menu), m2);
     location = gtk_moz_embed_get_location ( ss->embed );
     if (location) {
	  zh = get_zoom_history(location);
	  if (zh) gtk_widget_set_sensitive(m1, FALSE);
	  else gtk_widget_set_sensitive(m2, FALSE);
	  g_free(location);
     }	
     gtk_widget_show_all(popup_menu);
     gtk_menu_popup(GTK_MENU(popup_menu), NULL, NULL, NULL, NULL,
		    GDK_BUTTON3_MASK, ev->time);
     return TRUE;
}	
	       
	       
static void zoom_remember(GtkWidget *m, SkipStone *ss)
{
     gchar *location;
     gint num;
     GtkWidget *spinner=NULL;
     /* arg checks */
     g_return_if_fail(ss != NULL);
     spinner = gtk_object_get_data(GTK_OBJECT(ss->embed), "zoomerPlugin");
     if (!spinner) return;
     num = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spinner));

     location = gtk_moz_embed_get_location(ss->embed);
	
     if (location)  {
	  add_zoom_history(location, num);
	  g_free(location);
     }


}

static void zoom_unremember(GtkWidget *m, SkipStone *ss)
{
     gchar *location;
     ZoomHistory *rem = NULL;
     location = gtk_moz_embed_get_location(ss->embed);
     if (location) {
	  GSList *l;
	  for (l = zoom_history; l; l=l->next) {
	       ZoomHistory *zh = (ZoomHistory *)l->data;
	       if (!strcmp(location, zh->url)) {
		    rem = zh;
		    break;
	       }
	  }
	  g_free(location);
     }
     if (rem) {
	  zoom_history = g_slist_remove(zoom_history, rem);
	  write_zoom_history();
     }
}

	     
