/* copyright 	Maher Awamy <muhri@muhri.net>		*
 *		Charlie Schmidt <ishamael@themes.org>	*
 *							*
 *  released under the GPL				*/


#include "skipstone.h"
#include <regex.h>

static gboolean process_uri(const gchar *uri);
static gchar* check_file_exists(const gchar *directory, const gchar *filename);
static void launch_mailer(const gchar *uri);
static void set_theme_dirs(void);
static void read_bookmark_folder(FILE *bookmark_file,gchar *label,GNode *parent);
static void print_bookmarks(FILE *file);
static void print_node_data(GNode *node,FILE *file);
static void add_pixmap_directory(const gchar *directory);
static void skipstone_set_proxy_prefs(void);

gchar* get_bracketed_string(gchar *charset);
gboolean download_url(const gchar *uri);

extern GSList *window_count;
extern ConfigData config;
extern GList *combo_urls;
extern GSList *history;
extern GtkWidget *main_window;
extern GNode *bookmarks;
extern GSList *prefixes;
extern GHashTable *skipstone_plugin_config;
extern gchar *home;

static GSList *pixmaps_directories = NULL;
static char *dummy_pixmap_xpm[] = {
	"1 1 1 1",
	"  c None",
	" "
};

static char *autodetect_charset_prefs[] =
{
	"",
	"zh_parallel_state_machine",
	"cjk_parallel_state_machine",
	"ja_parallel_state_machine",
	"ko_parallel_state_machine",
	"ruprob",
	"zhcn_parallel_state_machine",
	"zhtw_parallel_state_machine",
	"ukprob"
};

static const char *lang_font_item [LANG_FONT_NUM] =
{
        "x-western",
        "x-central-euro",
        "ja",
        "zh-TW",
        "zh-CN",
        "ko",
        "x-cyrillic",
        "x-baltic",
        "el",
        "tr",
        "x-unicode",
        "x-user-def",
        "th",
        "he",
        "ar"
};

extern gchar *accept_languages_setup_or_lookup(GtkWidget *clist, gint lookup_only);

gboolean open_uri (const gchar *uri)
{
	gboolean process;
     	
     	D_ENTER;

     	if (!strncmp (uri, "mailto:", 7)) {
		if (!config.mailer || !strcmp(config.mailer,"")) { 
		     g_warning(_("Configure your mailer please!"));
		     D_RETURN_ (FALSE);
		}

		launch_mailer(&uri[7]);		
	     	D_RETURN_ ( TRUE );
	} else {
		if (!config.use_skipstone_mime) {
		  D_RETURN_ (FALSE);
		} else  {
		  process = process_uri(uri);
		  D_RETURN_ (process);
		}
	}
       	D_RETURN_ ( FALSE );
}

static GString *esc_string(GString *s)
{
	const gchar qchars[] = "`\"";
	gchar	    *ch;
	gint	    pos;

	D_ENTER;
	for (ch = s->str; *ch; ++ch)
		if (strchr(qchars, *ch))
		{
			pos = ch - s->str;
			s = g_string_insert_c(s, pos, '\\');
			ch = s->str + pos + 1;
		}
	D_RETURN_ (s);
}

static void launch_mailer(const gchar *uri)
{
    FILE *pipe;
    regex_t *pRegex = (regex_t *)malloc(sizeof(regex_t));
    regmatch_t *pRm = NULL;
    gchar **uriparts = g_strsplit(g_strdup(uri),"?",2);
    gchar *toaddr, *endpart=NULL;
    gchar *launch=NULL;
    gchar *counter=NULL;
    gchar hex[5];
    gchar hexch;
    GString *to=NULL, *subject=NULL, *cc=NULL, *bcc=NULL;
    GString *endstring, *launchstr=NULL;
    int regex_ret, i;
    gchar ch='\0';
    
     D_ENTER;     
     
    to = g_string_new(g_strdup(uriparts[0]));
    to = g_string_prepend_c(g_string_append_c(to,'\"'),'\"');
    toaddr = g_strdup((*to).str);
    g_string_free(to,TRUE);
    endstring = g_string_new(g_strdup(uriparts[1]));
    endstring = g_string_prepend_c(endstring,'<');
    
    if (g_strcasecmp((*endstring).str,"<") != 0){
        pRegex = (regex_t *)malloc(sizeof(regex_t));
        regcomp(pRegex,"[<&?]subject=",REG_EXTENDED);
        if (regexec(pRegex,(*endstring).str,0,NULL,0) != 0) {
            endstring = g_string_append(endstring, "&subject=");
        }
        regfree(pRegex);
        free(pRegex);
        pRegex = (regex_t *)malloc(sizeof(regex_t));
        
        regcomp(pRegex,"[<&?]cc=",REG_EXTENDED);
        if (regexec(pRegex,(*endstring).str,0,NULL,0) != 0) {
            endstring = g_string_append(endstring, "&cc=");
        }
        regfree(pRegex);
        free(pRegex);
        pRegex = (regex_t *)malloc(sizeof(regex_t));

        regcomp(pRegex,"[<&?]bcc=",REG_EXTENDED);
        if (regexec(pRegex,(*endstring).str,0,NULL,0) != 0) {
            endstring = g_string_append(endstring, "&bcc=");
        }
        regfree(pRegex);
        free(pRegex);
        pRegex = NULL;
        
        endstring = g_string_append_c(endstring,'>');
        endpart = g_strdup((*endstring).str);

        pRegex = (regex_t *)malloc(sizeof(regex_t));
        pRm = (regmatch_t *)malloc(7*sizeof(regmatch_t));
        regcomp(pRegex, "<(subject=|cc=|bcc=)(.*)&(subject=|cc=|bcc=)(.*)&(subject=|cc=|bcc=)(.*)>", REG_EXTENDED);
        regex_ret = regexec(pRegex, endpart, 7, pRm, 0);
        if (regex_ret == 0) {
            for (i=0; i<3; i++) {
                ch = ((*g_string_truncate(g_string_erase(g_string_new(endpart),0,pRm[2*i+1].rm_so),pRm[0].rm_eo-pRm[2*i+1].rm_so)).str)[0];
                switch(ch) {
                    case 's':
                    case 'S': 
                        subject = g_string_truncate(g_string_erase(g_string_new(endpart),0,pRm[2*i+2].rm_so),pRm[2*i+2].rm_eo-pRm[2*i+2].rm_so);
			subject = esc_string(subject);
                        subject = g_string_prepend_c(g_string_append_c(subject,'\"'),'\"');
                        break;
                    case 'c':
                    case 'C': 
                        cc = g_string_truncate(g_string_erase(g_string_new(endpart),0,pRm[2*i+2].rm_so),pRm[2*i+2].rm_eo-pRm[2*i+2].rm_so);
			cc = esc_string(cc);
                        cc = g_string_prepend_c(g_string_append_c(cc,'\"'),'\"');
                        break;
                    case 'b':
                    case 'B': 
                        bcc = g_string_truncate(g_string_erase(g_string_new(endpart),0,pRm[2*i+2].rm_so),pRm[2*i+2].rm_eo-pRm[2*i+2].rm_so);
			bcc = esc_string(bcc);
                        bcc = g_string_prepend_c(g_string_append_c(bcc,'\"'),'\"');
                        break;
                }
            }
        }
        regfree(pRegex);
        free(pRegex);
        pRegex = NULL;
        free(pRm);
        pRm = NULL;
    } else {
        subject = g_string_new("\"\"");
        cc = g_string_new("\"\"");
        bcc = g_string_new("\"\"");
    }
    launchstr = g_string_new(g_strdup(config.mailer));
    launch = g_strdup((*launchstr).str);
    counter = launch;
    while ((*counter) != '\0') {
        if ((*counter == '%') && (*(counter+1) == 's')){
            launchstr = g_string_erase(launchstr,(counter-launch),2);
            launchstr = g_string_insert(launchstr,(counter-launch),(*subject).str);
            g_free(launch);
            launch = g_strdup((*launchstr).str);
            counter = launch;
        } else if ((*counter == '%') && (*(counter+1) == 't')){
            launchstr = g_string_erase(launchstr,(counter-launch),2);
            launchstr = g_string_insert(launchstr,(counter-launch),toaddr);
            g_free(launch);
            launch = g_strdup((*launchstr).str);
            counter = launch;
        } else if ((*counter == '%') && (*(counter+1) == 'c')){
            launchstr = g_string_erase(launchstr,(counter-launch),2);
            launchstr = g_string_insert(launchstr,(counter-launch),(*cc).str);
            g_free(launch);
            launch = g_strdup((*launchstr).str);
            counter = launch;
        } else if ((*counter == '%') && (*(counter+1) == 'b')){
            launchstr = g_string_erase(launchstr,(counter-launch),2);
            launchstr = g_string_insert(launchstr,(counter-launch),(*bcc).str);
            g_free(launch);
            launch = g_strdup((*launchstr).str);
            counter = launch;
        } else {
            counter++;
        }
    }
        
    g_free(launch);
    launch = g_strdup((*launchstr).str);
    counter = launch;
    while (*counter != '\0') {
       if (*counter == '%'){
            hex[0] = '0';
            hex[1] = 'x';
            hex[2] = *(counter+1);
            hex[3] = *(counter+2);
            hex[4] = '\0';
            hexch = strtol(hex, (char **)NULL, 16);
            launchstr = g_string_erase(launchstr,(counter-launch),3);
            launchstr = g_string_insert_c(launchstr,(counter-launch),hexch);
            g_free(launch);
            launch = g_strdup((*launchstr).str);
            counter = launch;
        } else {
            counter++;
        }
    }
    launchstr = g_string_append(launchstr," &");
    g_free(launch);
    launch = g_strdup((*launchstr).str);
           
    g_string_free(subject, TRUE);
    g_string_free(cc, TRUE);
    g_string_free(bcc, TRUE);
    g_string_free(launchstr, TRUE);
        
    pipe = popen(launch,"r");
    
    if (pipe == NULL) {
	 	g_warning(_("Failed to launch mailer!"));
	   	g_free(launch);
	  	D_RETURN;
    }

    pclose(pipe);
    g_free(launch);     
    g_free(toaddr);
    g_free(endpart);
    g_strfreev(uriparts);
    D_RETURN;
}

