/********************** modified from t2.c *******************/
/********************* menu.c ********************************/

#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <sys/types.h>
#ifdef SYS_DIR
#include <sys_dir.h>
#else
#ifdef NDIR
#include <ndir.h>
#else
#include <dirent.h>
#endif
#endif

#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>

#include <stdlib.h>

#include <gtk/gtk.h>

#include <libintl.h>

#include "mandata.h"
#include "util.h"
#include "gman.h"
#include "list.h"
#include "task.h"
#include "window2.h"
#include "taskfunc.h"

static int print_hello(GtkWidget *w, gpointer data);
static int test_callback(GtkWidget *w, gpointer data);
static int window_resize_callback(GtkWidget *w, GtkAllocation *size, gpointer data);
static int section_policy_callback(GtkWidget *w, gpointer data);
static int section_select_callback(GtkWidget *w, gpointer data);
static int status_bar_callback (GtkWidget *widget, gpointer   data);
static int search_mode_callback (GtkWidget *widget, gpointer   data);
static int show_mode_callback(GtkWidget *w, gpointer data);
static void app_quit(GtkWidget *w, gpointer data);
static void select_row_callback(GtkWidget *, gint, gint, GdkEventButton *, gpointer);
static void select_row_callback3(GtkWidget *, gint, gint, GdkEventButton *, gpointer);
static void entry_activate_callback(GtkWidget *,gpointer);
static void entry_changed_callback(GtkWidget *,gpointer);
static void window_help_about_callback (GtkWidget *widget, gpointer   data);
static void entry4_activate_callback(GtkWidget *,gpointer);
static void entry4_changed_callback(GtkWidget *,gpointer);
static int button_clicked_callback(GtkWidget *,gpointer);

#define MAX_PATHS 10

#define MENU_DISPLAY_POSITION 201
#define MENU_NEXT_POSITION 202

#define _(string) gettext(string)

static GtkItemFactoryEntry menu_items[] = {
  {"/_File",         NULL,         NULL, 0, "<Branch>"},
  {"/File/_Quit",     "<control>Q", (void (*)(...))app_quit, 0, NULL},
  {"/_Sections", 		 NULL,         NULL, 0, "<Branch>"},
  {"/Sections/tearoff1", NULL,      NULL,       0, "<Tearoff>" },
  {"/Sections/_All",    NULL, 			(void (*)(...))section_policy_callback, 0, "<RadioItem>"},
  {"/Sections/all _But",   NULL, 		(void (*)(...))section_policy_callback, 1, "/Sections/All"},
  {"/Sections/_Only",   NULL, 			(void (*)(...))section_policy_callback, 2, "/Sections/All"},
  {"/Sections/sep1",	NULL,			NULL,		0,			"<Separator>"},
  {"/Sections/_1: User Commands",	NULL,	(void (*)(...))section_select_callback,	1<<0,	"<CheckItem>"},
  {"/Sections/_2: System Calls",	NULL,	(void (*)(...))section_select_callback, 1<<1,	"<CheckItem>"},
  {"/Sections/_3: Subroutines",		NULL,	(void (*)(...))section_select_callback, 1<<2,	"<CheckItem>"},
  {"/Sections/_4: Devices",			NULL,	(void (*)(...))section_select_callback,	1<<3,	"<CheckItem>"},
  {"/Sections/_5: File Formats",	NULL,	(void (*)(...))section_select_callback,	1<<4,	"<CheckItem>"},
  {"/Sections/_6: Games",			NULL,	(void (*)(...))section_select_callback,	1<<5,	"<CheckItem>"},
  {"/Sections/_7: Miscellaneous",	NULL,	(void (*)(...))section_select_callback,	1<<6,	"<CheckItem>"},
  {"/Sections/_8: Sys.Administration",NULL,	(void (*)(...))section_select_callback,	1<<7,	"<CheckItem>"},
  {"/Sections/_l: Local",			NULL,	(void (*)(...))section_select_callback,	1<<8,	"<CheckItem>"},
  {"/Sections/_n: New",				NULL,	(void (*)(...))section_select_callback,	1<<9,	"<CheckItem>"},
  {"/_View",      NULL,         NULL, 0, "<Branch>"},
  {"/View/x_Term",		"<control>T",	(void (*)(...))show_mode_callback, 0,	"<RadioItem>"},
  {"/View/_GhostView",		"<control>G",	(void (*)(...))show_mode_callback, 1,	"/View/xTerm"},
  {"/View/_LocalBrowse",		"<control>L",	(void (*)(...))show_mode_callback, 2,	"/View/xTerm"},
  {"/View/_NetBrowse",		"<control>N",	(void (*)(...))show_mode_callback, 3,	"/View/xTerm"},
  {"/_Options",      NULL,         NULL, 0, "<Branch>"},
  {"/Options/Status bar",		NULL,	(void (*)(...))status_bar_callback, 0,	"<CheckItem>"},
  {"/Options/sep1",     NULL,         NULL, 0, "<Separator>"},
  {"/Options/_Index search",    "<control>I",	(void (*)(...))search_mode_callback, 0, "<RadioItem>"},
  {"/Options/_Key word search",   "<control>K", (void (*)(...))search_mode_callback, 1, "/Options/Index search"},
  {"/Options/sep2",     NULL,         NULL, 0, "<Separator>"},
  {"/Options/Man _Paths...",    NULL, 	(void (*)(...))edit_paths_callback, 0, NULL},
  //  {"/Options/Test",  NULL,         (void (*)(...))test_callback, 0, NULL},
  {"/_Help",         NULL,         NULL, 0, "<LastBranch>"},
  {"/_Help/About",   NULL,         GTK_SIGNAL_FUNC(window_help_about_callback),0,NULL}
};

