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

#define IMAGE_TYPE_JPEG          1
#define IMAGE_TYPE_COLOR_BMP     2
#define IMAGE_TYPE_MONO_BMP      3
#define IMAGE_TYPE_GRAY_BMP      4

#ifndef HAVE_WCTYPE_H
static gint iswalpha(GdkWChar c)
{
	GdkWChar wc_buff[2];
	char *p;

	wc_buff[0] = c;
	wc_buff[1] = 0x00000000;

	p = gdk_wcstombs(wc_buff);

	return(isalpha(*p));
}
#endif

static void print_color(GdkGC *gc){
	GdkGCValues gcv;

	gdk_gc_get_values(gc, &gcv);
//	g_print("gcv.foreground = %x\n",gcv.foreground);
	g_print("gcv.foreground.pixel = %04x\n",(guint)gcv.foreground.pixel);
	g_print("gcv.foreground.red = %04x\n",gcv.foreground.red);
	g_print("gcv.foreground.green = %04x\n",gcv.foreground.green);
	g_print("gcv.foreground.blue = %04x\n",gcv.foreground.blue);
//	g_print("gcv.background = %x\n",gcv.background);
	g_print("gcv.background.pixel = %04x\n",(guint)gcv.background.pixel);
	g_print("gcv.background.red = %04x\n",gcv.background.red);
	g_print("gcv.background.green = %04x\n",gcv.background.green);
	g_print("gcv.background.blue = %04x\n",gcv.background.blue);
	
}

gint calculate_gaiji_size(gint height){
	gint size=16;

/*
	if(height <= 20)
		size = 16;
	else if(height <= 27)
		size = 24;
	else if(height <= 39)
		size = 30;
	else
		size = 48;
*/

	if(height < 24)
		size = 16;
	else if(height < 30)
		size = 24;
	else if(height < 48)
		size = 30;
	else
		size = 48;


	return(size);
}