static const struct
{
     gchar *ext;
     gint length;
}
types[] =
{
       { ".tar.gz", 7},
       { ".tar.bz2", 8},
       { ".rpm",4},
       { ".deb",4},
       { ".zip", 4},
       { ".bz2", 4},
       { ".gz", 3},
       { ".exe", 4},
       { ".bin", 4},
       { ".mp3", 4},
       { ".mpeg",5},
       { ".mpg",4},
       { ".tar",4},
       { NULL, 0}
};

typedef enum
{
        STRING,
        COMPOUND_TEXT
} SelType;

const GtkTargetEntry selection_types[] =
{
        { "STRING",        0, STRING        },
        { "COMPOUND_TEXT", 0, COMPOUND_TEXT }
};
const gint selection_types_num_targets = (sizeof (selection_types) /
                                          sizeof (GtkTargetEntry));

void set_selection_targets(GtkWidget *window, SkipStone *skipstone)
{
     	D_ENTER;
        gtk_selection_add_targets(GTK_WIDGET(window), GDK_SELECTION_PRIMARY, selection_types, selection_types_num_targets);
     	g_signal_connect(G_OBJECT(window), "selection_get", G_CALLBACK(on_selection_get), skipstone);
     	g_signal_connect(G_OBJECT(window), "selection_received", G_CALLBACK(on_selection_received), skipstone);
     	D_RETURN;
}

gboolean process_uri(const gchar *uri)
{
     gint i;
     gboolean download;
     D_ENTER;
     for (i = 0; types[i].ext != NULL; i++) {	  
     		if (!strcasecmp(uri + strlen (uri) - types[i].length , types[i].ext)) {
	       		download = download_url(uri);
     			D_RETURN_ ( download );
		}
     	}
	D_RETURN_ ( FALSE );
}

gboolean download_url(const gchar *uri)
{
	FILE *pipe;
     	gchar *cmd = g_strdup_printf("%s \"%s\" &", config.downloader, uri);

	D_ENTER;
	if (!config.downloader || !strcmp(config.downloader,"")) {
		     g_warning(_("Configure your download program"));
		     g_free(cmd);
	     	     D_RETURN_( FALSE );
       	}
	
     	if (!config.direct_connection) { /* set proxyes in the env */
	     	if (strlen(config.http_proxy) > 0 && strlen(config.http_proxy_port) > 0) {
		     	gchar *env = g_strdup_printf("%s:%s",config.http_proxy,config.http_proxy_port);
#ifdef HAVE_PUTENV
		     	if (!getenv("http_proxy")) putenv(env);
		     	if (!getenv("HTTP_PROXY")) putenv(env);
#elif defined(HAVE_SETENV)
		     	setenv("http_proxy",env,0);
		     	setenv("HTTP_PROXY",env,0);
#else
#error Need setenv or putenv
#endif		     
		     	g_free(env);
		}
	     	if (strlen(config.ftp_proxy) > 0 && strlen(config.ftp_proxy_port) > 0) {
		     	gchar *env = g_strdup_printf("%s:%s",config.ftp_proxy,config.ftp_proxy_port);
#ifdef HAVE_PUTENV
		     	if (!getenv("ftp_proxy")) putenv(env);
		     	if (!getenv("FTP_PROXY")) putenv(env);
#elif defined(HAVE_SETENV)		     
		     	setenv("ftp_proxy",env,0);
		     	setenv("ftp_proxy",env,0);
#else
#error Need setenv or putenv
#endif		     
		     	g_free(env);
		}
	}
     	
     	pipe = popen(cmd,"r");
     	
     	if (pipe == NULL) {
	     	g_warning(_("Failed to launch downloader!"));
		g_free(cmd);
	     	D_RETURN_ ( FALSE );
	}
     
     	pclose(pipe);
     	g_free(cmd);

	D_RETURN_ ( TRUE );
}
				    
gint progress(SkipStone *skipstone)
{
	gfloat val;
	
     	if (!skipstone->timer) { /* sometimes gtk_timeout_remove does not stop the timeout! */
	     skipstone->is_loading = FALSE;
	     D_RETURN_(  FALSE );
	}

	if (skipstone->progressbar && GTK_IS_PROGRESS(skipstone->progressbar)) {
		val = gtk_progress_get_value(GTK_PROGRESS(skipstone->progressbar));
	     	if (++val > 100)
	       		val = 0;
	     	gtk_progress_set_value(GTK_PROGRESS(skipstone->progressbar), val);
	     	skipstone->is_loading = TRUE;
	     	D_RETURN_ (TRUE);
	} else { 
	     	skipstone->is_loading = FALSE;
		D_RETURN_ ( FALSE );
	}
}