/********************* init_main_window *************************/

GtkWidget * clist;
GtkWidget * entry;
GtkWidget * clist3;
GtkWidget * window;		//main window
GtkTooltips * tooltips;

GtkWidget * section_buttons[MAX_MAN_SECTION];
GtkWidget * section_select[3];
GtkWidget * searching_mode_buttons[2];
GtkWidget * show_mode_buttons[4];
GtkWidget * status_bar_button;

int signal_select_row;	//used by select_row_callback() to decide whether to active man pages
int signal_entry_change; //used by entry_changed_callback() to decide whether to refresh list
int signal_menu_change; //used by menu_item callback to decide whether to take action or not
Dictionary * man_paths;
char * *man_items_buffer;
int man_items_count;
int clist_selected_row;
List * man_paths_to_be_load;
char * keyword;

void updata_menu_buttons(int);

void get_main_menu(GtkWidget *window, GtkWidget ** menubar) {
	int nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
	GtkItemFactory *item_factory;
	GtkAccelGroup *accel_group;

	accel_group = gtk_accel_group_new();

	/* This function initializes the item factory.
	   Param 1: The type of menu - can be GTK_TYPE_MENU_BAR, GTK_TYPE_MENU,
	            or GTK_TYPE_OPTION_MENU.
		Param 2: The path of the menu.
		Param 3: A pointer to a gtk_accel_group.  The item factory sets up
              the accelerator table while generating menus.
	*/

	item_factory = gtk_item_factory_new(GTK_TYPE_MENU_BAR, "<main>", 
										accel_group);

  /* This function generates the menu items. Pass the item factory,
     the number of items in the array, the array itself, and any
     callback data for the the menu items. */
	gtk_item_factory_create_items(item_factory, nmenu_items, menu_items, NULL);

  /* Attach the new accelerator group to the window. */
	gtk_accel_group_attach (accel_group, GTK_OBJECT (window));

	if (menubar)
	/* Finally, return the actual menu bar created by the item factory. */ 
		*menubar = gtk_item_factory_get_widget(item_factory, "<main>");
	section_select[0] = gtk_item_factory_get_widget(item_factory, "/Sections/All");
	section_select[1] = gtk_item_factory_get_widget(item_factory, "/Sections/all But");
	section_select[2] = gtk_item_factory_get_widget(item_factory, "/Sections/Only");
	section_buttons[0] = gtk_item_factory_get_widget(item_factory, "/Sections/1: User Commands");
	section_buttons[1] = gtk_item_factory_get_widget(item_factory, "/Sections/2: System Calls");
	section_buttons[2] = gtk_item_factory_get_widget(item_factory, "/Sections/3: Subroutines");
	section_buttons[3] = gtk_item_factory_get_widget(item_factory, "/Sections/4: Devices");
	section_buttons[4] = gtk_item_factory_get_widget(item_factory, "/Sections/5: File Formats");
	section_buttons[5] = gtk_item_factory_get_widget(item_factory, "/Sections/6: Games");
	section_buttons[6] = gtk_item_factory_get_widget(item_factory, "/Sections/7: Miscellaneous");
	section_buttons[7] = gtk_item_factory_get_widget(item_factory, "/Sections/8: Sys.Administration");
	section_buttons[8] = gtk_item_factory_get_widget(item_factory, "/Sections/l: Local");
	section_buttons[9] = gtk_item_factory_get_widget(item_factory, "/Sections/n: New");
	searching_mode_buttons[0] = gtk_item_factory_get_widget(item_factory, "/Options/Index search");
	searching_mode_buttons[1] = gtk_item_factory_get_widget(item_factory, "/Options/Key word search");
	show_mode_buttons[0] = gtk_item_factory_get_widget(item_factory, "/View/xTerm");
	show_mode_buttons[1] = gtk_item_factory_get_widget(item_factory, "/View/GhostView");
	show_mode_buttons[2] = gtk_item_factory_get_widget(item_factory, "/View/LocalBrowse");
	show_mode_buttons[3] = gtk_item_factory_get_widget(item_factory, "/View/NetBrowse");
	status_bar_button = gtk_item_factory_get_widget(item_factory, "/Options/Status bar");
	//  gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(section_buttons[4]),1);
	updata_menu_buttons(0);
}

