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

#include "defs.h"
#include "global.h"

#include "xml.h"
//#include <sys/stat.h>
#include <gdk/gdkkeysyms.h>
#include "dicttext.h"
#include "shortcutfunc.h"
#include "mainmenu.h"
#include "dictheading.h"
#include "dictbar.h"
#include "statusbar.h"

static GtkWidget *shortcut_dlg;
static GtkWidget *clist_shortcut;
static GtkWidget *label_key;
static GtkWidget *clist_command;
static GtkWidget *check_lock;

static gboolean grab=FALSE;
static GdkEventKey grabbed_event;

struct _shortcut_command commands[] = {
	{ N_("Toggle Menu Mar"), toggle_menu_bar},
	{ N_("Toggle Status Bar"), toggle_status_bar},
	{ N_("Toggle Dictionary Bar"), toggle_dict_bar},
	{ N_("Select Automatic Search"), select_any_search},
	{ N_("Select Exactword Search"), select_exactword_search},
	{ N_("Select Word Search"), select_word_search},
	{ N_("Select Endword Search"), select_endword_search},
	{ N_("Select Keyword Search"), select_keyword_search},
	{ N_("Select Multi Search"), select_multi_search},
	{ N_("Select Fulltext Search"), select_fulltext_search},
	{ N_("Select Internet Search"), select_internet_search},
	{ N_("Next Dictionary Group"), next_dict_group},
	{ N_("Previous Dictionary Group"), previous_dict_group},
	{ N_("Toggle Dictionary No. 1"), toggle_dictionary1},
	{ N_("Toggle Dictionary No. 2"), toggle_dictionary2},
	{ N_("Toggle Dictionary No. 3"), toggle_dictionary3},
	{ N_("Toggle Dictionary No. 4"), toggle_dictionary4},
	{ N_("Toggle Dictionary No. 5"), toggle_dictionary5},
	{ N_("Toggle Dictionary No. 6"), toggle_dictionary6},
	{ N_("Toggle Dictionary No. 7"), toggle_dictionary7},
	{ N_("Toggle Dictionary No. 8"), toggle_dictionary8},
	{ N_("Toggle Dictionary No. 9"), toggle_dictionary9},
	{ N_("Toggle Dictionary No. 10"), toggle_dictionary10},
	{ N_("Next Hit"), item_next},
	{ N_("Previous Hit"), item_previous},
	{ N_("Copy To Clipboard"), claim_clipboard_owner},
	{ N_("Start Search"), start_search},
	{ N_("Go Back In History"), go_back},
	{ N_("Go Forward In History"), go_forward},
	{ N_("Show Previous Text"), go_up},
	{ N_("Show Next Text"), go_down},
	{ N_("Toggle Selection Search"), toggle_auto},
	{ N_("Toggle Popup"), toggle_popup},
	{ N_("Show Help"), show_usage},
	{ N_("Clear Word"), clear_word},
	{ N_("Quit Program"), quit},
	{ N_("Iconify Window"), iconify},
	{NULL, NULL}};


struct _shortcuts shortcuts = {0};

extern void print_dict_group();

static void ok_pref(GtkWidget *widget,gpointer *data){

	gint i;
	struct _shortcut *shortcut;

	gtk_grab_remove(shortcut_dlg);

	shortcuts.count = 0;

	for(i=0;;i++){
		shortcut = (struct _shortcut *)gtk_clist_get_row_data(GTK_CLIST(clist_shortcut), i);
		if(shortcut == NULL)
			break;
		shortcuts.shortcut[i] = *shortcut;
		shortcuts.count ++;
		free(shortcut);
	}
	
	save_shortcut();

	bignore_locks = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_lock));

	gtk_widget_destroy(GTK_WIDGET(shortcut_dlg));
	auto_lookup_resume();
}

static void delete_event( GtkWidget *widget,
		   GdkEvent  *event,
		   gpointer   data )
{
	ok_pref(NULL, NULL);
}

static void grab_key(GtkWidget *widget,gpointer *data){
	
	grab = TRUE;
	gdk_keyboard_grab(shortcut_dlg->window, 0, GDK_CURRENT_TIME);
}