void read_skipstone_config(void) 
{
	FILE *config_file;
	gchar *file, *oldfile;
	gchar *line, tmpstr[1024];
     	gint i, temp;
     	
     	D_ENTER;
     
     	oldfile = g_strconcat(home,"/.skipstonerc", NULL);
     	file = g_strconcat(home,"/.skipstone/config", NULL);
	if (access(oldfile, F_OK) == 0 && access(file, F_OK) == -1 && errno == ENOENT) {
		if (rename(oldfile, file) == 0) {
			g_print(_("Note: .skipstonerc was moved to %s\n"), file);
			g_free(oldfile);
		} else {
			g_warning(_("Error moving .skipstonerc to %s: %s\n"), file, strerror(errno));
			/* we can still read the old file */
			g_free(file); file = oldfile;
		}
	} else {
		g_free(oldfile);
	}

  	/* defaults */   	
     	config.home = g_strdup("http://www.muhri.net/skipstone");
       	config.xsize = 700;
     	config.ysize = 500;
       	config.layout = 0;
     	config.mailer = g_strdup("pronto %t %s %c");
       	config.downloader = g_strdup("skipdownload");
     	config.http_version = g_strdup("1.1");
     	config.max_go = 15;
	config.maxpopupitems = 15;
       	config.bmarktbar = 1;
	config.navbar_buttons = 62;
       	config.navtbar = 1;
	config.lang_font = 0;
	for (i = 0; i < LANG_FONT_NUM; i++) {
	   config.font_size[i] = DEFAULT_FONT_SIZE;
	   config.min_font_size[i] = DEFAULT_MIN_FONT_SIZE;
	   config.serif_font[i]     = g_strdup(DEFAULT_SERIF_FONT);
	   config.sansserif_font[i] = g_strdup(DEFAULT_SANSSERIF_FONT);
	   config.monospace_font[i] = g_strdup(DEFAULT_MONOSPACE_FONT);
	   config.cursive_font[i] = g_strdup(DEFAULT_CURSIVE_FONT);
	   config.fantasy_font[i] = g_strdup(DEFAULT_FANTASY_FONT);
	}
     	config.java = TRUE;
     	config.javascript = TRUE;
     	config.http_proxy = g_strdup("");
	config.ftp_proxy = g_strdup("");
	config.ftp_proxy_port = g_strdup("");
     	config.http_proxy_port = g_strdup("");
     	config.ssl_proxy = g_strdup("");
     	config.ssl_proxy_port = g_strdup("");
     	config.no_proxy_for = g_strdup("localhost");
     	config.images = 0;
     	config.language = 0;
     	config.default_charset = g_strdup("Western (ISO-8859-1)");
     	config.accept_languages = g_strdup("en");/* Enable "en" for default */
     	config.theme = g_strdup("default");
     	config.default_search_engine=g_strdup("http://www.google.com/search?q=");
     	config.respect_sizeto = 1;
     	config.notebook = 0;
     	config.notebook_tabs_pos = 3; /* 1 - right, 2 - top, 3-buttom, 4-left */
     	config.disk_cache = g_strdup("0");
     	config.mem_cache = g_strdup("0");
     	config.use_skipstone_mime = 1;
	config.direct_connection = 1;
     	config.cookie_behavior = 0;
	config.warn_about_cookie = 0;
     	config.show_tabs = 1;
     	config.popup_in_new_window = 0;
     	config.shorten_tabs=0;
     	config.tab_text_length=50;
     	config.use_document_fonts=1;
     	config.use_document_colors=TRUE;
     	config.underline_links=FALSE;
     	config.jump_to_new_tab=0;
     	config.red_while_loading=1;
     	config.remember_signons = 0;
     	config.disable_popups = 0;
     	config.tabs_in_focus_order = 0;
	/*                  */

	config_file = fopen(file,"r");
	if (config_file == NULL) {
	     	set_theme_dirs();
	     	write_skipstone_config();
	        g_free(file);
		D_RETURN;
	}

	line = (gchar *)g_malloc(1024);

	while(fgets(line,1024,config_file) != NULL) {
		line[strlen(line)-1] = '\0';
		if (g_strncasecmp(line,"home=",5) == 0) {
			g_free(config.home);
		     	config.home = g_strdup(line+5);
			if (g_strcasecmp(config.home,"") == 0) {
				g_free(config.home);
				config.home = g_strdup("about:blank");
			}
		} else if (g_strncasecmp(line,"xsize=",6) == 0) {
			config.xsize = atoi(line+6);
		} else if (g_strncasecmp(line,"ysize=",6) == 0) {
			config.ysize = atoi(line+6);
		} else if (g_strncasecmp(line,"layout=",7) == 0) {
			config.layout = atoi(line+7);
		} else if (g_strncasecmp(line,"mailer=",7) == 0) {
		     	g_free(config.mailer);
		     	config.mailer = g_strdup(line+7);
		} else if (g_strncasecmp(line,"downloader=",11) == 0) {
		     	g_free(config.downloader);
		     	config.downloader = g_strdup(line+11);
		} else if (g_strncasecmp(line,"maxpopup=",9) == 0) {
		     	config.maxpopupitems = atoi(line+9);
		} else if (g_strncasecmp(line,"bmarktbar=",10) == 0) {
		     	config.bmarktbar = atoi(line+10);
		} else if (g_strncasecmp(line,"underline_links=",16) == 0) {
		     	config.underline_links = atoi(line+16);
		} else if (g_strncasecmp(line,"navbar_buttons=",15) == 0) {
			config.navbar_buttons = atoi(line+15);
		} else if (g_strncasecmp(line,"navtbar=",8) == 0) {
			config.navtbar = atoi(line+8);
		} else if (g_strncasecmp(line,"lang_font=",10) == 0) {
		     	config.lang_font = atoi(line+10);
		} else if (g_strncasecmp(line,"serif_",6) == 0) {
		     	for (i = 0; i < LANG_FONT_NUM; i++) {
				g_snprintf (tmpstr, 1024, "%s=", lang_font_item[i]);
				if (g_strncasecmp(line+6,tmpstr,strlen(tmpstr)))
					continue;
				g_free(config.serif_font[i]);
				config.serif_font[i] = g_strdup(line+6+strlen(tmpstr));
			};
		} else if (g_strncasecmp(line,"sansserif_",10) == 0) {
		     	for (i = 0; i < LANG_FONT_NUM; i++) {
				g_snprintf (tmpstr, 1024, "%s=", lang_font_item[i]);
				if (g_strncasecmp(line+10,tmpstr,strlen(tmpstr)))
					continue;
		     		g_free(config.sansserif_font[i]);
		     		config.sansserif_font[i] = g_strdup(line+10+strlen(tmpstr));
			};
		} else if (g_strncasecmp(line,"cursive_",8) == 0) {
		     	for (i = 0; i < LANG_FONT_NUM; i++) {
				g_snprintf (tmpstr, 1024, "%s=", lang_font_item[i]);
				if (g_strncasecmp(line+8,tmpstr,strlen(tmpstr)))
					continue;
				g_free(config.cursive_font[i]);
				config.cursive_font[i] = g_strdup(line+8+strlen(tmpstr));
			};
		} else if (g_strncasecmp(line,"fantasy_",8) == 0) {
		     	for (i = 0; i < LANG_FONT_NUM; i++) {
				g_snprintf (tmpstr, 1024, "%s=", lang_font_item[i]);
				if (g_strncasecmp(line+8,tmpstr,strlen(tmpstr)))
					continue;
				g_free(config.fantasy_font[i]);
				config.fantasy_font[i] = g_strdup(line+8+strlen(tmpstr));
			};
		} else if (g_strncasecmp(line,"monospace_",10) == 0) {
		     	for (i = 0; i < LANG_FONT_NUM; i++) {
				g_snprintf (tmpstr, 1024, "%s=", lang_font_item[i]);
				if (g_strncasecmp(line+10,tmpstr,strlen(tmpstr)))
					continue;
				g_free(config.monospace_font[i]);
				config.monospace_font[i] = g_strdup(line+10+strlen(tmpstr));
			};
		} else if (g_strncasecmp(line,"fontsize_",9) == 0) {
		     	for (i = 0; i < LANG_FONT_NUM; i++) {
				g_snprintf (tmpstr, 1024, "%s=", lang_font_item[i]);
				if (g_strncasecmp(line+9,tmpstr,strlen(tmpstr)))
					continue;
				config.font_size[i] = atoi(line+9+strlen(tmpstr));
			};
		} else if (g_strncasecmp(line,"min_fontsize_",13) == 0) {
		     	for (i=0; i < LANG_FONT_NUM; i++) {
			     	g_snprintf(tmpstr,1024,"%s=",lang_font_item[i]);
			     	if (g_strncasecmp(line+13,tmpstr,strlen(tmpstr)))
				    	continue;
				config.min_font_size[i] = atoi(line+13+strlen(tmpstr));
			}
		} else if (g_strncasecmp(line,"java=",5) == 0) {
			temp = atoi(line+5);
		     	if (temp) {
			     	config.java = TRUE;
			} else {
			     	config.java = FALSE;
			}
		} else if (g_strncasecmp(line,"javascript=",11) == 0) {
		     	temp = atoi(line+11);
		     	if (temp) {
			     	config.javascript = TRUE;
			} else {
			     	config.javascript = FALSE;
			}
		} else if (g_strncasecmp(line,"http_proxy=",11) == 0) {
		     	g_free(config.http_proxy);
		     	config.http_proxy = g_strdup(line+11);
		} else if (g_strncasecmp(line,"http_proxy_port=",16) == 0) {
		     	g_free(config.http_proxy_port);
		     	config.http_proxy_port = g_strdup(line+16);
		} else if (g_strncasecmp(line,"ftp_proxy=",10) == 0) {
			g_free(config.ftp_proxy);
			config.ftp_proxy = g_strdup(line+10);
		} else if (g_strncasecmp(line,"ftp_proxy_port=",15) == 0) {
			g_free(config.ftp_proxy_port);
			config.ftp_proxy_port = g_strdup(line+15);		
		} else if (g_strncasecmp(line,"no_proxy_for=",13) == 0) {
		     	g_free(config.no_proxy_for);
		     	config.no_proxy_for = g_strdup(line+13);
		} else if (g_strncasecmp(line,"ssl_proxy=",10) == 0) {
		     	g_free(config.ssl_proxy);
		     	config.ssl_proxy = g_strdup(line+10);
		} else if (g_strncasecmp(line,"ssl_proxy_port=",15) == 0) {
		     	g_free(config.ssl_proxy_port);
		     	config.ssl_proxy_port = g_strdup(line+15);
		} else if (g_strncasecmp(line,"images=",7) == 0) {
		     	config.images = atoi(line+7);
		} else if (g_strncasecmp(line,"language=",9) == 0) {
		     	config.language = atoi(line+9);
		} else if (g_strncasecmp(line,"default_charset=",16) == 0) {
		     	g_free(config.default_charset);
		     	config.default_charset = g_strdup(line+16);
		} else if (g_strncasecmp(line,"accept_languages=",17) == 0) {
		     	g_free(config.accept_languages);
		     	config.accept_languages = g_strdup(line+17);
		} else if (g_strncasecmp(line,"theme=",6) == 0) {
		     	g_free(config.theme);
		     	config.theme = g_strdup(line+6);
		} else if (g_strncasecmp(line,"sizeto=",7) == 0) {
		     	config.respect_sizeto = atoi(line+7);
		} else if (g_strncasecmp(line,"tabbed=",7) == 0) {
		     	config.notebook = atoi(line+7);
		} else if (g_strncasecmp(line,"tabpos=",7) == 0) {
		     	config.notebook_tabs_pos = atoi(line+7);
		} else if (g_strncasecmp(line,"disk_cache=",11) == 0) {
		     	g_free(config.disk_cache);
		     	config.disk_cache = g_strdup(line+11);
		} else if (g_strncasecmp(line,"mem_cache=",10) == 0) {
		     	g_free(config.mem_cache);
		     	config.mem_cache = g_strdup(line+10);
		} else if (g_strncasecmp(line,"use_skipstone_mime=",19) == 0) {
			config.use_skipstone_mime = atoi(line+19);
		} else if (g_strncasecmp(line,"direct_connection=",18) == 0) {
		     	config.direct_connection = atoi(line+18);
		} else if (g_strncasecmp(line,"cookie_behavior=",16) == 0) {
			config.cookie_behavior = atoi(line+16);
		} else if (g_strncasecmp(line,"warn_about_cookie=",18) == 0) {
			config.warn_about_cookie = atoi(line+18);
		} else if (g_strncasecmp(line,"max_go=",7) == 0) {
			config.max_go = atoi(line+7);
		} else if (g_strncasecmp(line,"show_tabs=",10) == 0) {
		     	config.show_tabs = atoi(line+10);
		} else if (g_strncasecmp(line,"popup_in_new_window=",20) == 0) {
		     	config.popup_in_new_window = atoi (line + 20);
		} else if (g_strncasecmp(line,"shorten_tab=", 12) == 0) {
		     	config.shorten_tabs = atoi (line + 12);
		} else if (g_strncasecmp(line,"tab_text_length=",16) == 0) {
		     	config.tab_text_length = atoi (line + 16);
		} else if (g_strncasecmp(line,"use_document_fonts=",19) == 0) {
		     	config.use_document_fonts = atoi(line+19);
		} else if (g_strncasecmp(line,"use_document_colors=",20) == 0) {
		     	config.use_document_colors = atoi(line+20);
		} else if (g_strncasecmp(line,"jump_to_new_tab=",16) == 0) {
		     	config.jump_to_new_tab=atoi(line+16);		
		} else if (g_strncasecmp(line,"red_while_loading=",18) == 0) {
		     	config.red_while_loading=atoi(line+18);		     
		} else if (g_strncasecmp(line,"remember_signons=",17) == 0) {
		     	config.remember_signons = atoi (line + 17);
		} else if (g_strncasecmp(line,"default_search_engine=",22) == 0) {
		     	g_free(config.default_search_engine);
		     	config.default_search_engine = g_strdup(line+22);
		} else if (g_strncasecmp(line,"http_version=",13) == 0) {
		     	g_free(config.http_version);
		     	config.http_version = g_strdup(line+13);
		} else if (g_strncasecmp(line,"disable_popups=",15) == 0) {
		     	config.disable_popups = atoi(line+15);
		} else if (g_strncasecmp(line,"tab_in_focus_order=",19) == 0) {
		     	config.tabs_in_focus_order = atoi(line+19);
		}
	}
	fclose(config_file);
	/* set pixmap dir */
     	set_theme_dirs();
     	/*                */
     	
     	g_free(line);
	g_free(file);
	D_RETURN;
}