/*flag = 0 means not to invoke call backs when changing the states of buttons.*/
void updata_menu_buttons(int flag) 
{
	int i,j,k,k2;
	k = (int)context->get_value("display_section_policy");
	if(k>0 && k<=2)
		if(!((GtkCheckMenuItem*)(section_select[k]))->active){
			if(!flag) signal_menu_change++;
			gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(section_select[k]),1);
		}
	k = (int)context->get_value("display_section");
	for (i = 0;i<10;i++)
		if(!(k&(1<<i)) != !(((GtkCheckMenuItem*)(section_buttons[i]))->active)) {
			if(!flag) signal_menu_change++;
			gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(section_buttons[i]),k&(1<<i));
		}
	k = (int)context->get_value("searching_mode");
	if(k>0 && k<=1)
		if(!(((GtkCheckMenuItem*)(searching_mode_buttons[k]))->active)) {
			if(!flag) signal_menu_change++;
			gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(searching_mode_buttons[k]),1);
		}
	k = (int)context->get_value("show_mode");
	if(k>0 && k<=3)
		if(!(((GtkCheckMenuItem*)(show_mode_buttons[k]))->active)) {
			if(!flag) signal_menu_change++;
			gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(show_mode_buttons[k]),1);
		}
	k2 = (int)context->get_value("show_status_bar");
	i = k2&(1<<k);
	j = (((GtkCheckMenuItem*)(status_bar_button))->active);
	if((i&&!j) || (!i&&j)) {
		if(!flag) signal_menu_change++;
		gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(status_bar_button),i);
	}
	gtk_widget_hide(status_bar_button);
}

static 	GtkWidget *index_search_vbox;
static 	GtkWidget *keyword_search_vbox;
static 	GtkWidget *hbox4;
static 	GtkWidget *hbox_status;
static 	GtkWidget *entry4;
GtkWidget *search_button;
GtkWidget *stop_button;
static	GtkWidget *statusbar1;
static	GtkWidget *statusbar2;

static void updata_widget_show(int flag)
{	
	int k,k2;
	
	k = (int)context->get_value("searching_mode");
	k2 = (int)context->get_value("show_status_bar");

	if(k2&(1<<k)) 
		gtk_widget_show(hbox_status);
	else
		gtk_widget_hide(hbox_status);
	gtk_widget_hide(!k?keyword_search_vbox:index_search_vbox);
	gtk_widget_show(k?keyword_search_vbox:index_search_vbox);
	if(k2 & (1<<k)) gtk_widget_show (hbox_status);
}


