#include <string.h>

#include <gdk/gdkkeysyms.h>

#include "gtk/gtkintl.h"
#include "gtk/gtkimcontextsimple.h"
#include "gtk/gtkimmodule.h"
#include <glib/gtypes.h>

GType type_imhiragana = 0;

static void imhiragana_class_init (GtkIMContextSimpleClass *class);
static void imhiragana_init (GtkIMContextSimple *im_context);

static void
imhiragana_register_type (GTypeModule *module)
{
  static const GTypeInfo object_info =
  {
    sizeof (GtkIMContextSimpleClass),
    (GBaseInitFunc) NULL,
    (GBaseFinalizeFunc) NULL,
    (GClassInitFunc) imhiragana_class_init,
    NULL,           /* class_finalize */
    NULL,           /* class_data */
    sizeof (GtkIMContextSimple),
    0,
    (GInstanceInitFunc) imhiragana_init,
  };

  type_imhiragana = 
    g_type_module_register_type (module,
				 GTK_TYPE_IM_CONTEXT_SIMPLE,
				 "GtkIMContextHiragana",
				 &object_info, 0);
}

#define N_COMPOSE 3
#define N_PEND_COMPOSE 1
typedef struct _MyRecord {
  guint16 compose_keys[N_COMPOSE];
  guint16 pend_compose_keys[N_PEND_COMPOSE];
  guchar output_str[10];
} MyRecord;