static void set_theme_dirs(void)
{
     	gchar *themedir;
	GSList *list;
     	
     	D_ENTER;
     
	if (pixmaps_directories !=NULL) {
	     	for (list = pixmaps_directories; list; list = list->next) {
		     	g_free(list->data);
		}
	     	g_slist_free(pixmaps_directories);
	     	pixmaps_directories = NULL;
	}
     
     	themedir = g_strdup_printf("%s/.skipstone/pixmaps/%s",g_get_home_dir(),config.theme);
     	add_pixmap_directory(themedir);
     	g_free(themedir);

     	themedir = g_strdup_printf("%s/%s",SKIPSTONE_LOCAL_THEME_DIR,config.theme);
     	add_pixmap_directory(themedir);
     	g_free(themedir);

     	themedir = g_strdup_printf("%s/%s",SKIPSTONE_SYSTEM_THEME_DIR,config.theme);
     	add_pixmap_directory(themedir);
     	g_free(themedir);

        themedir = g_strdup_printf("%s/default",SKIPSTONE_LOCAL_THEME_DIR);
        add_pixmap_directory(themedir);
        g_free(themedir);

        themedir = g_strdup_printf("%s/default",SKIPSTONE_SYSTEM_THEME_DIR);
        add_pixmap_directory(themedir);
        g_free(themedir);

     	D_RETURN;
}

void write_skipstone_config(void) 
{
	FILE *config_file;
	gchar *file;
	gint i;

     	D_ENTER;
     
     	file = g_strconcat(home,"/.skipstone/config",NULL);
     	config_file = fopen(file,"w");
	if (config_file == NULL) {
		g_error (_("Cannot write config file!"));
		D_RETURN;
	}

	fprintf(config_file,"home=%s\n",config.home);
	fprintf(config_file,"xsize=%d\n",config.xsize);
	fprintf(config_file,"ysize=%d\n",config.ysize);
	fprintf(config_file,"layout=%d\n",config.layout);
	fprintf(config_file,"mailer=%s\n",config.mailer);
	fprintf(config_file,"downloader=%s\n",config.downloader);	
	fprintf(config_file,"maxpopup=%d\n",config.maxpopupitems);
    	fprintf(config_file,"bmarktbar=%d\n",config.bmarktbar);	
	fprintf(config_file,"navbar_buttons=%d\n",config.navbar_buttons);
	fprintf(config_file,"navtbar=%d\n",config.navtbar);
	fprintf(config_file,"lang_font=%d\n",config.lang_font);     
	for (i=0; i < LANG_FONT_NUM; i++) {
	   fprintf(config_file,"serif_%s=%s\n", lang_font_item[i], config.serif_font[i]);
	   fprintf(config_file,"sansserif_%s=%s\n", lang_font_item[i] , config.sansserif_font[i]);
	   fprintf(config_file,"cursive_%s=%s\n", lang_font_item[i], config.cursive_font[i]);
	   fprintf(config_file,"fantasy_%s=%s\n", lang_font_item[i], config.fantasy_font[i]);
	   fprintf(config_file,"monospace_%s=%s\n", lang_font_item[i], config.monospace_font[i]);
	   fprintf(config_file,"fontsize_%s=%d\n", lang_font_item[i], config.font_size[i]);
	   fprintf(config_file,"min_fontsize_%s=%d\n",lang_font_item[i], config.min_font_size[i]);
	}
	fprintf(config_file,"http_proxy=%s\n",config.http_proxy);
     	fprintf(config_file,"http_proxy_port=%s\n",config.http_proxy_port);
	fprintf(config_file,"ftp_proxy=%s\n",config.ftp_proxy);
	fprintf(config_file,"ftp_proxy_port=%s\n",config.ftp_proxy_port);
     	fprintf(config_file,"ssl_proxy=%s\n",config.ssl_proxy);
     	fprintf(config_file,"ssl_proxy_port=%s\n",config.ssl_proxy_port);
	fprintf(config_file,"images=%d\n",config.images);     
	fprintf(config_file,"language=%d\n",config.language);     
	fprintf(config_file,"default_charset=%s\n",config.default_charset);     
     	fprintf(config_file,"accept_languages=%s\n",config.accept_languages);
     	fprintf(config_file,"sizeto=%d\n",config.respect_sizeto);
     	fprintf(config_file,"tabbed=%d\n",config.notebook);
     	fprintf(config_file,"tabpos=%d\n",config.notebook_tabs_pos);
     	fprintf(config_file,"no_proxy_for=%s\n",config.no_proxy_for);
     	fprintf(config_file,"use_skipstone_mime=%d\n",config.use_skipstone_mime);
	fprintf(config_file,"direct_connection=%d\n",config.direct_connection);
     	fprintf(config_file,"warn_about_cookie=%d\n",config.warn_about_cookie);
	fprintf(config_file,"cookie_behavior=%d\n",config.cookie_behavior);
	fprintf(config_file,"max_go=%d\n",config.max_go);
        fprintf(config_file,"show_tabs=%d\n",config.show_tabs);
     	fprintf(config_file,"popup_in_new_window=%d\n",config.popup_in_new_window);
	fprintf(config_file,"jump_to_new_tab=%d\n",config.jump_to_new_tab);
     	fprintf(config_file,"red_while_loading=%d\n",config.red_while_loading);     
	fprintf(config_file,"default_search_engine=%s\n",config.default_search_engine);
	fprintf(config_file,"http_version=%s\n",config.http_version);
     	fprintf(config_file,"disable_popups=%d\n",config.disable_popups);
     	fprintf(config_file,"tab_in_focus_order=%d\n",config.tabs_in_focus_order);
     
     	if (config.javascript == TRUE) {      
	       	fprintf(config_file,"javascript=1\n");
	} else {
	     	fprintf(config_file,"javascript=0\n");
	} 

     	if (config.java == TRUE) {
	     	fprintf(config_file,"java=1\n");
	} else {
	     	fprintf(config_file,"java=0\n");
	}
     	
     	fprintf(config_file,"theme=%s\n",config.theme);
     	fprintf(config_file,"disk_cache=%s\n",config.disk_cache);
     	fprintf(config_file,"mem_cache=%s\n",config.mem_cache);
	fprintf(config_file,"shorten_tab=%d\n",config.shorten_tabs);
     	fprintf(config_file,"tab_text_length=%d\n",config.tab_text_length);
	fprintf(config_file,"use_document_fonts=%d\n",config.use_document_fonts);
     	fprintf(config_file,"use_document_colors=%d\n",config.use_document_colors);
	fprintf(config_file,"remember_signons=%d\n",config.remember_signons);
	fprintf(config_file,"underline_links=%d\n",config.underline_links);     
     	fclose(config_file);
	g_free(file);

	write_prefixes();
	D_RETURN;
}