void init_main_window(GtkWidget * window)
{
	GtkWidget *	main_vbox;
	GtkWidget *	menubar;
	GtkWidget *	swindow;
	GtkWidget *	swindow2;
	GtkWidget * focus;

	int k,k2;

	::window = window;
	gchar *titles[2] = { "Name", "Section" };
	gchar *titles2[3] = { "Name", "Section", "Description"};
	signal_select_row = 0;
	signal_entry_change = 0;
	
	tooltips = gtk_tooltips_new();

	gtk_signal_connect(GTK_OBJECT(window), "destroy", 
					   GTK_SIGNAL_FUNC(app_quit), 
					   0);

	gtk_window_set_title(GTK_WINDOW(window), "G-man");
	gtk_window_set_policy( GTK_WINDOW( window ), FALSE, TRUE, FALSE );
	gtk_window_set_default_size(GTK_WINDOW(window),
								(int)context->get_value("h_size"),
								(int)context->get_value("v_size"));
	
	gtk_widget_set_usize(GTK_WIDGET(window),200,150);
	main_vbox = gtk_vbox_new(FALSE, 1);
	gtk_container_border_width(GTK_CONTAINER(main_vbox), 1);
	gtk_container_add(GTK_CONTAINER(window), main_vbox);
	gtk_widget_show(main_vbox);

	get_main_menu(window, &menubar);
	gtk_box_pack_start(GTK_BOX(main_vbox), menubar, FALSE, TRUE, 0);
	gtk_widget_show(menubar);

	gtk_signal_connect(GTK_OBJECT(window),"size_allocate",GTK_SIGNAL_FUNC(window_resize_callback),NULL);

	//keyword_search_vbox
	keyword_search_vbox = gtk_vbox_new(FALSE,1);
	gtk_box_pack_start(GTK_BOX(main_vbox), keyword_search_vbox, TRUE, TRUE, 0);
	
	hbox4 = gtk_hbox_new (FALSE, 1);
	gtk_object_set_data (GTK_OBJECT (window), "hbox4", hbox4);
	gtk_box_pack_start (GTK_BOX (keyword_search_vbox), hbox4, FALSE, TRUE, 0);
	gtk_widget_show (hbox4);

	stop_button = gtk_button_new_with_label ("Stop");
	gtk_object_set_data (GTK_OBJECT (window), "stop_button", stop_button);
	gtk_widget_set_sensitive(stop_button,0);
	gtk_signal_connect (GTK_OBJECT(stop_button),"clicked",(GtkSignalFunc)button_clicked_callback,(void*)1);
	gtk_widget_show (stop_button);
	gtk_box_pack_start (GTK_BOX (hbox4), stop_button, FALSE, TRUE, 0);
	gtk_widget_set_usize (stop_button, 40, -2);
	
	entry4 = gtk_entry_new ();
	gtk_object_set_data (GTK_OBJECT (window), "entry4", entry4);
	gtk_widget_show (entry4);
	gtk_tooltips_set_tip (tooltips, entry4, "Key word search", NULL);
	gtk_box_pack_start (GTK_BOX (hbox4), entry4, TRUE, TRUE, 0);
    gtk_signal_connect(GTK_OBJECT(entry4), "activate",
		       GTK_SIGNAL_FUNC(entry4_activate_callback),NULL);
    gtk_signal_connect(GTK_OBJECT(entry4), "changed",
		       GTK_SIGNAL_FUNC(entry4_changed_callback),NULL);
	
	search_button = gtk_button_new_with_label ("Search");
	gtk_object_set_data (GTK_OBJECT (window), "search_button", search_button);
	gtk_widget_set_sensitive(search_button,0);
	gtk_signal_connect (GTK_OBJECT(stop_button),"clicked",(GtkSignalFunc)button_clicked_callback,(void*)2);
	gtk_widget_show (search_button);
	gtk_box_pack_start (GTK_BOX (hbox4), search_button, FALSE, TRUE, 0);
	gtk_widget_set_usize (search_button, 60, -2);

	
    clist3 = gtk_clist_new_with_titles( 3, titles2);
	swindow2 = gtk_scrolled_window_new (NULL, NULL);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow2),
					GTK_POLICY_AUTOMATIC,
					GTK_POLICY_AUTOMATIC);

	
	gtk_clist_set_column_width(GTK_CLIST(clist3),0,100);
	gtk_clist_set_selection_mode(GTK_CLIST(clist3),GTK_SELECTION_SINGLE);
	gtk_clist_column_titles_passive(GTK_CLIST(clist3));
	gtk_clist_set_column_auto_resize (GTK_CLIST(clist3),2,1);

	gtk_container_add (GTK_CONTAINER (swindow2), clist3);
	gtk_box_pack_start (GTK_BOX (keyword_search_vbox), swindow2, TRUE, TRUE, 0);
	gtk_widget_show_all(GTK_WIDGET(swindow2));

	gtk_signal_connect(GTK_OBJECT(clist3),"select_row",
					   GTK_SIGNAL_FUNC(select_row_callback3),NULL);
	
	//index_search_vbox
	index_search_vbox = gtk_vbox_new(FALSE,1);
	gtk_box_pack_start(GTK_BOX(main_vbox), index_search_vbox, TRUE, TRUE, 0);
    entry = gtk_entry_new_with_max_length (50);
    clist = gtk_clist_new_with_titles( 2, titles);
    gtk_signal_connect(GTK_OBJECT(entry), "activate",
		       GTK_SIGNAL_FUNC(entry_activate_callback),
		       (gpointer)clist);
    gtk_signal_connect(GTK_OBJECT(entry), "changed",
		       GTK_SIGNAL_FUNC(entry_changed_callback),
		       (gpointer)clist);
    gtk_box_pack_start (GTK_BOX (index_search_vbox), entry, FALSE, TRUE, 0);
	gtk_tooltips_set_tip (tooltips, entry, "index search", NULL);
	gtk_widget_show(entry);

	swindow = gtk_scrolled_window_new (NULL, NULL);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
					GTK_POLICY_AUTOMATIC,
					GTK_POLICY_AUTOMATIC);


	gtk_clist_set_column_width(GTK_CLIST(clist),0,200);
	gtk_clist_set_selection_mode(GTK_CLIST(clist),GTK_SELECTION_SINGLE);
	gtk_clist_column_titles_passive(GTK_CLIST(clist));
	gtk_container_add (GTK_CONTAINER (swindow), clist);
	gtk_box_pack_start (GTK_BOX (index_search_vbox), swindow, TRUE, TRUE, 0);

	gtk_signal_connect(GTK_OBJECT(clist),"select_row",
					   GTK_SIGNAL_FUNC(select_row_callback),NULL);

	focus = entry;
	gtk_widget_grab_focus (focus);
	gtk_widget_show_all (swindow);

	hbox_status = gtk_hbox_new (FALSE, 0);
	gtk_object_set_data (GTK_OBJECT (window), "hbox_status", hbox_status);
	gtk_box_pack_start (GTK_BOX (main_vbox), hbox_status, FALSE, TRUE, 0);

	updata_widget_show(0);

	statusbar1 = gtk_statusbar_new ();
	gtk_object_set_data (GTK_OBJECT (window), "statusbar1", statusbar1);
	gtk_widget_show (statusbar1);
	gtk_box_pack_start (GTK_BOX (hbox_status), statusbar1, TRUE, TRUE, 0);

	statusbar2 = gtk_statusbar_new ();
	gtk_object_set_data (GTK_OBJECT (window), "statusbar2", statusbar2);
	gtk_widget_show (statusbar2);
	gtk_box_pack_start (GTK_BOX (hbox_status), statusbar2, FALSE, TRUE, 0);
}