void load_xbm(BOOK_INFO *binfo, gchar *name, GdkGC *gc, GdkPixmap **pixmap, GdkBitmap **bitmap, gint *w, gint *h){
	GtkStyle *style;
	gint x, y, width, height, depth;
	gint w_width, w_height;
	guchar *data = NULL;
	GdkGCValues gcv;
	GList **gaiji_cache;
	GList *gaiji_item;
	GAIJI_CACHE *gaiji_p;
	gint found=0;
	gint char_no;

	gint size;

	g_assert(gc != NULL);
	g_assert(pixmap != NULL);
	g_assert(bitmap != NULL);

//	g_print("load_xbm %s\n", name);

	gdk_gc_get_values(gc, &gcv);

#ifdef OLD_GAIJI
	char_no = strtol(&name[1], NULL, 16);
	found = 0;
	if(name[0] == 'h'){
		gaiji_p = binfo->gaiji_narrow;
	} else {
		gaiji_p = binfo->gaiji_wide;
	}
	while(gaiji_p != NULL){
		if(gaiji_p->code == char_no){
			found = 1;
			break;
		}
		gaiji_p = gaiji_p->next;
	}
#else

	char_no = strtol(&name[1], NULL, 16);
	found = 0;

//	size = calculate_gaiji_size(font_normal->ascent+font_normal->descent);
	size = calculate_gaiji_size(font_height);
	size = check_gaiji_size(binfo, size);

	if(name[0] == 'h'){
		switch(size){
		case 16:
			gaiji_cache = &(binfo->gaiji_narrow16);
			break;
		case 24:
			gaiji_cache = &(binfo->gaiji_narrow24);
			break;
		case 30:
			gaiji_cache = &(binfo->gaiji_narrow30);
			break;
		case 48:
			gaiji_cache = &(binfo->gaiji_narrow48);
			break;
		}
	} else {
		switch(size){
		case 16:
			gaiji_cache = &(binfo->gaiji_wide16);
			break;
		case 24:
			gaiji_cache = &(binfo->gaiji_wide24);
			break;
		case 30:
			gaiji_cache = &(binfo->gaiji_wide30);
			break;
		case 48:
			gaiji_cache = &(binfo->gaiji_wide48);
			break;
		}
	}

	gaiji_item = g_list_first(*gaiji_cache);
	while(gaiji_item != NULL){
		gaiji_p = gaiji_item->data;
		if(gaiji_p->code == char_no){
			found = 1;
			break;
		}
		gaiji_item = g_list_next(gaiji_item);
	}
#endif

	if(found){
		*pixmap = NULL;

		data = gaiji_p->data;
		width = gaiji_p->width;
		height = gaiji_p->height;

		style = gtk_widget_get_style(window);
		gdk_window_get_geometry (window->window, &x, &y, &w_width, &w_height, &depth);
		*pixmap = gdk_pixmap_create_from_data	(window->window,
							 data,
							 width, height,
							 depth,
							 &gcv.foreground,
							 &gcv.background);
		*bitmap = NULL;
		*bitmap = gdk_bitmap_create_from_data	(window->window,
							 data,
							 width,
							 height);
	} else {
		*pixmap = NULL;

//		XReadBitmapFileData(filename, &width, &height, &data, &x_hot, &y_hot);
		data = read_gaiji_as_bitmap(binfo, name, size, &width, &height);
		if(data == NULL){
			fprintf(stderr, "failed to read gaiji : %s\n", name);
			return;
		}

		style = gtk_widget_get_style(window);
		gdk_window_get_geometry (window->window, &x, &y, &w_width, &w_height, &depth);
		*pixmap = gdk_pixmap_create_from_data	(window->window,
							 data,
							 width, height,
							 depth,
							 &gcv.foreground,
							 &gcv.background);
		*bitmap = NULL;
		*bitmap = gdk_bitmap_create_from_data	(window->window,
							 data,
							 width,
							 height);

		gaiji_p = (GAIJI_CACHE *)calloc(sizeof(GAIJI_CACHE), 1);
		if(gaiji_p == NULL){
			fprintf(stderr, "No memory\n");
			exit(1);
		}
		gaiji_p->code = char_no;
		gaiji_p->data = data;
		gaiji_p->width = width;
		gaiji_p->height = height;

		*gaiji_cache = g_list_append(*gaiji_cache, gaiji_p);

	}

	*w = width;
	*h = height;

	return;
}