void read_history(void) {
	FILE *hist_file;
	gchar *file;
	gchar *line;
	gchar *url;
	
     	D_ENTER;
     
	file = g_strconcat(home,"/.skipstone/history",NULL);
	hist_file = fopen(file,"r");
	if (hist_file == NULL) {
		printf(_("No History file to read!\n"));
		D_RETURN;
	}
	line = (gchar *)g_malloc(1024);

	while(fgets(line,1024,hist_file) != NULL) {
		line[strlen(line)-1] = '\0';
		url = g_strdup(line);
		history = g_slist_append(history,url);
	}

	fclose(hist_file);
	g_free(line);
	g_free(file);
	D_RETURN;
}

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

	for (list = history; list ; list = list->next) {
		fprintf(hist_file,"%s\n",(gchar *)(list->data));
	}
	fclose(hist_file);
	g_free(file);	
	D_RETURN;
}


void read_urls(void) 
{
	FILE *url_file;
	gchar *file;
	gchar *line;
	gchar *url;
	D_ENTER;
     
	file = g_strconcat(home,"/.skipstone/urls",NULL);
	url_file = fopen(file,"r");
	if (url_file == NULL) {
		printf(_("No url file to read\n"));
	        g_free(file);
		D_RETURN;
	}
	line = (gchar *)g_malloc(1024);

	while(fgets(line,1024,url_file) != NULL) {
		line[strlen(line)-1] = '\0';
		url = g_strdup(line);
		combo_urls = g_list_append(combo_urls,url);
	}

	fclose(url_file);
	g_free(line);
	g_free(file);
	D_RETURN;
}

	
void write_urls(void) 
{
	FILE *url_file;
	gchar *file;
       	GList *list;
     	D_ENTER;
	file = g_strconcat(home,"/.skipstone/urls",NULL);
	url_file = fopen(file,"w");
	if (url_file == NULL) {
		g_print(_("Cannot write urls file!"));
	        g_free(file);
		D_RETURN;
	}

	for (list = combo_urls; list ; list = list->next) {
		fprintf(url_file,"%s\n",(gchar *)(list->data));
	}
     
	fclose(url_file);
	g_free(file);	
	D_RETURN;

}


void update_layout(void) 
{
     	GSList *l;
     	D_ENTER;
      	for (l = window_count; l ; l = g_slist_next(l)) {	     	
	     	SkipStone *skipstone = (SkipStone *)l->data;
	     	if (skipstone && skipstone->toolbar !=NULL) {
		        if (config.layout > 0) 
		     {
			create_toolbar(skipstone, 1, TRUE);
		     }else
		     {
 	     		gtk_toolbar_set_style(GTK_TOOLBAR(skipstone->toolbar),config.layout);
			gtk_widget_queue_resize(GTK_WIDGET(skipstone->handlebox));
		     }
		   
		}
	   

	}
	     
     	D_RETURN;
}


void insert_in_combo(gchar *url, SkipStone *skipstone)
{
	gint dontadd;
	gchar *url_in_glist;
	GList *l;

     	D_ENTER;
	dontadd = 0;

	if (url[strlen(url)-1] == '/') {
		url[strlen(url)-1] = '\0';
	}

  	for (l = combo_urls; l; l = l->next) {
		url_in_glist = (gchar *)g_strdup(l->data);

		if (url_in_glist[strlen(url_in_glist)-1] == '/') {
			url_in_glist[strlen(url_in_glist)-1] = '\0';
		}

		if (g_strcasecmp(url_in_glist,url) == 0 ) {
	     		dontadd = 1;
			g_free(url_in_glist);
			break;
		}
		g_free(url_in_glist);
	}
	if (!dontadd) 	{
	     	gint length = g_list_length(combo_urls);
	     	if (length + 1 >  config.maxpopupitems) { /* delete the last item if its more than the configured limit */
		     	combo_urls = g_list_remove(combo_urls, g_list_nth_data(combo_urls,length-1));
		}
		combo_urls = g_list_prepend(combo_urls, url); 	
	     	gtk_combo_set_popdown_strings(GTK_COMBO(skipstone->combo),combo_urls);
	     	write_urls();
	}
	D_RETURN;
}


void make_window_from_popup(GtkWidget *menuitem, SkipStone *skipstone)
{
        gchar *href;
     	D_ENTER;
     	href = g_object_get_data(G_OBJECT(menuitem), "link");
     	make_window(href);          
	D_RETURN;
}

void browse_in_window_from_popup(GtkWidget *menuitem, SkipStone *skipstone) 
{
	gchar *href;
     	D_ENTER;
     	href = g_object_get_data(G_OBJECT(menuitem), "link");
     	_skipstone_load_url(skipstone, href);
	D_RETURN;
}
	    
void download_link_from_popup(GtkWidget *menuitem, SkipStone *skipstone) 
{
	
	gchar *href;
     	D_ENTER;
     
     	href = g_object_get_data(G_OBJECT(menuitem), "link");
     	if (!config.downloader || !href) {
	     D_RETURN;	     
	}

	download_url(href);
	D_RETURN;
}

void save_image_from_popup(GtkWidget *menuitem, SkipStone *skipstone) 
{

	gchar *href, *name;
     	D_ENTER;
       	href = g_object_get_data(G_OBJECT(menuitem), "link");
     	if (!href) {
	     g_print("Could not find href to save image\n");
	     D_RETURN;	     	
	}
	name = g_object_get_data(G_OBJECT(menuitem), "name");
     	save_image(skipstone,href,name);
	D_RETURN;
}

void copy_link_from_popup(GtkWidget *menuitem, SkipStone *skipstone)
{
     	gchar *href;
     	gint selection;
     	D_ENTER;
     	href = g_object_get_data(G_OBJECT(menuitem), "link");
	if (href) {
		if (!skipstone->is_notebook)
			g_object_set_data_full (G_OBJECT(skipstone->window), "clipboard-link",
						  g_strdup(href), (GDestroyNotify) g_free);
		else
			g_object_set_data_full (G_OBJECT(main_window), "clipboard-link",
						  g_strdup(href), (GDestroyNotify) g_free);
	}

     	if (!skipstone->is_notebook) {
	     	selection = gtk_selection_owner_set(skipstone->window, 
						    GDK_SELECTION_PRIMARY,
						    GDK_CURRENT_TIME);
	} else {
       		selection = gtk_selection_owner_set(main_window, 
						    GDK_SELECTION_PRIMARY,
						    GDK_CURRENT_TIME);
	}
     
     	if (!selection) g_warning("Could not set selection\n");     	     
     	D_RETURN;
}
			   
void add_link_from_popup(GtkWidget *menuitem, SkipStone *skipstone)
{
     	gchar *url, *title;
     	D_ENTER;
     	url = g_object_get_data(G_OBJECT(menuitem), "link");
     	title = g_object_get_data(G_OBJECT(menuitem), "linktext");
     	add_bookmark_with_info(title, url, skipstone);
     	D_RETURN;
}
				  

