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

#include "kz-rb-ext.h"

#define RVAL2EVENTKEY(obj) \
  ((KzEmbedEventKey *)RVAL2BOXED(obj, KZ_TYPE_EMBED_EVENT_KEY))
#define RVAL2EVENTMOUSE(obj) \
  ((KzEmbedEventMouse *)RVAL2BOXED(obj, KZ_TYPE_EMBED_EVENT_MOUSE))

#define RVAL2EVENTTYPE(obj) \
  ((KzEmbedEventType)RVAL2GENUM(obj, KZ_TYPE_EMBED_EVENT_TYPE))
#define RVAL2EVENTKEYMODIFIER(obj) \
  RVAL2GFLAGS(obj, KZ_TYPE_EMBED_EVENT_KEY_MODIFIER)
#define RVAL2EVENTCONTEXT(obj) \
  RVAL2GFLAGS(obj, KZ_TYPE_EMBED_EVENT_CONTEXT)
#define EVENTKEYMODIFIER2RVAL(obj) \
  GFLAGS2RVAL(obj, KZ_TYPE_EMBED_EVENT_KEY_MODIFIER)
#define EVENTCONTEXT2RVAL(obj) \
  GFLAGS2RVAL(obj, KZ_TYPE_EMBED_EVENT_CONTEXT)


