/*  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 "eb.h"
#include "jcode.h"

#ifdef HAVE_ICONV_H
#include <iconv.h>
#include <langinfo.h>
#endif

static GtkWidget *hex_text = NULL;
static GtkWidget *text_text = NULL;
static GtkWidget *entry_hex_page;
static GtkWidget *entry_text_page;
static GtkWidget *entry_text_offset;

static GdkFont *font_fixed;

static void hex_close(GtkWidget *widget,gpointer *data){
	gtk_widget_destroy(hex_dlg);
	hex_dlg = NULL;
}

static void text_close(GtkWidget *widget,gpointer *data){
	gtk_widget_destroy(text_dlg);
	text_dlg = NULL;
}

//static gchar fontset_fixed[] = "-*-fixed-medium-r-normal-*-14-*-*-*-*-*-*-*,-misc-fixed-*-*-*-*-14-*-*-*-*-*-*-*";
static gchar fontset_fixed[] = "-*-fixed-medium-r-normal-*-14-*-*-*-*-*-*-*";


static gchar *jis2locale(gchar *inbuf){
#ifdef HAVE_ICONV_H
	iconv_t cd;
	const char* ocode = "euc-jp";
	const char* icode = "iso-2022-jp";
//	const char* ocode = "shift_jis";

	int r = 0;
	size_t isize;
	size_t osize;
	char *outbuf;
	char *result;
	char *lang;

	ocode = nl_langinfo(CODESET);

	cd = iconv_open( ocode, icode );
	if( (int)cd == -1 )
		return(NULL);		

	isize = strlen(inbuf);
	osize = isize * 4;
	result = outbuf = malloc(osize);
	r = iconv(cd, &inbuf, &isize, &outbuf, &osize);
	iconv_close(cd);

	if(r == 1){
		perror("iconv");
		return(NULL);
	}
	return(result);
#else 
	return(strdup(inbuf));
#endif
}

static void hex_dump_page(GtkWidget *widget,gpointer *data){
	gint page;
	gchar *p;
	gchar *p_hex;
	gchar *p_char;
	gchar *text;
	gchar hex_buff[512];
	gchar char_buff[512];
	gchar buff[512];
	gchar *result;
	gint i;
	gint j;
	
	p = gtk_entry_get_text(GTK_ENTRY(entry_hex_page));
	page = strtol(p, NULL, 16);

/*
	if((offset % 15) != 0)
		offset = offset - (offset % 15);
*/
	text = ebook_get_rawtext(current_book_info,
				 page,
				 0);
	if(text == NULL)
	{
		g_print("text is NULL\n");
		return;
	}
	
	gtk_text_set_editable(GTK_TEXT(hex_text), FALSE);
	gtk_text_freeze(GTK_TEXT(hex_text));

	gtk_text_backward_delete(GTK_TEXT(hex_text), 
				 gtk_text_get_length(GTK_TEXT(hex_text)));

	font_fixed = gdk_fontset_load (fontset_fixed);

	gtk_text_insert(GTK_TEXT(hex_text), 
			font_fixed, NULL, NULL,
			"Offset (Absolute)  00-01-02-03-04-05-06-07-08-09-0A-0B-0C-0D-0E-0F  0123456789ABCDEF\n", -1);


	for( i = 0 ;  i < EB_SIZE_PAGE ; i=i+2){

                // $B%"%I%l%9$rI=<((B
		if((i % 16) == 0){
			p_hex = hex_buff;
			p_char = char_buff;
			sprintf(p_hex, "0x%02x ", (i / 16));
			p_hex += 5;
			sprintf(p_hex, "(0x%08x)  ", (page - 1) * EB_SIZE_PAGE + i);
			p_hex += 14;

			sprintf(p_char, " ");
			p_char += 1;
		}

		sprintf(p_hex, "%02x ", (unsigned char)text[i]);
		p_hex += 3;
		sprintf(p_hex, "%02x ", (unsigned char)text[i+1]);
		p_hex += 3;


		if(isjisp(&text[i])) {
			buff[0] = 0x1b;
			buff[1] = 0x24;
			buff[2] = 0x42;
			strncpy(&buff[3], &text[i], 2);
			buff[5] = 0x1b;
			buff[6] = 0x28;
			buff[7] = 0x42;
			buff[8] = '\0';
			result = jis2locale(buff);
			if(result != NULL){
				result[2] = '\0';
				strncpy(p_char, result, 2);
				p_char +=2;
				*p_char = '\0';
				free(result);
			}
		} else {
			sprintf(p_char, "..");
			p_char +=2;
		}

		if((i % 16) == 14){
			gtk_text_insert(GTK_TEXT(hex_text), 
					font_fixed, NULL, NULL,
					hex_buff, -1);

			gtk_text_insert(GTK_TEXT(hex_text), 
					font_fixed, NULL, NULL,
					char_buff, -1);

			gtk_text_insert(GTK_TEXT(hex_text), 
					font_fixed, NULL, NULL,
					"\n", -1);
		}
	}
	gtk_text_thaw(GTK_TEXT(hex_text));
	free(text);

}