static void draw_string(CANVAS *canvas, DRAW_TEXT *text, LINK *link)
{

	GdkWChar *wc_buff;
	GdkWChar *wc_p;
	GdkWChar wc;
	GdkWChar *word_p;
	GdkFont *font;
	gint length;
	gint width;
	gint word_w;
	gint wc_buff_size;
	gint i;
	gint x,y;
	gint save_x, save_y;
	char *char_p;

	g_assert(canvas != NULL);
	g_assert(text != NULL);
#if 0
	{
		gchar *t;
		t = g_strndup(text->text, text->length);
		g_print("draw_string %s\n", t);
		free(t);
		
	}
#endif

	x = canvas->x;
	y = canvas->y;

	if((link != NULL) && (link->type & LINK_TYPE_EMPHASIS)){
		font = font_bold;
	} else if((link != NULL) && (link->type & LINK_TYPE_ITALIC)){
		font = font_italic;
        } else if((link != NULL) && (link->type & LINK_TYPE_SUBSCRIPT)){
		font = font_superscript;
        } else if((link != NULL) && (link->type & LINK_TYPE_SUPERSCRIPT)){
		font = font_superscript;
	} else {
		font = font_normal;
	}

	wc_buff_size = text->length * sizeof(GdkWChar)+1;
	wc_buff = malloc(wc_buff_size);
	length = gdk_mbstowcs(wc_buff, text->text, wc_buff_size - 1);
	wc_p = wc_buff;

	if((link != NULL) && (link->type & LINK_TYPE_CENTER)){
		gint w=0;
		for(i=0;i<length;i++){
			w += gdk_text_width_wc(font, wc_p, 1);
			wc_p ++;
		}
		if(w < (canvas->width - h_border * 2)){
			x = h_border + ((canvas->width - h_border * 2) - w) / 2;
		}
		wc_p = wc_buff;
	}

	for(i=0;i<length;i++){
		// 改行
		if(*wc_p == '\n'){
			x = h_border + canvas->indent * font_width;
//			x = h_border;
			y = y + canvas->line_height + v_space;
			canvas->line_height = font_height;
			wc_p ++;
			continue;
		}

		// キャンバスのサイズを超えるようなら改行する
		width = gdk_text_width_wc(font, wc_p, 1);
		if((x + width + h_border) >  canvas->width)	{
		x = h_border + canvas->indent * font_width;
//			x = h_border;
			y = y + canvas->line_height + v_space;
			canvas->line_height = font_height;
		}

		// 英単語の途中で改行されないようにする
		char_p = (char *)wc_p;
		if(isalpha(*char_p)){
			word_p = wc_p;
			word_w = 0;
			while(1){
			        char_p = (char *)word_p;
			        if(!isalpha(*char_p))
				        break;
				word_w += gdk_text_width_wc(font, word_p, 1);
				word_p ++;
			}
			if((x + word_w + h_border) >  canvas->width)	{
//				x = h_border;
				x = h_border + canvas->indent * font_width;
				y = y + canvas->line_height + v_space;
			}
		}

		if(canvas->pixmap != NULL){
			if((link != NULL) && (link->type & LINK_TYPE_SUPERSCRIPT)){
				gdk_draw_text_wc(canvas->pixmap, 
					 font, 
					 canvas->gc,
					 x, y-6, wc_p, 1);
			} else {
				gdk_draw_text_wc(canvas->pixmap, 
					 font, 
					 canvas->gc,
					 x, y, wc_p, 1);
			}

			wc = *wc_p;

			if(canvas->content_area)
				add_location_char(canvas->content_area, wc, 
						  x, 
						  y - font_ascent, 
						  width+h_space, font_height, 
						  font, link);

			if((link != NULL) && (canvas->content_area != NULL) &&
			   ((link->type & LINK_TYPE_JUMP) || 
			    (link->type & LINK_TYPE_WAVE) ||
			    (link->type & LINK_TYPE_MPEG))){

				save_x = x;
				save_y = y - font_ascent;
				x = x + width + h_space;
				link->start_x = save_x;
				link->start_y = save_y;
				link->end_x = x - 1;
				link->end_y = y + font_descent;
				set_link(canvas->content_area, link);
		
			} else {
				x = x + width + h_space;
			}


		} else {
			x = x + width + h_space;
		}

		wc_p ++;

	}
	
	canvas->x = x;
	canvas->y = y;

}