static void key_val_to_string(guint state, guint keyval, gchar *key){

	key[0] = '\0';

	if(state & GDK_CONTROL_MASK){
		strcat(key, "Ctrl + ");
	}

	if(state & GDK_SHIFT_MASK){
		strcat(key, "Shirt + ");
	}

	if(state & GDK_LOCK_MASK){
		strcat(key, "Lock + ");
	}

	if(state & GDK_MOD1_MASK){ // Alt
		strcat(key, "Alt + ");
	}

	if(state & GDK_MOD2_MASK){ // Num Lock
		strcat(key, "NumLock + ");
	}

	if(state & GDK_MOD3_MASK){ 
		strcat(key, "Mod3 + ");
	}

	if(state & GDK_MOD4_MASK){
		strcat(key, "Mod4 + ");
	}

	if(state & GDK_MOD5_MASK){ // Scroll Lock
		strcat(key, "ScrollLock + ");
	}

	if(state & GDK_BUTTON1_MASK){
		strcat(key, "Button1 + ");
	}

	if(state & GDK_BUTTON2_MASK){
		strcat(key, "Button2 + ");
	}

	if(state & GDK_BUTTON3_MASK){
		strcat(key, "Button3 + ");
	}

	if(state & GDK_BUTTON4_MASK){
		strcat(key, "Button4 + ");
	}

	if(state & GDK_BUTTON5_MASK){
		strcat(key, "Button5 + ");
	}

	if(state & GDK_RELEASE_MASK){
		strcat(key, "Release + ");
	}

	strcat(key, gdk_keyval_name(keyval));
}

static gint window_key_event(GtkWidget *widget, GdkEventKey *event){
	gchar key[256];
	
//	if(grab != TRUE)
//		return(FALSE);

	switch (event->keyval){
	case GDK_Shift_L:
	case GDK_Shift_R:
	case GDK_Control_L:
	case GDK_Control_R:
	case GDK_Meta_L:
	case GDK_Meta_R:
	case GDK_Alt_L:
	case GDK_Alt_R:
	case GDK_Caps_Lock:
	case GDK_Shift_Lock:
	case GDK_Scroll_Lock:
	case GDK_Num_Lock:
	case GDK_Kana_Lock:
		return(FALSE);
		break;
	}

	if(bignore_locks)
		event->state = event->state & (~GDK_LOCK_MASK) & (~GDK_MOD2_MASK);
	key_val_to_string(event->state, event->keyval, key);

	gtk_label_set_text(GTK_LABEL(label_key), key);

	gdk_keyboard_ungrab(GDK_CURRENT_TIME);
	grab = FALSE;
	grabbed_event = *event;
}

static void remove_entry(GtkWidget *widget,gpointer *data){

	GList *selection;
	int  line_no;
	struct _shortcut *shortcut;

	selection = GTK_CLIST(clist_shortcut)->selection;
	if(selection == NULL){
//		warning(_("Please select entry."));
		return;
	}

	line_no = GPOINTER_TO_INT(selection->data);

	shortcut = (struct _shortcut *)gtk_clist_get_row_data(GTK_CLIST(clist_shortcut), line_no);
	if(shortcut != 0)
		free(shortcut);

	gtk_clist_remove(GTK_CLIST(clist_shortcut), line_no);
}

static void add_entry(GtkWidget *widget,gpointer *data){
	gchar *key;
	gint row;
	struct _shortcut *shortcut;
	gchar *text[2];

	GList *selection;
	int  line_no;

	selection = GTK_CLIST(clist_command)->selection;
	if(selection == NULL){
		warning(_("Please select command."));
		return;
	}

	line_no = GPOINTER_TO_INT(selection->data);

	gtk_label_get(GTK_LABEL(label_key), &key);
	text[0] = key;
//	text[1] = commands[line_no].description;
	text[1] = _(commands[line_no].description);
	row = gtk_clist_append(GTK_CLIST(clist_shortcut), text);

	shortcut = calloc(sizeof(struct _shortcut), 1);
	shortcut->state = grabbed_event.state;
	shortcut->keyval = grabbed_event.keyval;
	shortcut->command = (struct _shortcut_command *)&commands[line_no];

	gtk_clist_set_row_data(GTK_CLIST(clist_shortcut), row, (gpointer)shortcut);


}

static void lock_changed(GtkWidget *widget,gpointer *data){

	bignore_locks = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check_lock));
}


