/*  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 "canvas.h"
#include "history.h"
#include "dump.h"

extern GtkWidget *note_tree;
extern GtkWidget *tree_viewport;
extern CONTENT_AREA *dict_area;

static void show_heading(GtkWidget *widget);

static GtkWidget *current_node = NULL;

GtkWidget *container_child(GtkWidget *container){
	GList *p;
	p = gtk_container_children(GTK_CONTAINER(container));
	if(p == NULL){
		return(NULL);
	} else {
		return((GtkWidget *)(p->data));
	}
}

static void show_location(SEARCH_RESULT *result){
	gchar msg[512];
	sprintf(msg, "HEADING: page=%08x offset=%03x   CONTENT: page=%08x offset=%03x",
		result->pos_heading.page, 
		result->pos_heading.offset,
		result->pos_text.page, 
		result->pos_text.offset);
	status_message(msg);

}


void ctree_select_row(GtkWidget *widget,
			       gint row, 
			       gint column, 
			       GdkEventButton *bevent,
			       gpointer user_data)
{
	GtkWidget *node;
	GtkWidget *last_node;
	ITEM_DATA *idata;
	gchar *text;

	g_return_if_fail (GTK_IS_CLIST (widget));

	node = (GtkWidget *)gtk_ctree_node_nth(GTK_CTREE(tree_root), row);
	idata = gtk_ctree_node_get_row_data(GTK_CTREE(tree_root), 
					    GTK_CTREE_NODE(node));
	if(idata == NULL) {
		last_node = current_node;
		current_row = -1;
		current_node = NULL;
		show_heading(last_node);
		return;
	}

	if(current_node != NULL) {
		last_node = current_node;
		current_row = row;
		current_node = node;
		show_heading(last_node);
	} else {
		current_row = row;
		current_node = node;
	}
	show_heading(node);

	text = ebook_get_text(
		idata->result->book_info,
		idata->result->pos_text.page, 
		idata->result->pos_text.offset);
	show_text(idata->result->book_info, text);
	save_history(dict_area,
		     idata->result->book_info,
		     idata->result->pos_text.page, 
		     idata->result->pos_text.offset);
	free(text);

	show_location(idata->result);

	current_position.page = idata->result->pos_text.page;
	current_position.offset = idata->result->pos_text.offset;
	current_book_info = idata->result->book_info;

	if(hex_dlg != NULL)
		dump_hex();
	if(text_dlg != NULL)
		dump_text();


	return;

}

void ctree_unselect_row(GtkWidget *widget,
			       gint row, 
			       gint column, 
			       GdkEventButton *bevent,
			       gpointer user_data)
{
	GtkWidget *last_node;

	g_return_if_fail (GTK_IS_CLIST (widget));

	last_node = current_node;
	current_row = -1;
	current_node = NULL;
	show_heading(last_node);
	return;
}

static void clear_node(GtkCTree *ctree, GtkCTreeNode *list){
	ITEM_DATA *data;

	data = gtk_ctree_node_get_row_data(GTK_CTREE(ctree),list);
	if(data != NULL){
		if(data->pixbuff != NULL){
			gdk_pixmap_unref(data->pixbuff);
		}
		free(data);
	}
	gtk_ctree_remove_node(GTK_CTREE(ctree),list);
}

void clear_tree(GtkWidget *tree){
	GtkCTreeNode *node;

	if(tree == NULL) {
		return;
	}

	gtk_clist_freeze(GTK_CLIST(tree));

	while(1){
		node = gtk_ctree_node_nth(GTK_CTREE(tree), 0);
		if(node == NULL)
			break;
		gtk_ctree_post_recursive(GTK_CTREE(tree), 
					node, 
					(GtkCTreeFunc)clear_node, 
					NULL);
	}

	gtk_clist_thaw(GTK_CLIST(tree));
	current_row = -1;
	current_node = NULL;

	gtk_container_check_resize(GTK_CONTAINER(tree_root));
}

gint x_max=0;

void show_result_tree()
{

	SEARCH_RESULT *rp;
	GList *l;
	ITEM_DATA *idata;
	GtkWidget *node=NULL;
	GtkWidget *leaf;
	BOOK_INFO *last_book = NULL;
	gint result_count=0;
	char *node_text[1];
	gchar *text;
	gint i;

	if(search_result == NULL){
		// 1
		show_text(0, _("No hit."));
		return;
	}

	gtk_notebook_set_page(GTK_NOTEBOOK(note_tree), 0);

	x_max = 0;

	if(tree_scroll != NULL)
		gtk_widget_destroy(tree_root);
	tree_root = gtk_ctree_new(1, 0);
	gtk_clist_set_row_height(GTK_CLIST(tree_root),font_height+4);
	gtk_ctree_set_line_style(GTK_CTREE(tree_root),GTK_CTREE_LINES_NONE);

        gtk_signal_connect (GTK_OBJECT(tree_root), "select_row",
                            GTK_SIGNAL_FUNC(ctree_select_row), tree_root);

        gtk_signal_connect (GTK_OBJECT(tree_root), "unselect_row",
                            GTK_SIGNAL_FUNC(ctree_unselect_row), tree_root);

	gtk_widget_set_usize(GTK_WIDGET(tree_root), 200, 350);
	gtk_container_add (GTK_CONTAINER (tree_scroll), tree_root);
	gtk_widget_show_all(tree_root);




	gtk_adjustment_set_value(
		gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(tree_scroll)), 0);

	gtk_clist_freeze(GTK_CLIST(tree_root));

	for(i=0, l = search_result ; l != NULL; i ++, l = g_list_next(l)){
		rp = (SEARCH_RESULT *)(l->data);
		if(result_count >= max_search) {
			status_message("Exceeded maximum hits.");
			break;
		}
		// 
		if(last_book != rp->book_info){
			//
			//1expand
			node_text[0] = rp->book_info->subbook_title;
			node = (GtkWidget *)gtk_ctree_insert_node(GTK_CTREE(tree_root), 
						     NULL, //parent
						     NULL, //sibling
						     node_text, //text
						     0,    //spacing
						     book_closed_pixmap, //pixmap closed 
						     book_closed_mask, //mask closed
						     book_open_pixmap, //pixmap opened 
						     book_open_mask, //mask opened
						     FALSE,//is leaf
						     TRUE);//expanded
			last_book = rp->book_info;
			i++;
		}

		idata = (ITEM_DATA *)calloc(sizeof(ITEM_DATA), 1);
		g_assert(idata != NULL);
		idata->result = rp;

		node_text[0] = "def";
		leaf = (GtkWidget *)gtk_ctree_insert_node(GTK_CTREE(tree_root), 
					     GTK_CTREE_NODE(node), //parent
					     NULL, //sibling
					     node_text, //text
					     2,    //spacing
					     item_pixmap, //pixmap closed 
					     item_mask, //mask closed
					     item_pixmap, //pixmap opened 
					     item_mask, //mask opened
					     TRUE,//is leaf
					     TRUE);//expanded
//		gtk_widget_set_usize( leaf, x, HEADING_HEIGHT );
		if(current_row < 0){
			current_row = 1;
			current_node = leaf;
		} else if(current_row == i){
			current_node = leaf;
		}
		gtk_ctree_node_set_row_data(GTK_CTREE(tree_root), 
					    GTK_CTREE_NODE(leaf), 
					    (gpointer)idata);
		show_heading(leaf);
		result_count++;
	}

	current_node = (GtkWidget *)gtk_ctree_node_nth(GTK_CTREE(tree_root), current_row);
	gtk_ctree_select(GTK_CTREE(tree_root),
			 GTK_CTREE_NODE(current_node));

	ctree_select_row(tree_root, 
			 current_row,
			 0,
			 NULL,
			 NULL);




/*
	rp = (SEARCH_RESULT *)(search_result->data);
	text = ebook_get_text(rp->book_info,
			      rp->pos_text.page, 
			      rp->pos_text.offset);
	show_text(rp->book_info, text);

	free(text);

	show_location(rp);

	current_position.page = rp->pos_text.page;
	current_position.offset = rp->pos_text.offset;
	current_book_info = rp->book_info;

	save_history(dict_area,
		     rp->book_info,
		     rp->pos_text.page,
		     rp->pos_text.offset);

*/


	gtk_clist_thaw(GTK_CLIST(tree_root));
	gtk_container_resize_children(GTK_CONTAINER(tree_scroll));
	gtk_container_check_resize(GTK_CONTAINER(tree_scroll));
	gtk_container_check_resize(GTK_CONTAINER(tree_root));
	gtk_clist_set_column_width(GTK_CLIST(tree_root), 0, x_max+60);


	if(hex_dlg != NULL)
		dump_hex();
	if(text_dlg != NULL)
		dump_text();

}