static void draw_gaiji(CANVAS *canvas, BOOK_INFO *binfo, LINK *link, gchar *code)
{
	gint width;
	gint height;

	GdkPixmap *gaiji_pixmap = NULL;
	GdkBitmap *mask;

	gint x, y, yy;
	gint save_x, save_y;


	g_assert(canvas != NULL);
	g_assert(binfo != NULL);
	g_assert(code != NULL);

	x = canvas->x;
	y = canvas->y;

/*
	if(code[0] == 'h'){
		width = font_height / 2;
	} else {
		width = font_height;
	}
*/

	load_xbm(binfo, code, canvas->gc, &gaiji_pixmap, &mask, &width, &height);


	if((x + width + h_border) > canvas->width){
		x = h_border + canvas->indent * font_width;
//		x = h_border;
		y = y + canvas->line_height + v_space;
//		canvas->line_height = font_height;
		canvas->line_height = height;
	}
	/*
	if(height > font_ascent)
	  yy = y - font_ascent;
	else
	*/

	yy = y + font_descent - height;

	if(canvas->pixmap != NULL){
		
		gdk_draw_pixmap(canvas->pixmap,
				canvas->gc,
				gaiji_pixmap,
				0,0,
				x, 
				//y - font_ascent,
				yy,
				width,
				height);
		if(gaiji_pixmap != NULL)
			gdk_pixmap_unref(gaiji_pixmap);
		if(mask != NULL)
			gdk_bitmap_unref(mask);

		if(canvas->content_area)
			add_location_gaiji(canvas->content_area, code, 
					   x, 
					   yy,
//					   y - font_ascent,
//					   x, y - height + 2,
//					   width, font_height, link);
					   width, height, link);


		if((link != NULL) && 
		   ((link->type & LINK_TYPE_JUMP) || 
		    (link->type & LINK_TYPE_WAVE))){
			save_x = x;
//			save_y = y - font_ascent;
			save_y = yy;
			x = x + width + h_space;
//		set_link(save_x, save_y, x-1, y, page, offset);
			link->start_x = save_x;
			link->start_y = save_y;
			link->end_x = x - 1;
			link->end_y = save_y + height;

			if(canvas->content_area != NULL)
				set_link(canvas->content_area, link);
		} else {
			x = x + width + h_space;
		}
	} else {
		x = x + width + h_space;
	}

	canvas->x = x;
	canvas->y = y;	
}

// imlibがキャッシュしているようなので、ファイル名を変える。
// キャッシュは有限? でないとリークする。
static int image_count=0;

static void draw_graphic(CANVAS *canvas, BOOK_INFO *binfo, gint type, gint page, gint offset, gint width, gint height)
{
	char filename[512];
	GdkPixmap *image=NULL;
	GdkBitmap *mask=NULL;
	GdkWindowPrivate *private;
	gint x, y;
	gint l_width, l_height;
	EB_Error_Code error_code=EB_SUCCESS;

	g_assert(canvas != NULL);
	g_assert(binfo != NULL);

	x = canvas->x;
	y = canvas->y;

	// いったんファイルに落とす

	sprintf(filename, "%s/%d-%d.img", tmp_dir, getpid(), image_count);
	image_count++;

	switch(type){
	case IMAGE_TYPE_COLOR_BMP:
	case IMAGE_TYPE_JPEG:
		error_code = ebook_output_color(binfo, filename, page, offset);
		break;
	case IMAGE_TYPE_MONO_BMP:
		error_code = ebook_output_mono(binfo, filename, page, offset, width, height);
		break;
	case IMAGE_TYPE_GRAY_BMP:
		error_code = ebook_output_gray(binfo, filename, page, offset, width, height);
		break;
	}

	if(error_code != EB_SUCCESS){
		return;
	}

	gdk_imlib_load_file_to_pixmap(filename, &image, &mask);
	g_assert(image != NULL);
//	g_assert(mask != NULL);
	gdk_pixmap_ref(image);

	// 改行したほうが見やすい?
	x = h_border;
	y = y + canvas->line_height + v_space;

	private = (GdkWindowPrivate *)image;
	
	l_width = private->width;
	l_height = private->height;

	if(canvas->pixmap != NULL){
		gdk_draw_pixmap(canvas->pixmap,
				canvas->gc,
				image,
				0,0,
				x, (y - font_height),
				l_width,
				l_height);
	}

	gdk_imlib_free_pixmap(image);
	if((image != NULL) && (private->ref_count > 0))
		gdk_pixmap_unref(image);
//	gdk_bitmap_unref(mask);

//	unlink(filename);

//	x = h_border;
//	x = h_border + canvas->indent * font_width;
	x = x + l_width;
//	y = y + l_height;
	if(canvas->line_height < l_height)
		canvas->line_height = l_height;

	if(x > canvas->max_width)
		canvas->max_width = x;
	canvas->x = x;
	canvas->y = y;

	return;
}