/* KzEmbedEvent */
#define DEFINE_EMBED_EVENT_FUNCS(type, TYPE)                            \
static VALUE                                                            \
rb_kz_ee_ ## type ## _get_context(VALUE self)                           \
{                                                                       \
    return EVENTCONTEXT2RVAL(RVAL2EVENT ## TYPE(self)->cinfo.context);  \
}                                                                       \
                                                                        \
static VALUE                                                            \
rb_kz_ee_ ## type ## _get_framed_page(VALUE self)                       \
{                                                                       \
    return CBOOL2RVAL(RVAL2EVENT ## TYPE(self)->cinfo.framed_page);     \
}                                                                       \
                                                                        \
static VALUE                                                            \
rb_kz_ee_ ## type ## _get_link(VALUE self)                              \
{                                                                       \
    return CSTR2RVAL(RVAL2EVENT ## TYPE(self)->cinfo.link);             \
}                                                                       \
                                                                        \
static VALUE                                                            \
rb_kz_ee_ ## type ## _get_linktext(VALUE self)                          \
{                                                                       \
    return CSTR2RVAL(RVAL2EVENT ## TYPE(self)->cinfo.linktext);         \
}                                                                       \
                                                                        \
static VALUE                                                            \
rb_kz_ee_ ## type ## _get_img(VALUE self)                               \
{                                                                       \
    return CSTR2RVAL(RVAL2EVENT ## TYPE(self)->cinfo.img);              \
}                                                                       \
                                                                        \
static VALUE                                                            \
rb_kz_ee_ ## type ## _get_frame_src(VALUE self)                         \
{                                                                       \
    return CSTR2RVAL(RVAL2EVENT ## TYPE(self)->cinfo.frame_src);        \
}


/* KzEmbedEventKey */
static VALUE
rb_kz_ee_key_initialize(VALUE self)
{
    G_INITIALIZE(self, kz_embed_event_new(KZ_EMBED_EVENT_KEY));
    return Qnil;
}

DEFINE_EMBED_EVENT_FUNCS(key, KEY)

static VALUE
rb_kz_ee_key_get_key(VALUE self)
{
    return INT2NUM(RVAL2EVENTKEY(self)->key);
}

static VALUE
rb_kz_ee_key_get_modifier(VALUE self)
{
    return EVENTKEYMODIFIER2RVAL(RVAL2EVENTKEY(self)->modifier);
}

static VALUE
rb_kz_ee_key_get_char_code(VALUE self)
{
    return INT2NUM(RVAL2EVENTKEY(self)->char_code);
}


/* KzEmbedEventMouse */
static VALUE
rb_kz_ee_mouse_initialize(VALUE self)
{
    G_INITIALIZE(self, kz_embed_event_new(KZ_EMBED_EVENT_MOUSE));
    return Qnil;
}

DEFINE_EMBED_EVENT_FUNCS(mouse, MOUSE)

static VALUE
rb_kz_ee_mouse_get_button(VALUE self)
{
    return INT2NUM(RVAL2EVENTMOUSE(self)->button);
}

static VALUE
rb_kz_ee_mouse_get_modifier(VALUE self)
{
    return EVENTKEYMODIFIER2RVAL(RVAL2EVENTMOUSE(self)->modifier);
}

static VALUE
rb_kz_ee_mouse_get_x(VALUE self)
{
    return INT2NUM(RVAL2EVENTMOUSE(self)->x);
}

static VALUE
rb_kz_ee_mouse_get_y(VALUE self)
{
    return INT2NUM(RVAL2EVENTMOUSE(self)->y);
}

static VALUE
rb_kz_ee_mouse_get_timestamp(VALUE self)
{
    return UINT2NUM(RVAL2EVENTMOUSE(self)->timestamp);
}


void
_kz_rb_embed_event_init(VALUE mKz)
{
    VALUE mKzEmbedEvent, cKzEmbedEventKey, cKzEmbedEventMouse;
    VALUE cKzEmbedEventKeyModifier, cKzEmbedEventContext;

    mKzEmbedEvent = rb_define_module_under(mKz, "EmbedEvent");
    cKzEmbedEventKey = G_DEF_CLASS(KZ_TYPE_EMBED_EVENT_KEY,
                                   "EmbedEventKey", mKz);
    cKzEmbedEventMouse = G_DEF_CLASS(KZ_TYPE_EMBED_EVENT_MOUSE,
                                     "EmbedEventMouse", mKz);

    cKzEmbedEventKeyModifier = G_DEF_CLASS(KZ_TYPE_EMBED_EVENT_KEY_MODIFIER,
                                           "EmbedEventKeyModifier", mKz);
    cKzEmbedEventContext = G_DEF_CLASS(KZ_TYPE_EMBED_EVENT_CONTEXT,
                                       "EmbedEventContext", mKz);
    G_DEF_CONSTANTS(mKzEmbedEvent, KZ_TYPE_EMBED_EVENT_KEY_MODIFIER, "KZ_");
    G_DEF_CONSTANTS(mKzEmbedEvent, KZ_TYPE_EMBED_EVENT_CONTEXT, "KZ_");

#define REGISTER_EMBED_EVENT_FUNKS(type, Type)                  \
    rb_define_method(cKzEmbedEvent ## Type, "context",          \
                     rb_kz_ee_ ## type ## _get_context, 0);     \
    rb_define_method(cKzEmbedEvent ## Type, "framed_page?",     \
                     rb_kz_ee_ ## type ## _get_framed_page, 0); \
    rb_define_method(cKzEmbedEvent ## Type, "link",             \
                     rb_kz_ee_ ## type ## _get_link, 0);        \
    rb_define_method(cKzEmbedEvent ## Type, "link_text",        \
                     rb_kz_ee_ ## type ## _get_linktext, 0);    \
    rb_define_method(cKzEmbedEvent ## Type, "img",              \
                     rb_kz_ee_ ## type ## _get_img, 0);         \
    rb_define_method(cKzEmbedEvent ## Type, "frame_src",        \
                     rb_kz_ee_ ## type ## _get_frame_src, 0);

    rb_define_method(cKzEmbedEventKey, "initialize",
                     rb_kz_ee_key_initialize, 0);
    REGISTER_EMBED_EVENT_FUNKS(key, Key)
    rb_define_method(cKzEmbedEventKey, "key", rb_kz_ee_key_get_key, 0);
    rb_define_method(cKzEmbedEventKey, "modifier",
                     rb_kz_ee_key_get_modifier, 0);
    rb_define_method(cKzEmbedEventKey, "char_code",
                     rb_kz_ee_key_get_char_code, 0);


    rb_define_method(cKzEmbedEventMouse, "initialize",
                     rb_kz_ee_mouse_initialize, 0);
    REGISTER_EMBED_EVENT_FUNKS(mouse, Mouse)
    rb_define_method(cKzEmbedEventMouse, "button",
                     rb_kz_ee_mouse_get_button, 0);
    rb_define_method(cKzEmbedEventMouse, "modifier",
                     rb_kz_ee_mouse_get_modifier, 0);
    rb_define_method(cKzEmbedEventMouse, "x", rb_kz_ee_mouse_get_x, 0);
    rb_define_method(cKzEmbedEventMouse, "y", rb_kz_ee_mouse_get_y, 0);
    rb_define_method(cKzEmbedEventMouse, "time_stamp",
                     rb_kz_ee_mouse_get_timestamp, 0);
}