void quit_skipstone(void)
{
     	gchar *file;
     	file = g_strconcat(home,"/.skipstone/running", NULL);
     	
     	D_ENTER;
     
     	unlink(file);
     	g_free(file);
     	/* sometimes NULL values sneak up when getting segvs from mozilla 
	 * so do some checks before writing the config file */
     	if (config.home != NULL && config.xsize && config.ysize && config.mailer != NULL) /* those are enough */            
	     	write_skipstone_config();
     	write_skipstone_plugin_config();
#ifndef WebKit
        mozilla_save_prefs ();
#endif
	if (gtk_main_level() > 0) gtk_main_quit();
	gtk_exit(0); 
	D_RETURN;
}

void write_skipstone_plugin_config(void)
{
     FILE *config;
     gchar *file;
     static gint writing = 0;
     
     D_ENTER;
     
     if (skipstone_plugin_config == NULL || writing) D_RETURN;
     file = g_strconcat(home,"/.skipstone/plugin_config",NULL);
     config = fopen(file,"w");
     if (config == NULL) {
	     g_print(_("Could not write plugin config !!\n"));
	     g_free(file);
	     D_RETURN;
     }
     writing = 1;
     g_hash_table_foreach(skipstone_plugin_config, (GHFunc)skipstone_write_plugin_config,
			  config);
     fclose(config);
     g_free(file);
     writing = 0;
     D_RETURN;
}

void read_bookmarks(void) {
	FILE *bookmark_file;
	gchar *file;
	gchar *line;
	BookmarkData *root;
     	
     	D_ENTER;

	root = g_new0(BookmarkData,1);

	root->label = NULL;
	root->url = NULL;

	bookmarks = g_node_new(root);


	file = g_strconcat(home,"/.skipstone/bookmarks",NULL);
	bookmark_file = fopen(file,"r");
	if (bookmark_file == NULL) {
	     	printf(_("No bookmarks file to read, creating default\n"));
		bookmark_file = fopen(file,"w");
		fprintf(bookmark_file,"folder menu\n/folder\nfolder toolbar\n");
	     	fprintf(bookmark_file,"url http://www.freshmeat.net freshmeat.net\n");
	       	fprintf(bookmark_file,"url http://slashdot.org Slashdot\n");
	     	fprintf(bookmark_file,"folder Mozilla\n");
	     	fprintf(bookmark_file,"url http://mozillazine.org/ MozillaZine\nurl http://mozilla.org Mozilla's site\nurl http://bugzilla.mozilla.org BugZilla\n");
	     	fprintf(bookmark_file,"/folder\n");
	     	fprintf(bookmark_file,"url http://google.com Google\n");
	     	fprintf(bookmark_file,"url http://muhri.net Muhri.net\n");
	     	fprintf(bookmark_file,"/folder\n");											     	
		fclose(bookmark_file);
		read_bookmarks();
		g_free(file);
		D_RETURN;
	}
	line = (gchar *)g_malloc(1024);

	while(fgets(line,1024,bookmark_file) != NULL) {
		line = g_strstrip(line);

		if (strcmp(line,"") == 0) {
			continue;
		}

		if (g_strncasecmp(line,"folder",6) == 0) {
			gchar *label = g_strdup(line+7);
			read_bookmark_folder(bookmark_file,label,bookmarks);
		}
	}

	fclose(bookmark_file);
	g_free(line);
	g_free(file);
	D_RETURN;
}

void setup_escape_key_handler(GtkWidget *window)
{	
     	D_ENTER;
     	g_signal_connect(G_OBJECT(window), "key_press_event",
			   G_CALLBACK(escape_key_handler),
			   NULL);
     	D_RETURN;
}

gint escape_key_handler(GtkWidget *window, GdkEventKey *ev)
{
     	D_ENTER;
     	g_return_val_if_fail(window != NULL, FALSE);
     	if (ev->keyval == GDK_Escape) {
       		gtk_widget_destroy(window);
	     	D_RETURN_( 1 );
	}
     	D_RETURN_(0);
}


static void read_bookmark_folder(FILE *bookmark_file,gchar *label,GNode *parent) {
	gint i = 1;
	gchar *line;
	BookmarkData *data;
	GNode *node;

     	D_ENTER;
     	
	data = g_new0(BookmarkData,1);
	data->label = label;
	data->url = NULL;
	data->type = 0;

	node = g_node_append_data(parent,data);

	line = (gchar *)g_malloc(1024);

	while (i == 1) {
		if (fgets(line,1024,bookmark_file) == NULL) {
		     g_warning(_("Error in bookmarks file - EOF while reading a folder\n"));
		     i = 0;
		     continue;
		}
			       
		line = g_strstrip(line);

		if (g_strncasecmp(line,"/folder",7) == 0) {
			i = 0;
			continue;
		}

		if (g_strncasecmp(line,"folder",6) == 0) {
			gchar *label = g_strdup(line+7);
			read_bookmark_folder(bookmark_file,label,node);
		}

		if (g_strncasecmp(line,"url",3) == 0) {
			gchar **temp;
			BookmarkData *url;

			url = g_new0(BookmarkData,1);
			temp = g_strsplit(line+4," ",2);
			url->url = g_strdup(temp[0]);

			if (temp[1] != NULL)
				url->label = g_strdup(temp[1]);
			else
				url->label = g_strdup(temp[0]);
			url->type = 1;
			g_strfreev(temp);

			g_node_append_data(node,url);
		}

		if (g_strncasecmp(line,"sep",3) == 0) {
			BookmarkData *sep;

			sep = g_new0(BookmarkData,1);
			sep->label = NULL;
			sep->url = NULL;
			sep->type = 2;
			g_node_append_data(node,sep);
		}	
	}

	g_free(line);

	D_RETURN;
}

void write_bookmarks(void) {
	FILE *file;
	gchar *path;
	
     	D_ENTER;
     
	path = g_strconcat(home,"/.skipstone/bookmarks",NULL);
	file = fopen(path,"w");

	print_bookmarks(file);

	fclose(file);
	D_RETURN;
}

static void print_bookmarks(FILE *file) {
     	D_ENTER;
	if (bookmarks != NULL) 
		g_node_children_foreach(bookmarks,G_TRAVERSE_ALL,(GNodeForeachFunc)print_node_data,file);	
	D_RETURN;
}

static void print_node_data(GNode *node,FILE *file) {	
     	BookmarkData *data;
     	
     	D_ENTER;
     	
     	data = node->data;

	switch (data->type) {
		case 0:
			fprintf(file,"folder %s\n",data->label);
			g_node_children_foreach(node,G_TRAVERSE_ALL,(GNodeForeachFunc)print_node_data,file);
			fprintf(file,"/folder\n");
			break;
		case 1:
			fprintf(file,"url %s %s\n",data->url,data->label);
			break;
		case 2:
			fprintf(file,"sep\n");
			break;
		default:
			break;
	}

	D_RETURN;
}

void read_prefixes(void)
{
	FILE *prefix_file;
	gchar *file;
	gchar *line;
	
     	D_ENTER;
     
	file = g_strconcat(home,"/.skipstone/prefixes",NULL);
	prefix_file = fopen(file,"r");

	if (prefix_file == NULL) {
		printf(_("No prefixes file to read (adding defaults)\n"));
		
		prefix_file = fopen(file,"w");
		
		if (prefix_file == NULL) {
			printf(_("Couldn't open prefix file for writing!\n"));
			g_free(file);
			D_RETURN;
		}
		
		fprintf(prefix_file,"fm:^^^http://www.freshmeat.net/search/?q=%%s\n");
		fprintf(prefix_file,"google:^^^http://www.google.com/search?q=%%s\n");
		fprintf(prefix_file,"yahoo:^^^http://search.yahoo.com/bin/search?p=%%s\n");
		fclose(prefix_file);
		read_prefixes();
		g_free(file);
		D_RETURN;
	}
	line = (gchar *)g_malloc(1024);

	while (fgets(line,1024,prefix_file) != NULL) {
		gchar *url;
		SkipPrefix *prefix;

		line = g_strstrip(line);

		if (strcmp(line,"") == 0) {
			continue;
		}

		prefix = g_new0(SkipPrefix,1);
	
		url = strstr(line,"^^^");
		url[0] = '\0';
		url += 3;
	
		prefix->prefix = g_strdup(line);
		prefix->url = g_strdup(url);
	
		prefixes = g_slist_prepend(prefixes,prefix);
	}

	fclose(prefix_file);
	g_free(line);
	g_free(file);
	D_RETURN;
}

void write_prefixes(void)
{
	FILE *prefix_file;
	gchar *file;
	GSList *l;
	
     	D_ENTER;
     
	file = g_strconcat(home,"/.skipstone/prefixes",NULL);
	prefix_file = fopen(file,"w");
	if (prefix_file == NULL) {
		g_free(file);
		printf(_("Couldn't open prefixes file for writing!\n"));
		D_RETURN;
	}

	for (l = prefixes; l; l = l->next) {
		SkipPrefix *prefix = l->data;

		fprintf(prefix_file,"%s^^^%s\n",prefix->prefix,prefix->url);
	}

	fclose(prefix_file);
	g_free(file);

	D_RETURN;
}


