
#include "defs.h"

#include "audio.h"
#include "ebook.h"
#include "jcode.h"
#include "history.h"
#include "textview.h"
#include "video.h"
#include "render.h"

void render_parse_link(RenderTextCtx *ctx, gchar *str, RESULT *lnk)
{
    gint i;
    gchar **ca = g_strsplit_set(str, "= >", 0);
    if(!lnk) lnk = ctx->link;
    for(i = 0; i < g_strv_length(ca); i += 2)
    {
	if(!g_strcmp0(ca[i], "page"))
	    lnk->pos.page = g_ascii_strtoll(ca[i+1], NULL, 16);
	if(!g_strcmp0(ca[i], "offset"))
	    lnk->pos.offset = g_ascii_strtoll(ca[i+1], NULL, 16);
	if(!g_strcmp0(ca[i], "size"))
	    lnk->size = g_ascii_strtoll(ca[i+1], NULL, 10);
	if(!g_strcmp0(ca[i], "filename"))
	    lnk->filename = g_strdup(ca[i+1]);
    }
    g_strfreev(ca);
}

void render_gaiji(RenderTextCtx *ctx, gchar *code)
{
    GdkPixbuf *pixbuf;
    GtkTextIter iter;
    gint w, h;

    if(!(pixbuf = ebook_read_gaiji(ctx->binfo, code, &w, &h)))
	return;
    gtk_text_buffer_get_end_iter(ctx->buf, &iter);
    gtk_text_buffer_insert_pixbuf(ctx->buf, &iter, pixbuf);
}

void render_startElement(void *ctx, const xmlChar *name, const xmlChar **atts)
{
    GtkTextIter iter;
    RenderTextCtx *my = (RenderTextCtx*)ctx;
    gchar type[16];
    sprintf(type, "%s", name);
    gint len = atts ? g_strv_length((gchar**)atts) : 0;
    gtk_text_buffer_get_end_iter(my->buf, &iter);
    if(!g_strcmp0((char*)name, "gaiji") && (len > 1))
    {
	render_gaiji(my, (gchar *)atts[1]);
	return;
    }
    else if(!g_strcmp0((char*)name, "indent") && (len > 1))
    {
	gint indent = g_ascii_strtoll((gchar*)atts[1], NULL, 10), i;
	for(i = 0; i < indent; i++)
	    gtk_text_buffer_insert(my->buf, &iter, " ", -1);
	return;
    }
    else if(!g_strcmp0((char*)name, "reference") || !strcmp((char*)name, "candidate"))
    {
	sprintf(type, "%s", "link");
    }
    else if((!g_strcmp0((char*)name, "jpeg") || !strcmp((char*)name, "bmp")) && (len > 3))
    {
	GdkPixbuf *pixbuf;
	EB_Position pos;
	pos.page = g_ascii_strtoll((gchar*)atts[1], NULL, 16);
	pos.offset = g_ascii_strtoll((gchar*)atts[3], NULL, 16);
	pixbuf = ebook_load_image(my->binfo, &pos);
	if(pixbuf)
	{
	    gtk_text_buffer_insert_pixbuf(my->buf, &iter, pixbuf);
	    gtk_text_buffer_insert(my->buf, &iter, "\r\0", -1);
	}
	return;
    }
    else if(!g_strcmp0((char*)name, "mpeg"))
    {
	my->link = result_new(my->binfo, NULL);
	my->link->filename = g_strdup((gchar*)atts[1]);
    }
    gtk_text_buffer_get_end_iter(my->buf, &iter);
    gtk_text_buffer_create_mark(my->buf, type, &iter, TRUE);
}

gboolean render_get_last_mark(RenderTextCtx *ctx, const gchar *name, GtkTextIter *iter1, GtkTextIter *iter2)
{
    GtkTextMark *mark = gtk_text_buffer_get_mark(ctx->buf, name);
    if(mark)
    {
	gtk_text_buffer_get_iter_at_mark(ctx->buf, iter1, mark);
	gtk_text_buffer_delete_mark(ctx->buf, mark);
	gtk_text_buffer_get_end_iter(ctx->buf, iter2);
	return TRUE;
    }
    return FALSE;
}

gint render_get_font_size(GtkWidget *w)
{

}