static void show_heading(GtkWidget *item)
{
	ITEM_DATA *idata;
	gint x,y;
	gint max_width, max_height;
	GdkGC *gc;
	CANVAS *canvas;
	DRAW_TEXT text;

//	g_assert(item != NULL);
	if(item == NULL)
		return;

//	idata = gtk_object_get_user_data(GTK_OBJECT(item));
	idata = gtk_ctree_node_get_row_data(GTK_CTREE(tree_root), GTK_CTREE_NODE(item));
	if(idata == NULL){
		return;
	}

	if(idata->result->heading == NULL)
		return;

	x = 0;
//	y = HEADING_PIXMAP_HEIGHT;
	y = font_ascent+2;

	// Pixmap

	canvas = create_canvas(window);


	canvas->x = x;
	canvas->y = y;
	canvas->width = HEADING_PIXMAP_WIDTH;
//	canvas->height = HEADING_PIXMAP_HEIGHT;
	canvas->height = font_height + 2;

	text.text = idata->result->heading;
	text.length = strlen(text.text);

	draw_content(canvas, &text, idata->result->book_info, NULL);
	x = canvas->x;
	y = canvas->y;

	if(x > HEADING_PIXMAP_WIDTH)
		x = HEADING_PIXMAP_WIDTH;

//	if(y > HEADING_PIXMAP_HEIGHT)
//		y = HEADING_PIXMAP_HEIGHT;
	if(y > font_height)
		y = font_height;
	y += 2;

	// 
	if(x_max < x) {
		x_max = x;
	}


	gc = gdk_gc_new(window->window);
	if(idata->pixbuff != NULL){
		gdk_pixmap_unref(idata->pixbuff);
	}

	idata->pixbuff = gdk_pixmap_new( window->window, x, y, -1 );

	if(idata->pixbuff == NULL){
		g_assert(idata->pixbuff != NULL);
	}

	if(item == current_node){
		gdk_gc_set_foreground(gc, &tree_root->style->bg[GTK_STATE_SELECTED]);
		gdk_draw_rectangle(idata->pixbuff, 
				   gc,
				   TRUE, 0,0,
//				   widget->allocation.width,
				   x, y);
	} else {
//		gdk_gc_set_foreground(gc, &colors[COLOR_WHITE]);
//		gdk_gc_set_foreground(gc, &tree_root->style->bg[GTK_STATE_NORMAL]);
		gdk_gc_set_foreground(gc, &tree_root->style->base[GTK_STATE_NORMAL]);
//		gdk_gc_set_foreground(gc, &widget->style->bg[GTK_STATE_ACTIVE]);
		gdk_draw_rectangle(idata->pixbuff, 
				   gc,
//				   item->style->white_gc,
				   TRUE, 0,0,
				   x, y);
	}

	max_width = HEADING_PIXMAP_WIDTH;
//	max_height = HEADING_PIXMAP_HEIGHT; // unused
	max_height = font_height+2; // unused

	x = 0;
//	y = HEADING_PIXMAP_HEIGHT;;
	y = font_ascent+2;

	// 
	if(item == current_node){
		gdk_gc_set_foreground(gc, 
				      &tree_root->style->fg[GTK_STATE_SELECTED]);
		gdk_gc_set_background(gc, &tree_root->style->bg[GTK_STATE_SELECTED]);

	} else {
		gdk_gc_set_foreground(gc, &tree_root->style->fg[GTK_STATE_NORMAL]);
//		gdk_gc_set_background(gc, &widget->parent->style->bg[GTK_STATE_NORMAL]);
//		gdk_gc_set_background(gc, &colors[COLOR_WHITE]);
		gdk_gc_set_background(gc, &tree_root->style->base[GTK_STATE_NORMAL]);

	}

	// 
	canvas->pixmap = idata->pixbuff;
	canvas->x = x;
	canvas->y = y;
	canvas->width = max_width;
	canvas->height = max_height;
	canvas->gc = gc;

	text.text = idata->result->heading;
	text.length = strlen(text.text);

	draw_content(canvas, &text, idata->result->book_info, NULL);

	gdk_gc_destroy(gc);

	// Pixmap
	gtk_ctree_node_set_pixmap(GTK_CTREE(tree_root),
				  GTK_CTREE_NODE(item),
				  0,
				  idata->pixbuff,
				  NULL);

//	idata->old_width = x;
//	idata->old_height = y;

	free(canvas);
}