/******************* tools functions ******************/
int search_array_for_text(char ** array, int count, char * text)
{
	int i;
	for (i=0;i<count && strcmp(text,array[i])>0 ;i++);
	return (i >= count)? i-1:i;
}

/******************* call backs ***********************/
void select_row_callback(GtkWidget *widget,
						 gint row,
						 gint column,
						 GdkEventButton *event,
						 gpointer data)
{
	ManItem * item;
	if(signal_select_row>0) {signal_select_row--;return;}
	item = (ManItem*) gtk_clist_get_row_data(GTK_CLIST(widget),row);
	item->active_man_page();
	signal_entry_change++;
	gtk_entry_set_text(GTK_ENTRY(entry),man_items_buffer[row]);
}
void select_row_callback3(GtkWidget *widget,
						 gint row,
						 gint column,
						 GdkEventButton *event,
						 gpointer data)
{
	ManItem * item;
	if(signal_select_row>0) {signal_select_row--;return;}
	item = (ManItem*) gtk_clist_get_row_data(GTK_CLIST(widget),row);
	if(item) item->active_man_page();
}
void entry_activate_callback(GtkWidget * w,gpointer data)
{
	int i;
	GtkWidget * clist = (GtkWidget *)data;
	i = search_array_for_text(man_items_buffer, 
							  man_items_count, 
							  gtk_entry_get_text(GTK_ENTRY(w)));
	if (i == -1) return;
	gtk_clist_moveto(GTK_CLIST(clist),i,0,0.1,0.0);
	GTK_CLIST(clist)->focus_row = i;
	gtk_clist_select_row(GTK_CLIST(clist),i,0);
}
	