static void back_page(GtkWidget *widget,gpointer *data){
	gint page;
	gchar *p;
	gchar buff[64];

	p = gtk_entry_get_text(GTK_ENTRY(entry_hex_page));
	page = strtol(p, NULL, 16);
	if(page == 0){
		return;
	}
	page --;

	sprintf(buff, "%08x",page);
	gtk_entry_set_text(GTK_ENTRY(entry_hex_page), buff);
	hex_dump_page(NULL, NULL);
}

static void forward_page(GtkWidget *widget,gpointer *data){
	gint page;
	gchar *p;
	gchar buff[64];

	p = gtk_entry_get_text(GTK_ENTRY(entry_hex_page));
	page = strtol(p, NULL, 16);
	if(page == 0){
		return;
	}
	page ++;

	sprintf(buff, "%08x",page);
	gtk_entry_set_text(GTK_ENTRY(entry_hex_page), buff);
	hex_dump_page(NULL, NULL);
}


void dump_hex(){

	GtkWidget *button;
	GtkWidget *hbox;
	GtkWidget *label;
	GtkWidget *vscrollbar;
	gchar buff[16];

	if(hex_dlg == NULL){

		hex_dlg = gtk_dialog_new();
		gtk_window_set_title (GTK_WINDOW (hex_dlg), "Hex dump");

		gtk_signal_connect (GTK_OBJECT (hex_dlg), "delete_event",
				    GTK_SIGNAL_FUNC (hex_close), NULL);

//		gtk_widget_set_usize(hex_dlg,400,280);
	
		button = gtk_button_new_with_label(_("Close"));
		GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
		gtk_box_pack_start (GTK_BOX (GTK_DIALOG (hex_dlg)->action_area), button,
				    TRUE, TRUE, 0);
		gtk_signal_connect (GTK_OBJECT (button), "clicked",
				    GTK_SIGNAL_FUNC (hex_close), (gpointer)hex_dlg);
		
		hbox = gtk_hbox_new(FALSE,5);
		gtk_container_border_width(GTK_CONTAINER(hbox), 5);
		gtk_box_pack_start (GTK_BOX(GTK_DIALOG(hex_dlg)->vbox)
				    , hbox, FALSE, FALSE, 0);
		
		label = gtk_label_new(_("page"));
		gtk_box_pack_start (GTK_BOX(hbox), label, FALSE, FALSE, 0);
		
		entry_hex_page = gtk_entry_new();
		gtk_widget_set_usize(entry_hex_page,100,20);
		gtk_box_pack_start (GTK_BOX(hbox), entry_hex_page, FALSE, FALSE, 0);
		gtk_signal_connect(GTK_OBJECT(entry_hex_page), "activate",
				   GTK_SIGNAL_FUNC (hex_dump_page), (gpointer)NULL);

		button = gtk_button_new_with_label("  >>  ");
		GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
		gtk_box_pack_end (GTK_BOX (hbox), button,
				    FALSE, FALSE, 0);
		gtk_signal_connect (GTK_OBJECT (button), "clicked",
				    GTK_SIGNAL_FUNC (forward_page), NULL);

		button = gtk_button_new_with_label("  <<  ");
		GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
		gtk_box_pack_end (GTK_BOX (hbox), button,
				    FALSE, FALSE, 0);
		gtk_signal_connect (GTK_OBJECT (button), "clicked",
				    GTK_SIGNAL_FUNC (back_page), NULL);



		
		hbox = gtk_hbox_new(FALSE,5);
		gtk_box_pack_start (GTK_BOX(GTK_DIALOG(hex_dlg)->vbox)
				    , hbox,TRUE, TRUE, 0);
		
		hex_text = gtk_text_new(NULL, NULL);
		gtk_box_pack_start (GTK_BOX(hbox)
				    , hex_text,TRUE, TRUE, 0);
		gtk_widget_set_usize(hex_dlg,640,480);
//		gtk_widget_set_usize(hex_dlg,630,400);




		vscrollbar = gtk_vscrollbar_new (GTK_TEXT(hex_text)->vadj);
		gtk_box_pack_start(GTK_BOX(hbox), vscrollbar, FALSE, FALSE, 0);

		gtk_widget_show_all(hex_dlg);
	}

	if(current_position.page >= 0){
		sprintf(buff, "%08x",current_position.page);
		gtk_entry_set_text(GTK_ENTRY(entry_hex_page), buff);
		hex_dump_page(NULL, NULL);
	}


}

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

	gint page, offset;
	gchar *p;
	gchar *text;
	
	p = gtk_entry_get_text(GTK_ENTRY(entry_text_page));
	page = strtol(p, NULL, 16);

	p = gtk_entry_get_text(GTK_ENTRY(entry_text_offset));
	offset = strtol(p, NULL, 16);

	text = ebook_get_text(current_book_info,
			      page,
			      offset);
	if(text == NULL)
	{
		g_print("text is NULL\n");
		return;
	}
	
	gtk_text_set_editable(GTK_TEXT(text_text), FALSE);
	gtk_text_freeze(GTK_TEXT(text_text));

	gtk_text_backward_delete(GTK_TEXT(text_text), 
				 gtk_text_get_length(GTK_TEXT(text_text)));

	font_fixed = gdk_fontset_load (fontset_fixed);

	gtk_text_insert(GTK_TEXT(text_text), 
			NULL, NULL, NULL,
			text, -1);
	gtk_text_thaw(GTK_TEXT(text_text));
	free(text);

}

