/* -*- c-file-style: "ruby"; indent-tabs-mode: nil -*- */

/*
 *  Copyright (C) 2007-2009 Kouhei Sutou <kou@cozmixng.org>
 *  Copyright (C) 2006 Eriko Sato
 *
 *  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, 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 "kz-rb-ext.h"

#include <kz-embed.h>

#define _SELF(obj) (KZ_EMBED(RVAL2GOBJ(obj)))
#define RVAL2KZBOOKMARK(obj) (KZ_BOOKMARK(RVAL2GOBJ(obj)))
#define RVAL2KZBOOKMARKFOLDER(obj) (KZ_BOOKMARK_FOLDER(RVAL2GOBJ(obj)))
#define RVAL2KZNAVI(obj) (KZ_NAVI(RVAL2GOBJ(obj)))
#define RVAL2KZNAVLINK(obj) (RVAL2GENUM(obj, KZ_TYPE_EMBED_NAV_LINK))
#define RVAL2KZRF(obj) (RVAL2GENUM(obj, KZ_TYPE_EMBED_RELOAD_FLAG))
#define RVAL2KZCT(obj) (RVAL2GENUM(obj, KZ_TYPE_EMBED_COPY_TYPE))

static VALUE
rb_kz_embed_load_uri(VALUE self, VALUE url)
{
    kz_embed_load_uri(_SELF(self), RVAL2CSTR(url));
    return self;
}

static VALUE
rb_kz_embed_view_source(VALUE self, VALUE url)
{
    kz_embed_view_source(_SELF(self), RVAL2CSTR(url));
    return self;
}

static VALUE
rb_kz_embed_can_cut_selection(VALUE self)
{
    gboolean can_cut_selection;
    can_cut_selection = kz_embed_can_cut_selection(_SELF(self));
    return CBOOL2RVAL(can_cut_selection);
}

static VALUE
rb_kz_embed_can_copy_selection(VALUE self)
{
    gboolean can_copy_selection;
    can_copy_selection = kz_embed_can_copy_selection(_SELF(self));
    return CBOOL2RVAL(can_copy_selection);
}

static VALUE
rb_kz_embed_can_paste(VALUE self)
{
    gboolean can_paste;
    can_paste = kz_embed_can_paste(_SELF(self));
    return CBOOL2RVAL(can_paste);
}

static VALUE
rb_kz_embed_cut_selection(VALUE self)
{
    kz_embed_cut_selection(_SELF(self));
    return self;
}

static VALUE
rb_kz_embed_copy_selection(VALUE self)
{
    kz_embed_copy_selection(_SELF(self));
    return self;
}

static VALUE
rb_kz_embed_paste(VALUE self)
{
    kz_embed_paste(_SELF(self));
    return self;
}

static VALUE
rb_kz_embed_select_all(VALUE self)
{
    kz_embed_select_all(_SELF(self));
    return self;
}

static VALUE
rb_kz_embed_get_selection_string(VALUE self)
{
    gchar *string;
    VALUE rb_string;
    string = kz_embed_get_selection_string(_SELF(self));
    rb_string = CSTR2RVAL(string);
    g_free(string);
    return rb_string;
}

static VALUE
rb_kz_embed_find(VALUE self, VALUE keyword, VALUE backward)
{
    gboolean find;
    find = kz_embed_find(_SELF(self), STR2CSTR(keyword), RVAL2CBOOL(backward));
    return CBOOL2RVAL(find);
}

static VALUE
rb_kz_embed_incremental_search(VALUE self, VALUE keyword, VALUE backward)
{
    gboolean search;
    search = kz_embed_incremental_search(_SELF(self), STR2CSTR(keyword),
                                         RVAL2CBOOL(backward));
    return CBOOL2RVAL(search);
}

static VALUE
rb_kz_embed_selection_is_collapsed(VALUE self)
{
    gboolean collapsed;
    collapsed = kz_embed_selection_is_collapsed(_SELF(self));
    return CBOOL2RVAL(collapsed);
}

static VALUE
rb_kz_embed_get_links(int arc, VALUE *argv, VALUE self)
{
    VALUE rb_selected_only;
    int n;
    gboolean selected_only;
    GList *list = NULL;

    n = rb_scan_args(arc, argv, "01", &rb_selected_only);

    if (n == 0)
        rb_selected_only = Qfalse;

    selected_only = RTEST(rb_selected_only);

    if (kz_embed_get_links(_SELF(self), &list, selected_only))
        return GLIST2ARY(list);
    else
        return rb_ary_new();
}

static VALUE
rb_kz_embed_get_dest_anchors(VALUE self)
{
    GList *list = NULL;

    if (kz_embed_get_dest_anchors(_SELF(self), &list))
    {
        VALUE result = GLIST2ARY(list);
        g_list_free(list);
        return result;
    }
    else
    {
        return rb_ary_new();
    }
}

static VALUE
rb_kz_embed_copy_page(VALUE self, VALUE dkzembed)
{
    kz_embed_copy_page(_SELF(self), _SELF(dkzembed));
    return self;
}

static VALUE
rb_kz_embed_shistory_get_pos(VALUE self)
{
    gboolean success;
    gint pos, count;
    success = kz_embed_shistory_get_pos(_SELF(self), &pos, &count);

    if (success)
        return rb_ary_new3(2, INT2NUM(pos), INT2NUM(count));
    else
        return Qnil;
}

static VALUE
rb_kz_embed_shistory_get_nth(VALUE self, VALUE nth, VALUE is_relative)
{
    gchar *url, *title;
    kz_embed_shistory_get_nth(_SELF(self), NUM2INT(nth),
                              RVAL2CBOOL(is_relative), &url, &title);
    return rb_ary_new3(2, CSTR2RVAL(url), CSTR2RVAL(title));
}

static VALUE
rb_kz_embed_reload(VALUE self, VALUE flags)
{
    kz_embed_reload(_SELF(self), RVAL2KZRF(flags));
    return self;
}

static VALUE
rb_kz_embed_stop_load(VALUE self)
{
    kz_embed_stop_load(_SELF(self));
    return self;
}

static VALUE
rb_kz_embed_go_back(VALUE self)
{
    kz_embed_go_forward(_SELF(self));
    return self;
}

static VALUE
rb_kz_embed_go_forward(VALUE self)
{
    kz_embed_go_forward(_SELF(self));
    return self;
}

static VALUE
rb_kz_embed_can_go_back(VALUE self)
{
    gboolean can_go_back;
    can_go_back = kz_embed_can_go_back(_SELF(self));
    return CBOOL2RVAL(can_go_back);
}

static VALUE
rb_kz_embed_can_go_forward(VALUE self)
{
    gboolean can_go_forward;
    can_go_forward = kz_embed_can_go_forward(_SELF(self));
    return CBOOL2RVAL(can_go_forward);
}

static VALUE
rb_kz_embed_can_go_nav_link(VALUE self, VALUE link)
{
    gboolean can_go_nav_link;
    can_go_nav_link = kz_embed_can_go_nav_link(_SELF(self),
                                               RVAL2KZNAVLINK(link));
    return CBOOL2RVAL(can_go_nav_link);
}

static VALUE
rb_kz_embed_go_nav_link(VALUE self, VALUE link)
{
    kz_embed_go_nav_link(_SELF(self), RVAL2KZNAVLINK(link));
    return self;
}

static VALUE
rb_kz_embed_append_nav_link(VALUE self, VALUE link, VALUE navi)
{
    kz_embed_append_nav_link(_SELF(self), RVAL2KZNAVLINK(link),
                             RVAL2KZNAVI(navi));
    return self;
}

static VALUE
rb_kz_embed_set_nav_link(VALUE self, VALUE link, VALUE navi)
{
    kz_embed_set_nav_link(_SELF(self), RVAL2KZNAVLINK(link), RVAL2GOBJ(navi));
    return self;
}

static VALUE
rb_kz_embed_set_nth_nav_link(VALUE self, VALUE link, VALUE navi, VALUE n)
{
    kz_embed_set_nth_nav_link(_SELF(self), RVAL2KZNAVLINK(link),
                              RVAL2GOBJ(navi), NUM2UINT(n));
    return self;
}

static VALUE
rb_kz_embed_get_nav_link(VALUE self, VALUE link)
{
    KzNavi *get_nav_link;
    get_nav_link = kz_embed_get_nav_link(_SELF(self), RVAL2KZNAVLINK(link));
    return GOBJ2RVAL(get_nav_link);
}

static VALUE
rb_kz_embed_get_nth_nav_link(VALUE self, VALUE link, VALUE n)
{
    KzNavi *nth_nav_link;
    nth_nav_link = kz_embed_get_nth_nav_link(_SELF(self),
                                             RVAL2KZNAVLINK(link),
                                             NUM2UINT(n));
    return GOBJ2RVAL(nth_nav_link);
}

static VALUE
rb_kz_embed_get_nav_links(VALUE self, VALUE link)
{
    GList *nav_links;
    nav_links = kz_embed_get_nav_links(_SELF(self), RVAL2KZNAVLINK(link));
    return GLIST2ARY(nav_links);
}

static VALUE
rb_kz_embed_go_history_index(VALUE self, VALUE index)
{
    kz_embed_go_history_index(_SELF(self), NUM2INT(index));
    return self;
}

static VALUE
rb_kz_embed_get_body_text(VALUE self)
{
    gchar *text;
    VALUE rb_text;
    text = kz_embed_get_body_text(_SELF(self));
    rb_text = CSTR2RVAL(text);
    g_free(text);
    return rb_text;
}

static VALUE
rb_kz_embed_set_encoding(VALUE self, VALUE encoding)
{
    kz_embed_set_encoding(_SELF(self), STR2CSTR(encoding));
    return self;
}

static VALUE
rb_kz_embed_get_encoding(VALUE self)
{
    gchar *encoding;
    gboolean forced;
    kz_embed_get_encoding(_SELF(self), &encoding, &forced);
    return rb_ary_new3(2, CSTR2RVAL(encoding), CBOOL2RVAL(forced));
}

static VALUE
rb_kz_embed_print(VALUE self)
{
    kz_embed_print(_SELF(self));
    return self;
}

static VALUE
rb_kz_embed_print_preview(VALUE self)
{
    kz_embed_print_preview(_SELF(self));
    return self;
}

static VALUE
rb_kz_embed_get_printer_list(VALUE self)
{
    GList *list;
    list = kz_embed_get_printer_list(_SELF(self));
    return GLIST2ARY(list);
}

static VALUE
rb_kz_embed_create_thumbnail(int argc, VALUE *argv, VALUE self)
{
    EggPixbufThumbnailSize size;
    VALUE rb_size;

    rb_scan_args(argc, argv, "01", &rb_size);
    if (NIL_P(rb_size))
        size = EGG_PIXBUF_THUMBNAIL_LARGE;
    else
        size = NUM2INT(rb_size); /* FIXME */
    kz_embed_create_thumbnail(_SELF(self), size);
    return self;
}