void preference_shortcut()
{
	GtkWidget *button;
	GtkWidget *vbox;
	GtkWidget *vbox2;
	GtkWidget *hbox;
	GtkWidget *hbox2;
	GtkWidget *frame;
	GtkWidget *label;
	GtkWidget *scroll;
	GtkObject *adj;
	GtkWidget *note_book;
	gchar *text[2];
	gchar *title[2];

	gint i;
	gchar key[256];
	struct _shortcut *shortcut;
	gint row;


	auto_lookup_suspend();

	title[0] = _("Key");
	title[1] = _("Command");


	shortcut_dlg = gtk_dialog_new();

//	gtk_widget_set_usize(shortcut_dlg, 520, 400);

	gtk_signal_connect (GTK_OBJECT (shortcut_dlg), "delete_event",
			    GTK_SIGNAL_FUNC (delete_event), NULL);


//	gtk_widget_set_usize(shortcut_dlg,400,280);
	gtk_window_set_position(GTK_WINDOW(shortcut_dlg), GTK_WIN_POS_CENTER_ALWAYS);

	gtk_grab_add(shortcut_dlg);
	gtk_widget_realize(shortcut_dlg);

	hbox = gtk_hbox_new(FALSE,0);
	gtk_box_pack_start (GTK_BOX(GTK_DIALOG (shortcut_dlg)->vbox)
			    , hbox, TRUE, TRUE, 0);

	vbox = gtk_vbox_new(FALSE,0);
	gtk_box_pack_start (GTK_BOX(hbox)
			    , vbox,TRUE, TRUE, 0);


	gtk_container_border_width(GTK_CONTAINER(vbox), 5);

	frame = gtk_frame_new(_("Shortcut"));
	gtk_box_pack_start (GTK_BOX(vbox), frame,TRUE, TRUE, 0);

	vbox2 = gtk_vbox_new(FALSE,2);
	gtk_container_border_width(GTK_CONTAINER(vbox2), 2);
	gtk_container_add (GTK_CONTAINER (frame), vbox2);


	scroll = gtk_scrolled_window_new(NULL, NULL);
	gtk_widget_set_usize(scroll,300,200);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
					GTK_POLICY_NEVER, 
					GTK_POLICY_AUTOMATIC);
	gtk_box_pack_start (GTK_BOX(vbox2)
			    ,scroll ,TRUE, TRUE, 0);

	clist_shortcut = gtk_clist_new_with_titles(2, title);
	gtk_clist_set_reorderable(GTK_CLIST(clist_shortcut), TRUE);
	gtk_clist_column_titles_passive (GTK_CLIST (clist_shortcut));
	gtk_container_add (GTK_CONTAINER (scroll), clist_shortcut);
	gtk_clist_set_column_width(GTK_CLIST(clist_shortcut),
				   0, 100);
	gtk_clist_set_column_width(GTK_CLIST(clist_shortcut),
				   1, 100);
	gtk_clist_set_reorderable(GTK_CLIST(clist_shortcut), TRUE);


	hbox2 = gtk_vbox_new(FALSE,2);
	gtk_box_pack_start (GTK_BOX (vbox2), hbox2,
			    FALSE, FALSE, 0);

	button = gtk_button_new_with_label(_("Remove"));
	gtk_box_pack_end (GTK_BOX (hbox2), button,
			    FALSE, FALSE, 0);
	gtk_signal_connect (GTK_OBJECT (button), "clicked",
			    GTK_SIGNAL_FUNC (remove_entry), (gpointer)NULL);

	for(i=0; i < shortcuts.count ; i++){
		key_val_to_string(shortcuts.shortcut[i].state,
			     shortcuts.shortcut[i].keyval,
			     key);
		text[0] = key;
//		text[1] = shortcuts.shortcut[i].command->description;
		text[1] = _(shortcuts.shortcut[i].command->description);
		row = gtk_clist_append(GTK_CLIST(clist_shortcut), text);

		shortcut = calloc(sizeof(struct _shortcut), 1);
		shortcut->state = shortcuts.shortcut[i].state;
		shortcut->keyval = shortcuts.shortcut[i].keyval;
		shortcut->command = shortcuts.shortcut[i].command;
		
		gtk_clist_set_row_data(GTK_CLIST(clist_shortcut), row, (gpointer)shortcut);

	}







	// ±¦È¾Ê¬

	vbox = gtk_vbox_new(FALSE,0);
	gtk_box_pack_start (GTK_BOX(hbox)
			    , vbox,TRUE, TRUE, 0);


	gtk_container_border_width(GTK_CONTAINER(vbox), 5);

	frame = gtk_frame_new(_("Add"));
	gtk_box_pack_start (GTK_BOX(vbox), frame,TRUE, TRUE, 0);

	vbox2 = gtk_vbox_new(FALSE,2);
	gtk_container_border_width(GTK_CONTAINER(vbox2), 2);
	gtk_container_add (GTK_CONTAINER (frame), vbox2);




	hbox2 = gtk_hbox_new(FALSE,0);
	gtk_box_pack_start (GTK_BOX(vbox2)
			    , hbox2, FALSE, FALSE, 0);

	label = gtk_label_new(_("Key : "));
	gtk_box_pack_start (GTK_BOX(hbox2)
			    , label,FALSE, FALSE, 0);

	label_key = gtk_label_new("");
	gtk_box_pack_start (GTK_BOX(hbox2)
			    , label_key,FALSE, FALSE, 0);