void draw_content(CANVAS *canvas, DRAW_TEXT *text, BOOK_INFO *binfo, LINK *link){
	gchar *p;
	gchar start_tag[512];
	gchar end_tag[512];
	gchar tag_name[512];
	gchar attr[512];
	gchar code[16];
	gchar body[65536];
	gchar *content;
	gint  content_length;
	gint  body_length;
	gint  l_page=0, l_offset=0, l_size=0;
	gint  l_width, l_height;
	gint  l_indent;
	LINK  l_link;
	DRAW_TEXT l_text;

	GdkColor color_save;
	GdkGCValues gcv;


	g_assert(canvas != NULL);
	g_assert(text != NULL);
	g_assert(text->text != NULL);


	l_link.type=0;
	l_link.page=0;
	l_link.offset=0;
	l_link.size=0;

	body_length = 0;
	p = text->text;

	if(text->length >= 65536){
		g_print("Text too long. Truncated to 65535 bytes. (Original %d bytes)\n", text->length);
		text->length = 65535;
		text->text[65535] = '\0';
	}
#if 0
	{
		gchar *tmp;

		tmp = g_strndup(text->text, text->length);
		g_print("text(length = %d) = \n%s\n\n", text->length, tmp);
		free(tmp);
	}
#endif
	while((p - text->text) <  text->length){
		if(*p == '<'){
			if(body_length != 0){
				l_text.text = body;
				l_text.length = body_length;
				draw_string(canvas, &l_text, link);
				body_length = 0;
			}

			get_start_tag(p, start_tag);
			get_tag_name(start_tag, tag_name);

			if((strcmp(tag_name, "reference") == 0) ||
			   (strcmp(tag_name, "candidate") == 0)){
				get_end_tag(p, tag_name, end_tag);

				get_attr(end_tag, "page", attr);
				l_page = strtol(attr, NULL, 16);
				get_attr(end_tag, "offset", attr);
				l_offset = strtol(attr, NULL, 16);

				get_content(p, tag_name, &content, &content_length);

				if(link) {
					l_link = *link;
					l_link.type = LINK_TYPE_JUMP | link->type;
				} else {
					l_link.type = LINK_TYPE_JUMP;
				}
				
				l_link.page = l_page;
				l_link.offset = l_offset;
				
				if(canvas->pixmap != NULL){
					gdk_gc_get_values(canvas->gc, &gcv);
					color_save = gcv.foreground;
					gdk_gc_set_foreground(canvas->gc, 
							      &colors[COLOR_BLUE]);
				}
				l_text.text = content;
				l_text.length = content_length;

				draw_content(canvas, &l_text, binfo, &l_link);

				if(canvas->pixmap != NULL){
					gdk_gc_set_foreground(canvas->gc, &color_save);
				}
				
				skip_end_tag(&p, tag_name);

			} else if(strcmp(tag_name, "keyword") == 0){

				get_content(p, tag_name, &content, &content_length);

				if(link) {
					l_link = *link;
					l_link.type = LINK_TYPE_KEYWORD | link->type;
				} else {
					l_link.type = LINK_TYPE_KEYWORD;
				}
				
				if(canvas->pixmap != NULL){
					gdk_gc_get_values(canvas->gc, &gcv);
					color_save = gcv.foreground;
					gdk_gc_set_foreground(canvas->gc, 
							      &colors[COLOR_BROWN]);
				}
				l_text.text = content;
				l_text.length = content_length;

				draw_content(canvas, &l_text, binfo, &l_link);

				if(canvas->pixmap != NULL){
					gdk_gc_set_foreground(canvas->gc, &color_save);
				}
				
				skip_end_tag(&p, tag_name);

			} else if(strcmp(tag_name, "modification") == 0){

				get_content(p, tag_name, &content, &content_length);

				get_attr(start_tag, "method", attr);

				if(link) {
					l_link = *link;
					if(attr[0] == '3')
					  l_link.type = LINK_TYPE_EMPHASIS | link->type;
					else
					  l_link.type = LINK_TYPE_ITALIC | link->type;
				} else {
					if(attr[0] == '3')
					  l_link.type = LINK_TYPE_EMPHASIS;
					else 
					  l_link.type = LINK_TYPE_ITALIC;
				}
				
				l_text.text = content;
				l_text.length = content_length;

				draw_content(canvas, &l_text, binfo, &l_link);

				skip_end_tag(&p, tag_name);

			} else if(strcmp(tag_name, "gaiji") == 0){

				get_attr(start_tag, "code", code);

				draw_gaiji(canvas, binfo, link, code);
	
				skip_start_tag(&p, tag_name);

			} else if(strcmp(tag_name, "indent") == 0){

				get_attr(start_tag, "position", attr);
				l_indent = strtol(attr, NULL, 10);
				
				// インデントの引数は位置?
				// 改行したばかり、または、文字が重ならないなら
				// 指定位置にセット
				if((canvas->x == h_border + canvas->indent * font_width) || 
				   (canvas->x < h_border + l_indent * font_width))
					canvas->x = h_border + l_indent * font_width;

				canvas->indent = l_indent;

				skip_start_tag(&p, tag_name);

			} else if(strcmp(tag_name, "emphasis") == 0){

				get_content(p, tag_name, &content, &content_length);

				l_text = *text;
				l_text.text = content;
				l_text.length = content_length;

				if(link) {
					l_link = *link;
					l_link.type = LINK_TYPE_EMPHASIS | link->type;
				} else {
					l_link.type = LINK_TYPE_EMPHASIS;
				}

				draw_content(canvas, &l_text, binfo, &l_link);

				skip_end_tag(&p, tag_name);

			} else if(strcmp(tag_name, "subscript") == 0){

				get_content(p, tag_name, &content, &content_length);
				l_text = *text;
				l_text.text = content;
				l_text.length = content_length;

				if(link) {
					l_link = *link;
					l_link.type = LINK_TYPE_SUBSCRIPT | link->type;
				} else {
					l_link.type = LINK_TYPE_SUBSCRIPT;
				}

				draw_content(canvas, &l_text, binfo, &l_link);

				skip_end_tag(&p, tag_name);

			} else if(strcmp(tag_name, "superscript") == 0){

				get_content(p, tag_name, &content, &content_length);
				l_text = *text;
				l_text.text = content;
				l_text.length = content_length;

				if(link) {
					l_link = *link;
					l_link.type = LINK_TYPE_SUPERSCRIPT | link->type;
				} else {
					l_link.type = LINK_TYPE_SUPERSCRIPT;
				}

				draw_content(canvas, &l_text, binfo, &l_link);

				skip_end_tag(&p, tag_name);

			} else if(strcmp(tag_name, "center") == 0){


				get_content(p, tag_name, &content, &content_length);
				l_text = *text;
				l_text.text = content;
				l_text.length = content_length;

				if(link) {
					l_link = *link;
					l_link.type = LINK_TYPE_CENTER | link->type;
				} else {
					l_link.type = LINK_TYPE_CENTER;
				}

				draw_content(canvas, &l_text, binfo, &l_link);

				skip_end_tag(&p, tag_name);

			} else if(strcmp(tag_name, "nonewline") == 0){

				skip_start_tag(&p, tag_name);

			} else if(strcmp(tag_name, "/nonewline") == 0){

				skip_start_tag(&p, tag_name);

			} else if(strcmp(tag_name, "narrow") == 0){

				skip_start_tag(&p, tag_name);

			} else if(strcmp(tag_name, "/narrow") == 0){

				skip_start_tag(&p, tag_name);

			} else if(strcmp(tag_name, "jpeg") == 0){

				get_attr(start_tag, "page", attr);
				l_page = strtol(attr, NULL, 16);
				get_attr(p, "offset", attr);
				l_offset = strtol(attr, NULL, 16);

				draw_graphic(canvas, binfo, IMAGE_TYPE_JPEG, l_page, l_offset, 0, 0);
				skip_start_tag(&p, tag_name);

			} else if(strcmp(tag_name, "bmp") == 0){

				get_attr(start_tag, "page", attr);
				l_page = strtol(attr, NULL, 16);
				get_attr(p, "offset", attr);
				l_offset = strtol(attr, NULL, 16);

				draw_graphic(canvas, binfo, IMAGE_TYPE_COLOR_BMP, l_page, l_offset, 0, 0);
				skip_start_tag(&p, tag_name);

			} else if(strcmp(tag_name, "mono") == 0){

				get_attr(start_tag, "width", attr);
				l_width = strtol(attr, NULL, 10);
				get_attr(start_tag, "height", attr);
				l_height = strtol(attr, NULL, 10);

				get_end_tag(p, tag_name, end_tag);

				get_attr(end_tag, "page", attr);
				l_page = strtol(attr, NULL, 16);
				get_attr(end_tag, "offset", attr);
				l_offset = strtol(attr, NULL, 16);

				draw_graphic(canvas, binfo, IMAGE_TYPE_MONO_BMP, l_page, l_offset, l_width, l_height);
				skip_end_tag(&p, tag_name);

			} else if(strcmp(tag_name, "wave") == 0){

				get_end_tag(p, tag_name, end_tag);

				get_attr(end_tag, "page", attr);
				l_page = strtol(attr, NULL, 16);
				get_attr(end_tag, "offset", attr);
				l_offset = strtol(attr, NULL, 16);
				get_attr(end_tag, "size", attr);
				l_size = strtol(attr, NULL, 10);

				get_content(p, tag_name, &content, &content_length);

				if(link) {
					l_link = *link;
					l_link.type = LINK_TYPE_WAVE | link->type;
				} else {
					l_link.type = LINK_TYPE_WAVE;
				}

				l_link.page = l_page;
				l_link.offset = l_offset;
				l_link.size = l_size;
				
				if(canvas->pixmap != NULL){
					gdk_gc_get_values(canvas->gc, &gcv);
					color_save = gcv.foreground;
					gdk_gc_set_foreground(canvas->gc, 
							      &colors[COLOR_GREEN]);
				}
				l_text.text = content;
				l_text.length = content_length;

				draw_content(canvas, &l_text, binfo, &l_link);

				if(canvas->pixmap != NULL){
					gdk_gc_set_foreground(canvas->gc, &color_save);
				}

				skip_end_tag(&p, tag_name);

			} else if(strcmp(tag_name, "mpeg") == 0){

				get_attr(start_tag, "filename", attr);

//				get_content(p, tag_name, &content, &content_length);

				if(link) {
					l_link = *link;
					l_link.type = LINK_TYPE_MPEG | link->type;
				} else {
					l_link.type = LINK_TYPE_MPEG;
				}

				l_link.page = l_page;
				l_link.offset = l_offset;
				l_link.size = l_size;
				sprintf(l_link.filename, "%s", attr);
				
				if(canvas->pixmap != NULL){
					gdk_gc_get_values(canvas->gc, &gcv);
					color_save = gcv.foreground;
					gdk_gc_set_foreground(canvas->gc, 
							      &colors[COLOR_GREEN]);
				}
				l_text.text = _(" [Movie] ");
				l_text.length = strlen(l_text.text);

				draw_content(canvas, &l_text, binfo, &l_link);

				if(canvas->pixmap != NULL){
					gdk_gc_set_foreground(canvas->gc, &color_save);
				}

				skip_start_tag(&p, tag_name);

			} else {
//				fprintf(stderr, "warning: unknown tag <%s> found. Treated as plain text\n", tag_name);
				body[body_length] = *p;
				body_length ++;
				body[body_length] = '\0';
				p++;
			}
		} else {
			body[body_length] = *p;
			body_length ++;
			body[body_length] = '\0';
			p++;
		}

	}

	if(body_length != 0){
		l_text.text = body;
		l_text.length = body_length;
		draw_string(canvas, &l_text, link);
	}

}



syntax highlighted by Code2HTML, v. 0.9.1