static VALUE
rb_kz_embed_save_with_content(VALUE self, VALUE rawfilename)
{
    gboolean save;
    save = kz_embed_save_with_content(_SELF(self), STR2CSTR(rawfilename));
    return RVAL2CBOOL(save);
}

static VALUE
rb_kz_embed_get_html_with_contents(VALUE self, VALUE storedir)
{
    gchar *html;
    VALUE rb_html;
    html = kz_embed_get_html_with_contents(_SELF(self), RVAL2CSTR(storedir));
    rb_html = CSTR2RVAL(html);
    g_free(html);
    return rb_html;
}

static VALUE
rb_kz_embed_get_last_modified(VALUE self)
{
    guint last_modified;
    last_modified = kz_embed_get_last_modified(_SELF(self));
    return UINT2NUM(last_modified);
}

static VALUE
rb_kz_embed_fine_scroll(VALUE self, VALUE horiz, VALUE vert)
{
    kz_embed_fine_scroll(_SELF(self), NUM2INT(horiz), NUM2INT(vert));
    return self;
}

static VALUE
rb_kz_embed_page_up(VALUE self)
{
    kz_embed_page_up(_SELF(self));
    return self;
}

static VALUE
rb_kz_embed_page_down(VALUE self)
{
    kz_embed_page_down(_SELF(self));
    return self;
}