void entry_changed_callback(GtkWidget * w,gpointer data)
{
	int i;
	GtkWidget * clist = (GtkWidget *)data;
	if(signal_entry_change>0) {signal_entry_change--;return;}
	i = search_array_for_text(man_items_buffer, 
							  man_items_count, 
							  gtk_entry_get_text(GTK_ENTRY(w)));
	if (i == -1) return;
	signal_select_row++;
	gtk_clist_moveto(GTK_CLIST(clist),i,0,0.1,0.0);
	GTK_CLIST(clist)->focus_row = i;
	gtk_clist_select_row(GTK_CLIST(clist),i,0);
}

static int print_hello(GtkWidget *w, gpointer data) {
	if(signal_menu_change>0) {signal_menu_change--;return 1;}
	g_message("Hello, World! %x\n",data);
	return 0;
}

static int print_page(GtkWidget *w, gpointer data) {
	if(signal_menu_change>0) {signal_menu_change--;return 1;}
	g_message("Hello, World! %x\n",data);
	return 0;
}

static int test_callback(GtkWidget *w, gpointer data) {
	int i,j;
	if(signal_menu_change>0) {signal_menu_change--;return 1;}
	j = man_paths->get_size();
	for(i = 0;i<j;i++)
		delete ((ManPath*)(man_paths->get_value(i)));
	delete (man_paths);
	init_man_data();
	return 0;
}

static int section_policy_callback(GtkWidget *w, gpointer data) {
	//	static int signal;
	int k,k2;
	k2 = (int) data;
	if(!((GtkCheckMenuItem*)(section_select[k2]))->active) return 1;
	//	g_message("Hello, World! %x\n signal = %d",data,signal_menu_change);
	if(signal_menu_change>0) {signal_menu_change--;return 1;}
	//if(!signal) {signal++;return 1;}
	//signal--;
	k = (int) context->get_value("display_section_policy");
	if(k == k2) return 1;
	pthread_mutex_lock(&context_lock);
	context->set_value("display_section_policy","int",(void*)k2);
	pthread_mutex_unlock(&context_lock);
	task_set_active(task_extract_man_data);
	task_set_active(task_add_data_to_clist);
}

static int section_select_callback(GtkWidget *w, gpointer data) {
	int var;
	if(signal_menu_change>0) {signal_menu_change--;return 1;}

	pthread_mutex_lock(&context_lock);
	var = (int)context->get_value("display_section");
	var ^= (int)data;
	context->set_value("display_section","int",(void*)var);
	if (context->get_value("display_section_policy")) {
		task_set_active(task_extract_man_data);
		task_set_active(task_add_data_to_clist);
	}
	pthread_mutex_unlock(&context_lock);
	//		g_message("Hello, World! %x\n",data);
}

static void app_quit(GtkWidget *w, gpointer data) {
  //	g_message("Bye, World! %x\n",data);
	char buffer[1024],*p;
	FILE * fd;
	int i,j;
	p = buffer;
	j = man_paths->get_size();
	for (i = 0;i<j;i++) {
		sprintf(p,i?":%s":"%s",man_paths->get_name(i));
		for(;*p;p++);
	}
	context->set_value("man_paths","char*",my_strdup(buffer));
	attach(buffer,getenv("HOME"),".gman");
	if((fd = fopen(buffer,"w"))) {
		context->save(fd,"automatically made by G-man");
		fclose(fd);
	}
	//	context->save(stdout,"automatically made by G-man");
	
	gtk_exit((int)data);
}

static int window_resize_callback(GtkWidget *w, GtkAllocation * size, gpointer data)
{
	/*
	g_message("x = %d, y = %d, width = %d, height = %d, data = %x\n",
	size->x,size->y,size->width,size->height,data); */
	context->set_value("h_size","int",(void*)size->width);
	context->set_value("v_size","int",(void*)size->height);
	return 0;
}