void dump_text(){

	GtkWidget *button;
	GtkWidget *hbox;
	GtkWidget *label;
	GtkWidget *vscrollbar;
	gchar buff[16];

	if(text_dlg == NULL){

		text_dlg = gtk_dialog_new();
		gtk_window_set_title (GTK_WINDOW (text_dlg), "Text dump");

		gtk_signal_connect (GTK_OBJECT (text_dlg), "delete_event",
				    GTK_SIGNAL_FUNC (text_close), NULL);

//		gtk_widget_set_usize(text_dlg,400,280);
	
		button = gtk_button_new_with_label(_("Close"));
		GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
		gtk_box_pack_start (GTK_BOX (GTK_DIALOG (text_dlg)->action_area), button,
				    TRUE, TRUE, 0);
		gtk_signal_connect (GTK_OBJECT (button), "clicked",
				    GTK_SIGNAL_FUNC (text_close), (gpointer)text_dlg);

		hbox = gtk_hbox_new(FALSE,5);
		gtk_box_pack_start (GTK_BOX(GTK_DIALOG(text_dlg)->vbox)
				    , hbox, FALSE, FALSE, 0);
		
		label = gtk_label_new(_("page"));
		gtk_box_pack_start (GTK_BOX(hbox), label, FALSE, FALSE, 0);
		
		entry_text_page = gtk_entry_new();
		gtk_widget_set_usize(entry_text_page,100,20);
		gtk_box_pack_start (GTK_BOX(hbox), entry_text_page, FALSE, FALSE, 0);
		gtk_signal_connect(GTK_OBJECT(entry_text_page), "activate",
				   GTK_SIGNAL_FUNC (text_dump_page), (gpointer)NULL);
		
		label = gtk_label_new(_("offset"));
		gtk_box_pack_start (GTK_BOX(hbox), label, FALSE, FALSE, 0);
		
		entry_text_offset = gtk_entry_new();
		gtk_widget_set_usize(entry_text_offset,100,20);
		gtk_box_pack_start (GTK_BOX(hbox), entry_text_offset, FALSE, FALSE, 0);
		gtk_signal_connect(GTK_OBJECT(entry_text_offset), "activate",
				   GTK_SIGNAL_FUNC (text_dump_page), (gpointer)NULL);

		
		hbox = gtk_hbox_new(FALSE,5);
		gtk_box_pack_start (GTK_BOX(GTK_DIALOG(text_dlg)->vbox)
				    , hbox,TRUE, TRUE, 0);
		
		text_text = gtk_text_new(NULL, NULL);
		gtk_box_pack_start (GTK_BOX(hbox)
				    , text_text,TRUE, TRUE, 0);
		gtk_widget_set_usize(text_dlg,560,400);
//		gtk_widget_set_usize(text_dlg,630,400);


		vscrollbar = gtk_vscrollbar_new (GTK_TEXT(text_text)->vadj);
		gtk_box_pack_start(GTK_BOX(hbox), vscrollbar, FALSE, FALSE, 0);

		gtk_widget_show_all(text_dlg);
	}

	if(current_position.page >= 0){
		sprintf(buff, "%08x",current_position.page);
		gtk_entry_set_text(GTK_ENTRY(entry_text_page), buff);
		sprintf(buff, "%08x",current_position.offset);
		gtk_entry_set_text(GTK_ENTRY(entry_text_offset), buff);
		text_dump_page(NULL, NULL);
	}

}





syntax highlighted by Code2HTML, v. 0.9.1