void item_next()
{

	ITEM_DATA *idata;
	gchar *text;
	gint row;
	GtkWidget *node, *last_node;
	
	row = current_row + 1;
	while(1){
		node = (GtkWidget *)gtk_ctree_node_nth(GTK_CTREE(tree_root),
						       row);
		if(node == NULL)
		{
			return;
		}
		if(GTK_CTREE_ROW(node)->is_leaf == 1){
			last_node = current_node;
			if(last_node)
				gtk_ctree_unselect(GTK_CTREE(tree_root), 
						   GTK_CTREE_NODE(last_node));
			current_node = node;
			current_row = row;
			gtk_ctree_select(GTK_CTREE(tree_root), 
					 GTK_CTREE_NODE(current_node));
			if(last_node)
				show_heading(last_node);
			show_heading(node);

			idata = gtk_ctree_node_get_row_data(GTK_CTREE(tree_root), GTK_CTREE_NODE(node));
			show_location(idata->result);

			text = ebook_get_text(
				idata->result->book_info,
				idata->result->pos_text.page, 
				idata->result->pos_text.offset);
			show_text(idata->result->book_info, text);
			save_history(dict_area,
				     idata->result->book_info,
				     idata->result->pos_text.page, 
				     idata->result->pos_text.offset);
			free(text);
			current_position.page = idata->result->pos_text.page;
			current_position.offset = idata->result->pos_text.offset;
			current_book_info = idata->result->book_info;
			if(gtk_ctree_node_is_visible(GTK_CTREE(tree_root), 
						     GTK_CTREE_NODE(current_node)) != GTK_VISIBILITY_FULL)
				gtk_clist_moveto(GTK_CLIST(tree_root), row, 0, 1, 0);

			if(hex_dlg != NULL)
				dump_hex();
			if(text_dlg != NULL)
				dump_text();

			return;
		}
	        row ++;
	}

}