static void window_help_about_callback (GtkWidget *widget, gpointer   data)
{
	const gchar *authors[] = {"Xinkai Wang <aakwxk@hotmail.com>", NULL };
	static GtkWidget *about_window = NULL;

	if (!about_window)
	{

	GtkWidget *button;
	GdkFont *font;

	about_window = gtk_dialog_new ();
	gtk_window_set_position (GTK_WINDOW (about_window), GTK_WIN_POS_MOUSE);
	gtk_window_set_title (GTK_WINDOW (about_window), _("About gman"));

	gtk_signal_connect (GTK_OBJECT (about_window), "delete_event",
		  GTK_SIGNAL_FUNC (gtk_false), NULL);
	gtk_signal_connect (GTK_OBJECT (about_window), "destroy",
		  (GtkSignalFunc) gtk_widget_destroyed,
		  &about_window);

	button = gtk_button_new_with_label (_("Close"));
	gtk_widget_show (button);
	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (about_window)->action_area),
		  button, TRUE, TRUE, 0);
	gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
		  (GtkSignalFunc) gtk_widget_destroy,
		  GTK_OBJECT (about_window));

	gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (about_window)->vbox), 5);

	 /* TODO: we need a logo ;) */

	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (about_window)->vbox),
		  gtk_label_new ("Gman - version " VERSION),
		  FALSE, FALSE, 5);

	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (about_window)->vbox),
		  gtk_label_new ("Copyright (C) 1999 Xinkai Wang"),
		  FALSE, FALSE, 5);

	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (about_window)->vbox),
		  gtk_label_new ("Comments and suggestions are extremely welcomed!"),
		  FALSE, FALSE, 5);

	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (about_window)->vbox),
		  gtk_label_new ("Web: http://homex.coolconnect.com/user/xkwang/gman/"),
		  FALSE, FALSE, 5);

	if (!GTK_WIDGET_VISIBLE (about_window))
		  gtk_widget_show_all (about_window);
	else
		  gtk_widget_hide (about_window);

	}
}

static int status_bar_callback (GtkWidget *widget, gpointer   data)
{
	int k,k2;
	if(signal_menu_change>0) {signal_menu_change--;return 1;}
	k2 = (int) context->get_value("show_status_bar");
	k = (int) context->get_value("searching_mode");
	if(((GtkCheckMenuItem*)(status_bar_button))->active) k2 = k2 | (1<<k);
	else k2 = k2 & ~(1<<k);
	pthread_mutex_lock(&context_lock);
	context->set_value("show_status_bar","int",(void*)k2);
	pthread_mutex_unlock(&context_lock);
	updata_widget_show(0);
	return 0;
}

static int search_mode_callback (GtkWidget *widget, gpointer   data)
{
	int k,k2;
	k2 = (int) data;
	if(!((GtkCheckMenuItem*)(searching_mode_buttons[k2]))->active) return 1;
	if(signal_menu_change>0) {signal_menu_change--;return 1;}
	//if(!signal) {signal++;return 1;}
	//signal--;
	k = (int) context->get_value("searching_mode");
	if(k == k2) return 1;
	pthread_mutex_lock(&context_lock);
	context->set_value("searching_mode","int",(void*)k2);
	pthread_mutex_unlock(&context_lock);
	updata_widget_show(0);
	updata_menu_buttons(0);
	return 0;
}

static int show_mode_callback (GtkWidget *widget, gpointer   data)
{
	int k,k2;
	k2 = (int) data;
	if(!((GtkCheckMenuItem*)(show_mode_buttons[k2]))->active) return 1;
	if(signal_menu_change>0) {signal_menu_change--;return 1;}
	//if(!signal) {signal++;return 1;}
	//signal--;
	k = (int) context->get_value("show_mode");
	if(k == k2) return 1;
	pthread_mutex_lock(&context_lock);
	context->set_value("show_mode","int",(void*)k2);
	pthread_mutex_unlock(&context_lock);
	//updata_widget_show(0);
	//updata_menu_buttons(0);
	return 0;
}

static void entry4_activate_callback(GtkWidget *w,gpointer data)
{
	keyword = gtk_entry_get_text(GTK_ENTRY(entry4));
	task_set_active(task_key_word_search);
}

static void entry4_changed_callback(GtkWidget *w,gpointer data)
{
	char * tmp;
	tmp = gtk_entry_get_text(GTK_ENTRY(entry4));
	gtk_widget_set_sensitive(search_button,strlen(tmp) >= 3);
		
}

static int button_clicked_callback(GtkWidget * w,gpointer data)
{
	int i = (int) data;
	switch (i) {
	case 1: task_set_stop(task_key_word_search);break;
	case 2: task_set_active(task_key_word_search);break;
	}
}