GtkWidget* create_dummy_pixmap(GtkWidget *widget)
{
  	GdkColormap *colormap;
  	GdkPixmap *gdkpixmap;
  	GdkBitmap *mask;
  	GtkWidget *pixmap;
	
     	D_ENTER;
     
  	colormap = gtk_widget_get_colormap (widget);
  	gdkpixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &mask,
                                                     NULL, dummy_pixmap_xpm);
  	if (gdkpixmap == NULL)
  	  g_error (_("Couldn't create replacement pixmap."));
	  pixmap = gtk_pixmap_new (gdkpixmap, mask);
  	gdk_pixmap_unref (gdkpixmap);
  	gdk_bitmap_unref (mask);
  	
     	D_RETURN_ (pixmap);
}


static void add_pixmap_directory(const gchar *directory)
{
     	D_ENTER;
     	pixmaps_directories = g_slist_append (pixmaps_directories,
					       g_strdup (directory));
     	D_RETURN;
}

static gchar* check_file_exists(const gchar *directory,const gchar *filename)
{
  	gchar *full_filename;
  	struct stat s;
  	gint status;
	
     	D_ENTER;
     
  	full_filename = (gchar*) g_malloc (strlen (directory) + 1
        	                             + strlen (filename) + 1);
  	strcpy (full_filename, directory);
  	strcat (full_filename, G_DIR_SEPARATOR_S);
  	strcat (full_filename, filename);

  	status = stat (full_filename, &s);
  	if (status == 0 && S_ISREG (s.st_mode))
    		D_RETURN_ ( full_filename );
  	g_free (full_filename);
  	D_RETURN_ ( NULL );
}


GtkWidget* create_pixmap(GtkWidget *widget, const gchar *filename, gint *loaded)
{
  	gchar *found_filename = NULL;
  	GtkWidget *pixmap;
  	GSList *elem;
     
     	D_ENTER;

  	if (!filename || !filename[0]) {
	       *loaded = 0;
      		D_RETURN_( create_dummy_pixmap (widget) );
	}
  	/* We first try any pixmaps directories set by the application. */
  	elem = pixmaps_directories;
  	while (elem) {
      		found_filename = check_file_exists ((gchar*)elem->data, filename);
      		if (found_filename)
        		break;
      			elem = elem->next;
    	}

  	/* If we haven't found the pixmap, try the source directory. */
  	if (!found_filename)
    	{
      		found_filename = check_file_exists ("../pixmaps", filename);
	}

  	if (!found_filename)
    	{
      		g_warning (_("Couldn't find pixmap file: %s"), filename);
	        *loaded = 0;
      	       	D_RETURN_( create_dummy_pixmap (widget) );
    	}

        pixmap = gtk_image_new_from_file(found_filename);

        if (pixmap == NULL || !GTK_IS_IMAGE(pixmap)) {
	     	g_warning(_("Error loading pixmap file: %s"), found_filename);
	        loaded = 0;
	     	g_free(found_filename);
	     	D_RETURN_( create_dummy_pixmap(widget) );
	}
  
	g_free (found_filename);
        *loaded = 1;
  	D_RETURN_(pixmap);
}

GtkWidget* create_tab_animation(GtkWidget *widget)
{
  	gchar *found_filename = NULL;
        gchar *filename = "tab_loading.gif";
  	GtkWidget *pixmap = NULL;
  	GSList *elem = NULL;
        GdkPixbufAnimation *p = NULL;
     	D_ENTER;


  	/* We first try any pixmaps directories set by the application. */
  	elem = pixmaps_directories;
  	while (elem) {
      		found_filename = check_file_exists ((gchar*)elem->data, filename);
      		if (found_filename)
        		break;
      			elem = elem->next;
    	}

  	/* If we haven't found the pixmap, try the source directory. */
  	if (!found_filename)
    	{
      		found_filename = check_file_exists ("../pixmaps", filename);
	}

  	if (!found_filename)
    	{
      		g_warning (_("Couldn't find pixmap file: %s"), filename);
      	       	D_RETURN_( create_dummy_pixmap (widget) );
    	}

        p = gdk_pixbuf_animation_new_from_file(found_filename,NULL);
        pixmap =  gtk_image_new_from_animation (p);
        g_object_unref(p);

        if (pixmap == NULL || !GTK_IS_IMAGE(pixmap)) {
	     	g_warning(_("Error loading pixmap file: %s"), found_filename);
	     	g_free(found_filename);
	     	D_RETURN_( create_dummy_pixmap(widget) );
	}
  
	g_free (found_filename);
  	D_RETURN_(pixmap);
}



GtkWidget* create_pixmap_from_path(gchar *dir, gchar *theme_dir, GtkWidget *menu_item)
{

     	GtkWidget *pixmap;
	gchar *fullpath;
     	
     	D_ENTER;
     
     	fullpath = g_strconcat(dir,"/",theme_dir,"/back.png",NULL);
        pixmap = gtk_image_new_from_file(fullpath);
     
     	if (pixmap == NULL || !GTK_IS_IMAGE(pixmap)) {
	     	g_warning(_("Error loading pixmap file: %s"), fullpath);
	     	g_free(fullpath);
	     	D_RETURN_( create_dummy_pixmap(menu_item) );
	}
  
     	g_free(fullpath);   
     	D_RETURN_( pixmap );
}
     
void switch_theme(GtkWidget *menu_item, gchar *theme)
{
	GSList *l;
     	
     	D_ENTER;
     
     	g_free(config.theme);
     	config.theme = g_strdup(theme);
     	set_theme_dirs();
     	for (l=window_count; l; l=l->next) {
	     SkipStone *skipstone = (SkipStone *)l->data;
	     if (skipstone)
		     create_toolbar(skipstone,1,TRUE);
	}      
     	
     	D_RETURN;
}
		  