static MyRecord my_records[] = {
  GDK_a,      0,	0,	0, "あ",

  GDK_b,      0,	0,	0, "ｂ",
  GDK_b,      GDK_a,	0,	0, "ば",
  GDK_b,      GDK_b,    0,	GDK_b,  "っ",
  GDK_b,      GDK_e,	0,	0, "べ",
  GDK_b,      GDK_i,	0,	0, "び",
  GDK_b,      GDK_o,	0,	0, "ぼ",
  GDK_b,      GDK_u,	0,	0, "ぶ",
  GDK_b,      GDK_y,	0,	0, "ｂｙ",
  GDK_b,      GDK_y,	GDK_a,	0, "びゃ",
  GDK_b,      GDK_y,	GDK_e,	0, "びぇ",
  GDK_b,      GDK_y,	GDK_i,	0, "びぃ",
  GDK_b,      GDK_y,	GDK_o,	0, "びょ",
  GDK_b,      GDK_y,	GDK_u,	0, "びゅ",

  GDK_c,      0,	0,	0, "ｃ",
  GDK_c,      GDK_c,    0,	GDK_c,  "っ",
  GDK_c,      GDK_h,	0,	0, "ｃｈ",
  GDK_c,      GDK_h,	GDK_a,	0, "ちゃ",
  GDK_c,      GDK_h,	GDK_e,	0, "ちぇ",
  GDK_c,      GDK_h,	GDK_i,	0, "ち",
  GDK_c,      GDK_h,	GDK_o,	0, "ちょ",
  GDK_c,      GDK_h,	GDK_u,	0, "ちゅ",
  GDK_c,      GDK_y,	0,	0, "ｃｙ",
  GDK_c,      GDK_y,	GDK_a,	0, "ちゃ",
  GDK_c,      GDK_y,	GDK_e,	0, "ちぇ",
  GDK_c,      GDK_y,	GDK_i,	0, "ちぃ",
  GDK_c,      GDK_y,	GDK_o,	0, "ちょ",
  GDK_c,      GDK_y,	GDK_u,	0, "ちゅ",

  GDK_d,      0,	0,	0, "ｄ",
  GDK_d,      GDK_a,	0,	0, "だ",
  GDK_d,      GDK_d,    0,	GDK_d,  "っ",
  GDK_d,      GDK_e,	0,	0, "で",
  GDK_d,      GDK_h,	0,	0, "ｄｈ",
  GDK_d,      GDK_h,	GDK_a,	0, "でゃ",
  GDK_d,      GDK_h,	GDK_e,	0, "でぇ",
  GDK_d,      GDK_h,	GDK_i,	0, "でぃ",
  GDK_d,      GDK_h,	GDK_o,	0, "でょ",
  GDK_d,      GDK_h,	GDK_u,	0, "でゅ",
  GDK_d,      GDK_i,	0,	0, "ぢ",
  GDK_d,      GDK_o,	0,	0, "ど",
  GDK_d,      GDK_u,	0,	0, "づ",
  GDK_d,      GDK_y,	0,	0, "ｄｙ",
  GDK_d,      GDK_y,	GDK_a,	0, "ぢゃ",
  GDK_d,      GDK_y,	GDK_e,	0, "ぢぇ",
  GDK_d,      GDK_y,	GDK_i,	0, "ぢぃ",
  GDK_d,      GDK_y,	GDK_o,	0, "ぢょ",
  GDK_d,      GDK_y,	GDK_u,	0, "ぢゅ",

  GDK_e,      0,	0,	0, "え",

  GDK_f,      0,	0,	0, "ｆ",
  GDK_f,      GDK_a,	0,	0, "ふぁ",
  GDK_f,      GDK_e,	0,	0, "ふぇ",
  GDK_f,      GDK_f,    0,	GDK_f,  "っ",
  GDK_f,      GDK_i,	0,	0, "ふぃ",
  GDK_f,      GDK_o,	0,	0, "ふぉ",
  GDK_f,      GDK_u,	0,	0, "ふ",
  GDK_f,      GDK_y,	0,	0, "ｆｙ",
  GDK_f,      GDK_y,	GDK_a,	0, "ふゃ",
  GDK_f,      GDK_y,	GDK_e,	0, "ふぇ",
  GDK_f,      GDK_y,	GDK_i,	0, "ふぃ",
  GDK_f,      GDK_y,	GDK_o,	0, "ふょ",
  GDK_f,      GDK_y,	GDK_u,	0, "ふゅ",

  GDK_g,      0,	0,	0, "ｇ",
  GDK_g,      GDK_a,	0,	0, "が",
  GDK_g,      GDK_e,	0,	0, "げ",
  GDK_g,      GDK_g,    0,	GDK_g,  "っ",
  GDK_g,      GDK_i,	0,	0, "ぎ",
  GDK_g,      GDK_o,	0,	0, "ご",
  GDK_g,      GDK_u,	0,	0, "ぐ",
  GDK_g,      GDK_y,	0,	0, "ｇｙ",
  GDK_g,      GDK_y,	GDK_a,	0, "ぎゃ",
  GDK_g,      GDK_y,	GDK_e,	0, "ぎぇ",
  GDK_g,      GDK_y,	GDK_i,	0, "ぎぃ",
  GDK_g,      GDK_y,	GDK_o,	0, "ぎょ",
  GDK_g,      GDK_y,	GDK_u,	0, "ぎゅ",

  GDK_h,      0,	0,	0, "ｈ",
  GDK_h,      GDK_a,	0,	0, "は",
  GDK_h,      GDK_e,	0,	0, "へ",
  GDK_h,      GDK_h,    0,	GDK_h,  "っ",
  GDK_h,      GDK_i,	0,	0, "ひ",
  GDK_h,      GDK_o,	0,	0, "ほ",
  GDK_h,      GDK_u,	0,	0, "ふ",
  GDK_h,      GDK_y,	0,	0, "ｈｙ",
  GDK_h,      GDK_y,	GDK_a,	0, "ひゃ",
  GDK_h,      GDK_y,	GDK_e,	0, "ひぇ",
  GDK_h,      GDK_y,	GDK_i,	0, "ひぃ",
  GDK_h,      GDK_y,	GDK_o,	0, "ひょ",
  GDK_h,      GDK_y,	GDK_u,	0, "ひゅ",

  GDK_i,      0,	0,	0, "い",

  GDK_j,      0,	0,	0, "ｊ",
  GDK_j,      GDK_a,	0,	0, "じゃ",
  GDK_j,      GDK_e,	0,	0, "じぇ",
  GDK_j,      GDK_i,	0,	0, "じ",
  GDK_j,      GDK_j,    0,	GDK_j,  "っ",
  GDK_j,      GDK_o,	0,	0, "じょ",
  GDK_j,      GDK_u,	0,	0, "じゅ",
  GDK_j,      GDK_y,	0,	0, "ｊｙ",
  GDK_j,      GDK_y,	GDK_a,	0, "じゃ",
  GDK_j,      GDK_y,	GDK_e,	0, "じぇ",
  GDK_j,      GDK_y,	GDK_i,	0, "じぃ",
  GDK_j,      GDK_y,	GDK_o,	0, "じょ",
  GDK_j,      GDK_y,	GDK_u,	0, "じゅ",

  GDK_k,      0,	0,	0, "ｋ",
  GDK_k,      GDK_a,	0,	0, "か",
  GDK_k,      GDK_e,	0,	0, "け",
  GDK_k,      GDK_i,	0,	0, "き",
  GDK_k,      GDK_k,    0,	GDK_k,  "っ",
  GDK_k,      GDK_o,	0,	0, "こ",
  GDK_k,      GDK_u,	0,	0, "く",
  GDK_k,      GDK_y,	0,	0, "ｋｙ",
  GDK_k,      GDK_y,	GDK_a,	0, "きゃ",
  GDK_k,      GDK_y,	GDK_e,	0, "きぇ",
  GDK_k,      GDK_y,	GDK_i,	0, "きぃ",
  GDK_k,      GDK_y,	GDK_o,	0, "きょ",
  GDK_k,      GDK_y,	GDK_u,	0, "きゅ",

  GDK_l,      0,	0,	0, "ｌ",
  GDK_l,      GDK_a,	0,	0, "ぁ",
  GDK_l,      GDK_e,	0,	0, "ぇ",
  GDK_l,      GDK_i,	0,	0, "ぃ",
  GDK_l,      GDK_l,    0,	GDK_l,  "っ",
  GDK_l,      GDK_o,	0,	0, "ぉ",
  GDK_l,      GDK_t,	GDK_u,	0, "っ",
  GDK_l,      GDK_u,	0,	0, "ぅ",
  GDK_l,      GDK_y,	0,	0, "ｌｙ",
  GDK_l,      GDK_y,	GDK_a,	0, "ゃ",
  GDK_l,      GDK_y,	GDK_e,	0, "ぇ",
  GDK_l,      GDK_y,	GDK_i,	0, "ぃ",
  GDK_l,      GDK_y,	GDK_o,	0, "ょ",
  GDK_l,      GDK_y,	GDK_u,	0, "ゅ",

  GDK_m,      0,	0,	0, "ｍ",
  GDK_m,      GDK_a,	0,	0, "ま",
  GDK_m,      GDK_e,	0,	0, "め",
  GDK_m,      GDK_i,	0,	0, "み",
  GDK_m,      GDK_m,    0,	GDK_m,  "っ",
  GDK_m,      GDK_o,	0,	0, "も",
  GDK_m,      GDK_u,	0,	0, "む",
  GDK_m,      GDK_y,	0,	0, "ｍｙ",
  GDK_m,      GDK_y,	GDK_a,	0, "みゃ",
  GDK_m,      GDK_y,	GDK_e,	0, "みぇ",
  GDK_m,      GDK_y,	GDK_i,	0, "みぃ",
  GDK_m,      GDK_y,	GDK_o,	0, "みょ",
  GDK_m,      GDK_y,	GDK_u,	0, "みゅ",

  GDK_n,      0,	0,	0, "ｎ",
  GDK_n,      '\'',	0,	0, "ん",
  GDK_n,      GDK_a,	0,	0, "な",
  GDK_n,      GDK_e,	0,	0, "ね",
  GDK_n,      GDK_i,	0,	0, "に",
  GDK_n,      GDK_n,	0,	0, "ん",
  GDK_n,      GDK_o,	0,	0, "の",
  GDK_n,      GDK_u,	0,	0, "ぬ",
  GDK_n,      GDK_y,	0,	0, "ｎｙ",
  GDK_n,      GDK_y,	GDK_a,	0, "にゃ",
  GDK_n,      GDK_y,	GDK_e,	0, "にぇ",
  GDK_n,      GDK_y,	GDK_i,	0, "にぃ",
  GDK_n,      GDK_y,	GDK_o,	0, "にょ",
  GDK_n,      GDK_y,	GDK_u,	0, "にゅ",

  GDK_o,      0,	0,	0, "お",

  GDK_p,      0,	0,	0, "ｐ",
  GDK_p,      GDK_a,	0,	0, "ぱ",
  GDK_p,      GDK_e,	0,	0, "ぺ",
  GDK_p,      GDK_i,	0,	0, "ぴ",
  GDK_p,      GDK_o,	0,	0, "ぽ",
  GDK_p,      GDK_p,    0,	GDK_p,  "っ",
  GDK_p,      GDK_u,	0,	0, "ぷ",
  GDK_p,      GDK_y,	0,	0, "ｐｙ",
  GDK_p,      GDK_y,	GDK_a,	0, "ぴゃ",
  GDK_p,      GDK_y,	GDK_e,	0, "ぴぇ",
  GDK_p,      GDK_y,	GDK_i,	0, "ぴぃ",
  GDK_p,      GDK_y,	GDK_o,	0, "ぴょ",
  GDK_p,      GDK_y,	GDK_u,	0, "ぴゅ",

  GDK_q,      0,	0,	0, "ｑ",

  GDK_r,      0,	0,	0, "ｒ",
  GDK_r,      GDK_a,	0,	0, "ら",
  GDK_r,      GDK_e,	0,	0, "れ",
  GDK_r,      GDK_i,	0,	0, "り",
  GDK_r,      GDK_o,	0,	0, "ろ",
  GDK_r,      GDK_r,    0,	GDK_r,  "っ",
  GDK_r,      GDK_u,	0,	0, "る",
  GDK_r,      GDK_y,	0,	0, "ｒｙ",
  GDK_r,      GDK_y,	GDK_a,	0, "りゃ",
  GDK_r,      GDK_y,	GDK_e,	0, "りぇ",
  GDK_r,      GDK_y,	GDK_i,	0, "りぃ",
  GDK_r,      GDK_y,	GDK_o,	0, "りょ",
  GDK_r,      GDK_y,	GDK_u,	0, "りゅ",

  GDK_s,      0,	0,	0, "ｓ",
  GDK_s,      GDK_a,	0,	0, "さ",
  GDK_s,      GDK_e,	0,	0, "せ",
  GDK_s,      GDK_h,	0,	0, "ｓｈ",
  GDK_s,      GDK_h,	GDK_a,	0, "しゃ",
  GDK_s,      GDK_h,	GDK_e,	0, "しぇ",
  GDK_s,      GDK_h,	GDK_i,	0, "し",
  GDK_s,      GDK_h,	GDK_o,	0, "しょ",
  GDK_s,      GDK_h,	GDK_u,	0, "しゅ",
  GDK_s,      GDK_i,	0,	0, "し",
  GDK_s,      GDK_o,	0,	0, "そ",
  GDK_s,      GDK_s,    0,	GDK_s,  "っ",
  GDK_s,      GDK_u,	0,	0, "す",
  GDK_s,      GDK_y,	0,	0, "ｓｙ",
  GDK_s,      GDK_y,	GDK_a,	0, "しゃ",
  GDK_s,      GDK_y,	GDK_e,	0, "しぇ",
  GDK_s,      GDK_y,	GDK_i,	0, "しぃ",
  GDK_s,      GDK_y,	GDK_o,	0, "しょ",
  GDK_s,      GDK_y,	GDK_u,	0, "しゅ",

  GDK_t,      0,	0,	0, "ｔ",
  GDK_t,      GDK_a,	0,	0, "た",
  GDK_t,      GDK_e,	0,	0, "て",
  GDK_t,      GDK_h,	0,	0, "ｔｈ",
  GDK_t,      GDK_h,	GDK_a,	0, "てゃ",
  GDK_t,      GDK_h,	GDK_e,	0, "てぇ",
  GDK_t,      GDK_h,	GDK_i,	0, "てぃ",
  GDK_t,      GDK_h,	GDK_o,	0, "てょ",
  GDK_t,      GDK_h,	GDK_u,	0, "てゅ",
  GDK_t,      GDK_i,	0,	0, "ち",
  GDK_t,      GDK_o,	0,	0, "と",
  GDK_t,      GDK_s,	GDK_a,	0, "つぁ",
  GDK_t,      GDK_s,	GDK_e,	0, "つぇ",
  GDK_t,      GDK_s,	GDK_i,	0, "つぃ",
  GDK_t,      GDK_s,	GDK_o,	0, "つぉ",
  GDK_t,      GDK_s,	GDK_u,	0, "つ",
  GDK_t,      GDK_t,    0,	GDK_t,  "っ",
  GDK_t,      GDK_u,	0,	0, "つ",
  GDK_t,      GDK_y,	0,	0, "ｔｙ",
  GDK_t,      GDK_y,	GDK_a,	0, "ちゃ",
  GDK_t,      GDK_y,	GDK_e,	0, "ちぇ",
  GDK_t,      GDK_y,	GDK_i,	0, "ちぃ",
  GDK_t,      GDK_y,	GDK_o,	0, "ちょ",
  GDK_t,      GDK_y,	GDK_u,	0, "ちゅ",

  GDK_u,      0,	0,	0, "う",

  GDK_v,      0,	0,	0, "ｖ",
  GDK_v,      GDK_a,	0,	0, "う゛ぁ",
  GDK_v,      GDK_e,	0,	0, "う゛ぇ",
  GDK_v,      GDK_i,	0,	0, "う゛ぃ",
  GDK_v,      GDK_o,	0,	0, "う゛ぉ",
  GDK_v,      GDK_u,	0,	0, "う゛",
  GDK_v,      GDK_v,    0,	GDK_v,  "っ",

  GDK_w,      0,	0,	0, "ｗ",
  GDK_w,      GDK_a,	0,	0, "わ",
  GDK_w,      GDK_e,	0,	0, "うぇ",
  GDK_w,      GDK_i,	0,	0, "うぃ",
  GDK_w,      GDK_o,	0,	0, "を",
  GDK_w,      GDK_u,	0,	0, "う",
  GDK_w,      GDK_w,    0,	GDK_w,  "っ",

  GDK_x,      0,	0,	0, "ｘ",
  GDK_x,      GDK_a,	0,	0, "ぁ",
  GDK_x,      GDK_e,	0,	0, "ぇ",
  GDK_x,      GDK_i,	0,	0, "ぃ",
  GDK_x,      GDK_o,	0,	0, "ぉ",
  GDK_x,      GDK_t,	GDK_u,	0, "っ",
  GDK_x,      GDK_u,	0,	0, "ぅ",
  GDK_x,      GDK_x,    0,	GDK_x,  "っ",
  GDK_x,      GDK_y,	0,	0, "ｘｙ",
  GDK_x,      GDK_y,	GDK_a,	0, "ゃ",
  GDK_x,      GDK_y,	GDK_e,	0, "ぇ",
  GDK_x,      GDK_y,	GDK_i,	0, "ぃ",
  GDK_x,      GDK_y,	GDK_o,	0, "ょ",
  GDK_x,      GDK_y,	GDK_u,	0, "ゅ",

  GDK_y,      0,	0,	0, "ｙ",
  GDK_y,      GDK_a,	0,	0, "や",
  GDK_y,      GDK_e,	0,	0, "いぇ",
  GDK_y,      GDK_i,	0,	0, "い",
  GDK_y,      GDK_o,	0,	0, "よ",
  GDK_y,      GDK_u,	0,	0, "ゆ",
  GDK_y,      GDK_y,    0,	GDK_y,  "っ",

  GDK_z,      0,	0,	0, "ｚ",
  GDK_z,      GDK_a,	0,	0, "ざ",
  GDK_z,      GDK_e,	0,	0, "ぜ",
  GDK_z,      GDK_i,	0,	0, "ぃ",
  GDK_z,      GDK_o,	0,	0, "ぞ",
  GDK_z,      GDK_u,	0,	0, "ず",
  GDK_z,      GDK_y,	0,	0, "ｚｙ",
  GDK_z,      GDK_y,	GDK_a,	0, "じゃ",
  GDK_z,      GDK_y,	GDK_e,	0, "じぇ",
  GDK_z,      GDK_y,	GDK_i,	0, "じぃ",
  GDK_z,      GDK_y,	GDK_o,	0, "じょ",
  GDK_z,      GDK_y,	GDK_u,	0, "じゅ",
  GDK_z,      GDK_z,    0,	GDK_z,  "っ"

};