/*
	button = gtk_button_new_with_label(_("Grab"));
	gtk_box_pack_end (GTK_BOX (hbox2), button,
			    FALSE, FALSE, 0);
	
	gtk_signal_connect (GTK_OBJECT (button), "clicked",
			    GTK_SIGNAL_FUNC (grab_key), (gpointer)shortcut_dlg);
*/

	
	scroll = gtk_scrolled_window_new(NULL, NULL);
	gtk_widget_set_usize(scroll,250,200);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
					GTK_POLICY_NEVER, 
					GTK_POLICY_AUTOMATIC);
	gtk_box_pack_start (GTK_BOX(vbox2)
			    ,scroll ,TRUE, TRUE, 0);

	title[0] = _("Command");
	clist_command = gtk_clist_new_with_titles(1, title);
	gtk_clist_column_titles_passive (GTK_CLIST (clist_command));
	gtk_container_add (GTK_CONTAINER (scroll), clist_command);
	gtk_clist_set_column_width(GTK_CLIST(clist_command),
				   0, 100);
	gtk_clist_set_column_width(GTK_CLIST(clist_command),
				   1, 100);
	gtk_clist_set_reorderable(GTK_CLIST(clist_command), TRUE);



	for(i=0; ; i++){
		if(commands[i].description == NULL)
			break;
//		text[0] = commands[i].description;
		text[0] = _(commands[i].description);
		gtk_clist_append(GTK_CLIST(clist_command), text);
	}


	button = gtk_button_new_with_label(_("Add"));
	gtk_box_pack_start (GTK_BOX (vbox2), button,
			    FALSE, FALSE, 0);
	gtk_signal_connect (GTK_OBJECT (button), "clicked",
			    GTK_SIGNAL_FUNC (add_entry), (gpointer)NULL);


	check_lock = gtk_check_button_new_with_label(_("Ignore locks"));
	gtk_box_pack_start (GTK_BOX (vbox2), check_lock,
			    FALSE, FALSE, 0);
	gtk_tooltips_set_tip(tooltip, check_lock, 
			     _("Ignore Caps Lock and Num Lock key."),"Private");
	gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check_lock), bignore_locks);
	gtk_signal_connect (GTK_OBJECT (check_lock), "clicked",
			    GTK_SIGNAL_FUNC (lock_changed), NULL);


	button = gtk_button_new_with_label(_("Ok"));
	GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
	gtk_box_pack_start (GTK_BOX (GTK_DIALOG (shortcut_dlg)->action_area), button,
			    TRUE, TRUE, 0);
	
	gtk_signal_connect (GTK_OBJECT (button), "clicked",
			    GTK_SIGNAL_FUNC (ok_pref), (gpointer)shortcut_dlg);
	gtk_widget_grab_default (button);


	gtk_signal_connect( GTK_OBJECT(shortcut_dlg),"key_press_event",
			    (GtkSignalFunc)window_key_event, NULL);


	gtk_widget_show_all(shortcut_dlg);

}


gboolean perform_shortcut(GdkEventKey *event){

	gint i;


	for(i=0 ; i < shortcuts.count ; i ++){
		if(event->keyval == shortcuts.shortcut[i].keyval){
			if(event->state == shortcuts.shortcut[i].state){
				shortcuts.shortcut[i].command->func();
				return(TRUE);
			}

			if((bignore_locks) &&
			   ((event->state | GDK_MOD2_MASK | GDK_LOCK_MASK)== (shortcuts.shortcut[i].state | GDK_MOD2_MASK | GDK_LOCK_MASK))){
				shortcuts.shortcut[i].command->func();
				return(TRUE);
			}
		}
	}
	return(FALSE);
}


syntax highlighted by Code2HTML, v. 0.9.1