#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
typedef struct _MyRecord {
  guint16 compose_keys[N_COMPOSE];
  guchar output_str[10];
} MyRecord;

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

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

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

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

  GDK_e,      0,	0,	"え",

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

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

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

  GDK_i,      0,	0,	"い",

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

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

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

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

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

  GDK_o,      0,	0,	"お",

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

  GDK_q,      0,	0,	"ｑ",

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

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

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

  GDK_u,      0,	0,	"う",

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

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

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

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

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

};

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,
				     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;
}