static void
imhiragana_class_init (GtkIMContextSimpleClass *class)
{
}

static void
imhiragana_init (GtkIMContextSimple *im_context)
{
  gsize record_size;
  
  gtk_im_context_simple_add_records (im_context,
				     (void*)my_records,
				     G_N_ELEMENTS (my_records),
				     sizeof (MyRecord),
				     N_COMPOSE,
				     N_PEND_COMPOSE,
				     G_STRUCT_OFFSET (MyRecord, output_str));
}

static const GtkIMContextInfo imhiragana_info = { 
  "imhiragana",		   /* ID */
  N_("Hiragana"),	   /* Human readable name */
  "",			   /* Translation domain */
  "",
  ""
};

static const GtkIMContextInfo *info_list[] = {
  &imhiragana_info
};

void
im_module_init (GTypeModule *module)
{
  imhiragana_register_type (module);
}

void 
im_module_exit (void)
{
}

void 
im_module_list (const GtkIMContextInfo ***contexts,
		int                      *n_contexts)
{
  *contexts = info_list;
  *n_contexts = G_N_ELEMENTS (info_list);
}

GtkIMContext *
im_module_create (const gchar *context_id)
{
  if (strcmp (context_id, "imhiragana") == 0)
    return GTK_IM_CONTEXT (g_object_new (type_imhiragana, NULL));
  else
    return NULL;
}
