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

/*
 *  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 <stdio.h>
#include <glib/gi18n.h>
#include "kz-rb-ext.h"

#include "kz-ext-impl.h"

#ifdef POSIX_SIGNAL
#define ruby_signal(sig, handle) posix_signal((sig), (handle))
#else
#define ruby_signal(sig, handle) signal((sig), (handle))
#endif

#define INIT_PRE_RB "kazehakase-init-pre"
#define INIT_RB "kazehakase-init"

extern VALUE rb_load_path;
void Init_stack _((VALUE *));

static VALUE mKz;

ID rbgobj_id_children;

static VALUE
rb_kz_gettext(VALUE self, VALUE msgid)
{
    return CSTR2RVAL(_(RVAL2CSTR(msgid)));
}

static VALUE
rb_kz_get_backends(VALUE self)
{
    return rb_str_split(rb_str_new2(KZ_BACKENDS), ", ");
}

static void
Init_kz (void)
{
    gchar *config_dir, *actions_dir, *sidebars_dir;

    mKz = rb_define_module("Kz");

    rb_define_const(mKz, "VERSION", rb_str_new2(VERSION));
    rb_define_const(mKz, "URI", rb_str_new2(KAZEHAKASE_URI));
    rb_define_const(mKz, "PACKAGE", rb_str_new2(PACKAGE));

    config_dir = g_build_filename(g_get_home_dir(), "."PACKAGE, NULL);
    actions_dir = g_build_filename(config_dir, "actions", NULL);
    sidebars_dir = g_build_filename(config_dir, "sidebars", NULL);
    rb_define_const(mKz, "CONFIG_DIR", rb_str_new2(config_dir));
    rb_define_const(mKz, "ACTIONS_DIR", rb_str_new2(actions_dir));
    rb_define_const(mKz, "SIDEBARS_DIR", rb_str_new2(sidebars_dir));
    g_free(config_dir);
    g_free(actions_dir);
    g_free(sidebars_dir);

    rb_define_module_function(mKz, "gettext", rb_kz_gettext, 1);
    rb_define_module_function(mKz, "backends", rb_kz_get_backends, 0);
}

static void
kz_ext_ruby_init(void)
{
    RETSIGTYPE (*sigint_handler)_((int));
#ifdef SIGHUP
    RETSIGTYPE (*sighup_handler)_((int));
#endif
#ifdef SIGQUIT
    RETSIGTYPE (*sigquit_handler)_((int));
#endif
#ifdef SIGTERM
    RETSIGTYPE (*sigterm_handler)_((int));
#endif
#ifdef SIGSEGV
    RETSIGTYPE (*sigsegv_handler)_((int));
#endif

    sigint_handler = signal(SIGINT, SIG_DFL);
#ifdef SIGHUP
    sighup_handler = signal(SIGHUP, SIG_DFL);
#endif
#ifdef SIGQUIT
    sigquit_handler = signal(SIGQUIT, SIG_DFL);
#endif
#ifdef SIGTERM
    sigterm_handler = signal(SIGTERM, SIG_DFL);
#endif
#ifdef SIGSEGV
    sigsegv_handler = signal(SIGSEGV, SIG_DFL);
#endif

    ruby_init();

    ruby_signal(SIGINT, sigint_handler);
#ifdef SIGHUP
    ruby_signal(SIGHUP, sighup_handler);
#endif
#ifdef SIGQUIT
    ruby_signal(SIGQUIT, sigquit_handler);
#endif
#ifdef SIGTERM
    ruby_signal(SIGTERM, sigterm_handler);
#endif
#ifdef SIGSEGV
    ruby_signal(SIGSEGV, sigsegv_handler);
#endif
}

void
KZ_EXT_IMPL_INIT (KzApp *app, void *init_address)
{
    gchar *dirname;
    char *argv[] = {"kazehakase"};

    kz_ext_ruby_init();

    Init_stack(init_address);

    ruby_init_loadpath();

    ruby_script("kazehakase");
    ruby_set_argv(1, argv);

    dirname = g_build_filename(KZ_DATADIR, "ext", "ruby", NULL);
    rb_ary_unshift(rb_load_path, rb_str_new2(dirname));
    g_free(dirname);

    rb_ary_unshift(rb_load_path, rb_str_new2(KZ_RUBY_EXTDIR));

    Init_kz();

    rb_funcall(Qnil, rb_intern("require"), 1, rb_str_new2(INIT_PRE_RB));

    if (RTEST(rb_const_get(mKz, rb_intern("ENABLE")))) {
        Init_kz_rb_app(mKz, app);
        Init_kz_rb_window(mKz);
        Init_kz_rb_notebook(mKz);
        Init_kz_rb_statusbar(mKz);
        Init_kz_rb_embed(mKz);
        Init_kz_rb_embed_event(mKz);
        Init_kz_rb_conf(mKz);
        Init_kz_rb_downloader(mKz);
        Init_kz_rb_downloader_group(mKz);
        Init_kz_rb_bookmark(mKz);
        Init_kz_rb_sidebar(mKz);

        rb_funcall(Qnil, rb_intern("require"), 1, rb_str_new2(INIT_RB));
    }
}

void
KZ_EXT_IMPL_SETUP (KzWindow *kz)
{
    if (RTEST(rb_const_get(mKz, rb_intern("ENABLE")))) {
        rb_funcall(mKz, rb_intern("setup"), 1, GOBJ2RVAL(kz));
        kz_rb_setup_sidebar(kz);
    }
}

void
KZ_EXT_IMPL_EXIT (gboolean success)
{
    rb_funcall(mKz, rb_intern("exit"), 0);
    ruby_cleanup(0);
}