void item_previous()
{

	ITEM_DATA *idata;
	gchar *text;
	gint row;
	GtkWidget *node, *last_node;
	
	row = current_row - 1;
	while(1){
		node = (GtkWidget *)gtk_ctree_node_nth(GTK_CTREE(tree_root), 
						       row);
		if(node == NULL)
		{
			gtk_clist_moveto(GTK_CLIST(tree_root), 0, 0, 0, 0);
			return;
		}
		if(GTK_CTREE_ROW(node)->is_leaf == 1){
			last_node = current_node;
			if(last_node)
				gtk_ctree_unselect(GTK_CTREE(tree_root), 
						   GTK_CTREE_NODE(last_node));
			current_node = node;
			current_row = row;
			gtk_ctree_select(GTK_CTREE(tree_root), 
					 GTK_CTREE_NODE(current_node));
			if(last_node)
				show_heading(last_node);
			show_heading(node);

			idata = gtk_ctree_node_get_row_data(GTK_CTREE(tree_root), GTK_CTREE_NODE(node));

			show_location(idata->result);

			text = ebook_get_text(
				idata->result->book_info,
				idata->result->pos_text.page, 
				idata->result->pos_text.offset);
			show_text(idata->result->book_info, text);
			save_history(dict_area,
				     idata->result->book_info,
				     idata->result->pos_text.page, 
				     idata->result->pos_text.offset);
			free(text);
			current_position.page = idata->result->pos_text.page;
			current_position.offset = idata->result->pos_text.offset;
			current_book_info = idata->result->book_info;
			if(gtk_ctree_node_is_visible(GTK_CTREE(tree_root), 
						     GTK_CTREE_NODE(current_node)) != GTK_VISIBILITY_FULL)
				gtk_clist_moveto(GTK_CLIST(tree_root), row, 0, 0, 0);

			if(hex_dlg != NULL)
				dump_hex();
			if(text_dlg != NULL)
				dump_text();

			return;
		}
	        row --;
	}
}


syntax highlighted by Code2HTML, v. 0.9.1