static VALUE
rb_kz_embed_get_allow_javascript(VALUE self)
{
    gboolean allow;
    allow = kz_embed_get_allow_javascript(_SELF(self));
    return CBOOL2RVAL(allow);
}

static VALUE
rb_kz_embed_set_allow_javascript(VALUE self, VALUE allow)
{
    kz_embed_set_allow_javascript(_SELF(self), RVAL2CBOOL(allow));
    return self;
}

static VALUE
rb_kz_embed_get_allow_images(VALUE self)
{
    gboolean allow;
    allow = kz_embed_get_allow_images(_SELF(self));
    return CBOOL2RVAL(allow);
}

static VALUE
rb_kz_embed_set_allow_images(VALUE self, VALUE allow)
{
    kz_embed_set_allow_images(_SELF(self), RVAL2CBOOL(allow));
    return self;
}

static VALUE
rb_kz_embed_show_page_certificate(VALUE self)
{
    kz_embed_show_page_certificate(_SELF(self));
    return self;
}

void
_kz_rb_embed_init(VALUE mKz)
{
    VALUE cKzEmbed;
    VALUE cKzGeckoEmbed;

    cKzEmbed = G_DEF_CLASS(KZ_TYPE_EMBED, "Embed", mKz);
    cKzGeckoEmbed = G_DEF_CLASS3("KzGeckoEmbed", "GeckoEmbed", mKz);

    G_DEF_CLASS(KZ_TYPE_EMBED_LOAD_FLAG, "EmbedLoadFlag", mKz);
    G_DEF_CLASS(KZ_TYPE_EMBED_RELOAD_FLAG, "EmbedReloadFlag", mKz);
    G_DEF_CLASS(KZ_TYPE_EMBED_GO_ACTION, "EmbedGoAction", mKz);
    G_DEF_CLASS(KZ_TYPE_EMBED_NAV_LINK, "EmbedNavLink", mKz);

    rb_define_method(cKzEmbed, "load_uri", rb_kz_embed_load_uri, 1);
    rb_define_method(cKzEmbed, "view_source",
                     rb_kz_embed_view_source, 1);
    rb_define_method(cKzEmbed, "can_cut_selection?",
                     rb_kz_embed_can_cut_selection, 0);
    rb_define_method(cKzEmbed, "can_copy_selection?",
                     rb_kz_embed_can_copy_selection, 0);
    rb_define_method(cKzEmbed, "can_paste?", rb_kz_embed_can_paste, 0);
    rb_define_method(cKzEmbed, "cut_selection",
                     rb_kz_embed_cut_selection, 0);
    rb_define_method(cKzEmbed, "copy_selection",
                     rb_kz_embed_copy_selection, 0);
    rb_define_method(cKzEmbed, "paste", rb_kz_embed_paste, 0);
    rb_define_method(cKzEmbed, "select_all", rb_kz_embed_select_all, 0);
    rb_define_method(cKzEmbed, "selection_string",
                     rb_kz_embed_get_selection_string, 0);
    rb_define_method(cKzEmbed, "find?", rb_kz_embed_find, 2);
    rb_define_method(cKzEmbed, "incremental_search?",
                     rb_kz_embed_incremental_search, 2);
    rb_define_method(cKzEmbed, "selection_is_collapsed?",
                     rb_kz_embed_selection_is_collapsed, 0);
    rb_define_method(cKzEmbed, "links", rb_kz_embed_get_links, -1);
    rb_define_method(cKzEmbed, "dest_anchors", rb_kz_embed_get_dest_anchors, 0);
    rb_define_method(cKzEmbed, "copy_page", rb_kz_embed_copy_page, 1);
    rb_define_method(cKzEmbed, "shistory_get_pos",
                     rb_kz_embed_shistory_get_pos, 0);
    rb_define_method(cKzEmbed, "shistory_get_nth",
                     rb_kz_embed_shistory_get_nth, 2);
    rb_define_method(cKzEmbed, "reload", rb_kz_embed_reload, 1);
    rb_define_method(cKzEmbed, "stop_load", rb_kz_embed_stop_load, 0);
    rb_define_method(cKzEmbed, "go_back", rb_kz_embed_go_back, 0);
    rb_define_method(cKzEmbed, "go_forward", rb_kz_embed_go_forward, 0);
    rb_define_method(cKzEmbed, "can_go_back?",
                     rb_kz_embed_can_go_back, 0);
    rb_define_method(cKzEmbed, "can_go_forward?",
                     rb_kz_embed_can_go_forward, 0);
    rb_define_method(cKzEmbed, "can_go_nav_link?",
                     rb_kz_embed_can_go_nav_link, 1);
    rb_define_method(cKzEmbed, "go_nav_link",
                     rb_kz_embed_go_nav_link, 1);
    rb_define_method(cKzEmbed, "append_nav_link",
                     rb_kz_embed_append_nav_link, 1);
    rb_define_method(cKzEmbed, "set_nav_link",
                     rb_kz_embed_set_nav_link, 2);
    rb_define_method(cKzEmbed, "set_nth_nav_link",
                     rb_kz_embed_set_nth_nav_link, 3);
    rb_define_method(cKzEmbed, "get_nav_link",
                     rb_kz_embed_get_nav_link, 1);
    rb_define_method(cKzEmbed, "get_nth_nav_link",
                     rb_kz_embed_get_nth_nav_link, 2);
    rb_define_method(cKzEmbed, "get_nav_links",
                     rb_kz_embed_get_nav_links, 1);
    rb_define_method(cKzEmbed, "go_history_index",
                     rb_kz_embed_go_history_index, 1);
    rb_define_method(cKzEmbed, "get_body_text",
                     rb_kz_embed_get_body_text, 0);
    rb_define_method(cKzEmbed, "set_encoding",
                     rb_kz_embed_set_encoding, 1);
    rb_define_method(cKzEmbed, "get_encoding",
                     rb_kz_embed_get_encoding, 0);
    rb_define_method(cKzEmbed, "print", rb_kz_embed_print, 0);
    rb_define_method(cKzEmbed, "print_preview",
                     rb_kz_embed_print_preview, 0);
    rb_define_method(cKzEmbed, "get_printer_list",
                     rb_kz_embed_get_printer_list, 0);
    rb_define_method(cKzEmbed, "create_thumbnail",
                     rb_kz_embed_create_thumbnail, -1);
    rb_define_method(cKzEmbed, "save_with_content",
                     rb_kz_embed_save_with_content, 1);
    rb_define_method(cKzEmbed, "get_html_with_contents",
                     rb_kz_embed_get_html_with_contents, 1);
    rb_define_method(cKzEmbed, "get_last_modified",
                     rb_kz_embed_get_last_modified, 0);
    rb_define_method(cKzEmbed, "fine_scroll", rb_kz_embed_fine_scroll, 2);
    rb_define_method(cKzEmbed, "page_up", rb_kz_embed_page_up, 0);
    rb_define_method(cKzEmbed, "page_down", rb_kz_embed_page_down, 0);
    rb_define_method(cKzEmbed, "allow_javascript?",
                     rb_kz_embed_get_allow_javascript, 0);
    rb_define_method(cKzEmbed, "set_allow_javascript",
                     rb_kz_embed_set_allow_javascript, 1);
    rb_define_method(cKzEmbed, "allow_images?",
                     rb_kz_embed_get_allow_images, 0);
    rb_define_method(cKzEmbed, "set_allow_images",
                     rb_kz_embed_set_allow_images, 1);
    rb_define_method(cKzEmbed, "show_page_certificate",
                     rb_kz_embed_show_page_certificate, 0);

    G_DEF_SETTERS(cKzEmbed);
}