void set_mozilla_prefs(void)
{
#ifndef WebKit   
     	gchar **font;
     	gint i, disk_cache, mem_cache, lang_length;
	gchar *cachedir, *default_charset, tmpstr[1024], *user_agent;
  
     	D_ENTER;
     		
     	mozilla_preference_set_boolean ("security.warn_entering_secure", FALSE);
     	mozilla_preference_set_boolean ("security.warn_leaving_secure", FALSE);
     	mozilla_preference_set_boolean ("security.warn_submit_insecure", FALSE);
     	mozilla_preference_set_boolean ("security.warn_viewing_mixed", FALSE);
        mozilla_preference_set_boolean ("print.show_print_progress", FALSE);
     	mozilla_preference_set_boolean ("dom.disable_open_during_load", config.disable_popups);
     
     	mozilla_preference_set_boolean("nglayout.widget.gfxscrollbars", FALSE);
     	user_agent = g_strdup_printf("SkipStone %d.%d.%d", SKIPSTONE_MAJOR, SKIPSTONE_MINOR, SKIPSTONE_MICRO);
     	mozilla_preference_set ("general.useragent.misc", user_agent);
     	g_free(user_agent);
     	mozilla_preference_set_int("network.image.imageBehavior",config.images);
     	mozilla_preference_set("network.http.version",config.http_version);	
	mozilla_preference_set ("intl.charset.detector", autodetect_charset_prefs[config.language]);	
	default_charset = get_bracketed_string(config.default_charset);	
	if (default_charset)
	{
     		mozilla_preference_set ("intl.charset.default", default_charset);
		g_free(default_charset);
	}
	
	lang_length = strlen(config.accept_languages);
	
	if (lang_length > 0)
	{
     		mozilla_preference_set ("intl.accept_languages", config.accept_languages);
	}
     	
	/* cookies */
	mozilla_preference_set_int("network.cookie.cookieBehavior",config.cookie_behavior);
	mozilla_preference_set_boolean("network.cookie.warnAboutCookies",config.warn_about_cookie);
       
	disk_cache = atoi(config.disk_cache);
     	mem_cache = atoi(config.mem_cache);

	for (i = 0; i < LANG_FONT_NUM; i++) {

	   if (!strncmp(config.serif_font[i],"-",1)) {

		font = g_strsplit(config.serif_font[i],"-",-1);
		g_snprintf (tmpstr, 1024, "font.name.serif.%s", lang_font_item[i]);
		mozilla_preference_set(tmpstr,
				  g_strconcat(font[1],"-",font[2],"-",font[13],"-",font[14],NULL));
		g_strfreev(font);
	   } else {
//		gchar *s = strrchr(config.serif_font[i], ' ');
//		*s = '\0';
		g_snprintf(tmpstr, 1024, "font.name.serif.%s", lang_font_item[i]);
		
		mozilla_preference_set(tmpstr, g_strdup(config.serif_font[i]));
	   }
	     
	   if (!strncmp(config.sansserif_font[i], "-",1)) {
		font = g_strsplit(config.sansserif_font[i],"-",-1);
		g_snprintf (tmpstr, 1024, "font.name.sans-serif.%s", lang_font_item[i]);
		mozilla_preference_set(tmpstr,
				  g_strconcat(font[1],"-",font[2],"-",font[13],"-",font[14],NULL));
		g_strfreev(font);
	   } else {
//		gchar *s = strrchr(config.sansserif_font[i], ' ');
//		*s = '\0';
		g_snprintf(tmpstr, 1024, "font.name.sans-serif.%s", lang_font_item[i]);
		mozilla_preference_set(tmpstr, g_strdup(config.sansserif_font[i]));
	   }

	   if (!strncmp(config.cursive_font[i],"-",1)) {
		font = g_strsplit(config.cursive_font[i],"-",-1);
		g_snprintf (tmpstr, 1024, "font.name.cursive.%s", lang_font_item[i]);
		mozilla_preference_set(tmpstr,
				  g_strconcat(font[1],"-",font[2],"-",font[13],"-",font[14],NULL));
		g_strfreev(font);
	   } else {
//		gchar *s = strrchr(config.cursive_font[i], ' ');
//		*s = '\0';

		g_snprintf(tmpstr, 1024, "font.name.cursive.%s", lang_font_item[i]);
		mozilla_preference_set(tmpstr, g_strdup(config.cursive_font[i]));
	   }
	   if (!strncmp(config.fantasy_font[i],"-",1)) {
		font = g_strsplit(config.fantasy_font[i],"-",-1);
		g_snprintf (tmpstr, 1024, "font.name.fantasy.%s", lang_font_item[i]);
		mozilla_preference_set(tmpstr,
				  g_strconcat(font[1],"-",font[2],"-",font[13],"-",font[14],NULL));
		g_strfreev(font);
	   } else {
//		gchar *s = strrchr(config.fantasy_font[i], ' ');
//		*s = '\0';

		g_snprintf(tmpstr, 1024, "font.name.fantasy.%s", lang_font_item[i]);
		mozilla_preference_set(tmpstr, g_strdup(config.fantasy_font[i]));
	   }
	   if (!strncmp(config.monospace_font[i],"-",1)) {	      
		font = g_strsplit(config.monospace_font[i],"-",-1);
		g_snprintf (tmpstr, 1024, "font.name.monospace.%s", lang_font_item[i]);
		mozilla_preference_set(tmpstr,
				  g_strconcat(font[1],"-",font[2],"-",font[13],"-",font[14],NULL));

		g_snprintf (tmpstr, 1024, "font.size.fixed.%s", lang_font_item[i]);
		mozilla_preference_set_int(tmpstr,atoi(font[7]));
		g_strfreev(font);
	   } else {
//		gchar *s = strrchr(config.monospace_font[i], ' ');
//		*s = '\0';

		 g_snprintf (tmpstr, 1024, "font.name.monospace.%s", lang_font_item[i]);
		 mozilla_preference_set(tmpstr, g_strdup(config.monospace_font[i]));
	   }	
	     g_snprintf (tmpstr, 1024, "font.size.variable.%s", lang_font_item[i]);
	     mozilla_preference_set_int(tmpstr,config.font_size[i]);
	     
	     g_snprintf(tmpstr, 1024, "font.min-size.variable.%s", lang_font_item[i]);
	     mozilla_preference_set_int(tmpstr, config.min_font_size[i]);
	     
	}

     	mozilla_preference_set_int("browser.display.use_document_fonts", config.use_document_fonts);
	mozilla_preference_set_boolean ("browser.display.use_document_colors", config.use_document_colors);
     	mozilla_preference_set_boolean ("browser.underline_anchors", config.underline_links);
	mozilla_preference_set_boolean ("security.enable_java", config.java);
        mozilla_preference_set_boolean ("javascript.enabled", config.javascript);
     	mozilla_preference_set_boolean ("browser.view_source.syntax_highlight", TRUE);
	cachedir = g_strconcat(home,"/.skipstone/cache",NULL);
	mkdir(cachedir,0755);
	mozilla_preference_set("browser.cache.directory",cachedir);
	g_free(cachedir);
	if ((disk_cache > 0) || (mem_cache > 0)) {
       		mozilla_preference_set_boolean("browser.cache.disk.enable",TRUE);
	     	mozilla_preference_set_boolean("browser.cache.enable", TRUE);
	}
     	else
       {
       		mozilla_preference_set_boolean("browser.cache.disk.enable",FALSE);
	       	mozilla_preference_set_boolean("browser.cache.enable", FALSE);
       }
     	if (disk_cache > 0) {
       	        mozilla_preference_set_boolean("browser.cache.disk.enable",TRUE);
	     	mozilla_preference_set_int("browser.cache.disk_cache_size",disk_cache);
	     	mozilla_preference_set_int("browser.cache.disk.capacity",disk_cache);
	}
	else 
       {
       	        mozilla_preference_set_boolean("browser.cache.disk.enable",FALSE);
	     	mozilla_preference_set_int("browser.cache.disk_cache_size", 0);
	    	mozilla_preference_set_int("browser.cache.disk.capacity",0);
	}
     	
     	if (mem_cache > 0)  {
		mozilla_preference_set_int("browser.cache.memory_cache_size",mem_cache);
	     	mozilla_preference_set_int("browser.cache.memory.capacity",mem_cache);
	} else {
		mozilla_preference_set_int("browser.cache.memory_cache_size", 0);   
	     	mozilla_preference_set_int("browser.cache.memory.capacity",0);
	}
     	mozilla_preference_set_boolean("signon.rememberSignons",config.remember_signons);
     	mozilla_preference_set("keyword.URL",config.default_search_engine);
				 
     	/* set proxy stuff */
     	skipstone_set_proxy_prefs();

        mozilla_save_prefs ();
#endif
     	D_RETURN;
}


static void skipstone_set_proxy_prefs(void)
{
#ifndef WebKit   
 	gint network_type = 0;
     	
     	D_ENTER;
     
     	if (config.direct_connection) {
		mozilla_preference_set("network.proxy.http","");
	     	mozilla_preference_set("network.proxy.ssl","");
	     	mozilla_preference_set("network.proxy.ftp","");
	     	mozilla_preference_set("network.proxy.no_proxies_on", " ");
	     	mozilla_preference_set_int("network.proxy.type",network_type);
	     	D_RETURN;
	}
       
     	if (strlen(config.http_proxy) != 0 && strcmp(config.http_proxy,"") != 0 && strlen(config.http_proxy_port) > 0 && strcmp(config.http_proxy_port,"") != 0) {
	     	mozilla_preference_set_int ("network.proxy.type", 1);
		network_type=1;
	     	mozilla_preference_set ("network.proxy.http", config.http_proxy);
	     	mozilla_preference_set_int ("network.proxy.http_port", atoi(config.http_proxy_port));		
	}
	
	if (strlen(config.ftp_proxy) != 0 && strcmp(config.ftp_proxy,"") != 0 && strlen(config.ftp_proxy_port) > 0 && strcmp(config.http_proxy_port,"") != 0) {
	        if (!network_type)
		  mozilla_preference_set_int("network.proxy.type", 1);
		mozilla_preference_set ("network.proxy.ftp", config.ftp_proxy);
	     	mozilla_preference_set_int ("network.proxy.ftp_port", atoi(config.ftp_proxy_port));
	}

	if (strlen(config.ssl_proxy) != 0 && strcmp(config.ssl_proxy,"") != 0 && strlen(config.ssl_proxy_port) > 0 && strcmp(config.ssl_proxy_port,"") != 0) {
	        if (!network_type)
		  mozilla_preference_set_int("network.proxy.type", 1);
		mozilla_preference_set ("network.proxy.ssl", config.ssl_proxy);
	     	mozilla_preference_set_int ("network.proxy.ssl_port", atoi(config.ssl_proxy_port));
	}

	
	if (strlen(config.no_proxy_for) != 0)
	     mozilla_preference_set("network.proxy.no_proxies_on", config.no_proxy_for);
	else
	     mozilla_preference_set("network.proxy.no_proxies_on", " ");
#endif   
     	D_RETURN;
}

/**
 * get_bracketed_string: get the string between brackets. ex: language (string)
 */
gchar * get_bracketed_string (gchar *str)
{
	gchar *begin;
	gchar *end;
	
     	D_ENTER;
     
	begin = strchr (str,'(');
	end = strchr (str,')');

	if (begin && end)
	{
		begin ++;
		D_RETURN_( g_strndup(begin, end - begin) );
	}
	else 
	{
		D_RETURN_(NULL);
	}
}