void render_endElement(void *ctx, const xmlChar *name)
{
    const gchar *color = "#000000";
    gchar type[16];
    GtkTextIter iter1, iter2;
    RenderTextCtx *my = (RenderTextCtx*)ctx;
    gtk_text_buffer_get_end_iter(my->buf, &iter2);
    sprintf(type, "%s", name);
    if(!g_strcmp0((char*)name, "keyword"))
	color = prefs_get_str(my->prefs, "color.keyword");
    else if(!g_strcmp0((char*)name, "reference") || !strcmp((char*)name, "candidate"))
    {
	color = prefs_get_str(my->prefs, "color.link");
	sprintf(type, "%s", "link");
    }
    else if(!g_strcmp0((char*)name, "wave"))
    {
	Audio *audio = g_object_new(TYPE_AUDIO, "link", my->link, NULL);
	audio_render(audio, my);
    }
    else if(!g_strcmp0((char*)name, "mpeg"))
    {
	Video *video = g_object_new(TYPE_VIDEO, "link", my->link, NULL);
	video_render(video, my);
    }
    else if(!g_strcmp0((char*)name, "sup"))
    {
    }
    else
	return;
    if(render_get_last_mark(my, type, &iter1, &iter2))
    {
	pango_font_description_get_size
	if(!g_strcmp0((char*)name, "sup"))
	{
	    GtkTextTag *tag = gtk_text_buffer_create_tag(my->buf, NULL, "rise", 10*PANGO_SCALE, "size", 8*PANGO_SCALE, NULL);
	    gtk_text_buffer_apply_tag(my->buf, tag, &iter1, &iter2);
	}
	GtkTextTag *tag = gtk_text_buffer_create_tag(my->buf, NULL, "foreground", color, NULL);
	gtk_text_buffer_apply_tag(my->buf, tag, &iter1, &iter2);
	if(my->link ? !my->link->filename : TRUE)
	    my->link = result_new(my->binfo, NULL);
	g_object_set_data_full(G_OBJECT(tag), type, my->link, result_free);
    }
}

void render_characters(void *ctx, const xmlChar *ch, int len)
{
    gchar *s = g_strstr_len((gchar*)ch, len, ">");
    GtkTextIter iter, iter2;
    RenderTextCtx *my = (RenderTextCtx*)ctx;
    if(s)
    {
	GtkTextIter end;
	render_parse_link(my, (gchar*)ch, NULL);
	gtk_text_buffer_get_end_iter(my->buf, &end);
	gtk_text_buffer_insert(my->buf, &end, &(s[1]), -1);
	return;
    }
    gtk_text_buffer_get_end_iter(my->buf, &iter);
    gtk_text_buffer_insert(my->buf, &iter, (gchar*)ch, len);
    gtk_text_buffer_get_end_iter(my->buf, &iter2);
}

void render_title(RenderTextCtx *ctx, gchar *title)
{
    GtkTextIter iter;
    GtkTextTag *tag;
    const gchar *color = prefs_get_str(ctx->prefs, "color.title");
    gtk_text_buffer_get_end_iter(ctx->buf, &iter);
    tag = gtk_text_buffer_create_tag(ctx->buf, NULL, "foreground", color, "justification", GTK_JUSTIFY_CENTER, "scale", 1.2, "weight", PANGO_WEIGHT_BOLD, NULL);
    gtk_text_buffer_insert_with_tags(ctx->buf, &iter, "---", -1, tag, NULL);
    gtk_text_buffer_insert_with_tags(ctx->buf, &iter, title, -1, tag, NULL);
    gtk_text_buffer_insert_with_tags(ctx->buf, &iter, "---", -1, tag, NULL);
    gtk_text_buffer_insert(ctx->buf, &iter, "\n", -1);
}

void render_text(BOOK_INFO *binfo, TextView *view, const gchar *text, const gchar *word, Prefs *prefs)
{
    gchar *utf_text = iconv_convert(ENC_EUC_JP, ENC_UTF8, text);
    htmlSAXHandler cb;
    memset(&cb, 0, sizeof(htmlSAXHandler));
    cb.startElement = &render_startElement;
    cb.endElement = &render_endElement;
    cb.characters = &render_characters;
    RenderTextCtx ctx;
    ctx.binfo = binfo;
    ctx.view = view;
    ctx.buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
    ctx.prefs = prefs;
    ctx.link = NULL;
    render_title(&ctx, binfo->title);
    htmlDocPtr doc = htmlSAXParseDoc((xmlChar*)utf_text, ENC_UTF8, &cb, &ctx);
    xmlFreeDoc(doc);
    g_free(utf_text);
}

