#include <ctype.h>
#include <gtk/gtk.h>

#include "internal.h"
#include "plugin.h"
#include "account.h"
#include "conversation.h"
#include "prefs.h"
#include "gtkplugin.h"
#include "gtkprefs.h"
#include "gtkutils.h"
#include "version.h"

#define ESP_PREF(x) ("/plugins/gtk/X11/esperanto/" x)

static const char 
conversion_map[] =
"C\304\210"
"c\304\211"
"G\304\234"
"g\304\235"
"H\304\244"
"h\304\245"
"J\304\264"
"j\304\265"
"S\305\234"
"s\305\235"
"U\305\254"
"u\305\255";

static const char *
characters[] =
  {
    N_("' (apostrophe)"),   "'",
    N_("x (the letter x)"), "x",
    N_("^ (a caret)"),      "^",
    N_("h (the letter h)"), "h",
    NULL 
  };

static void
convert_esperanto_characters (char *msg,
			      char ch,
			      int postfix)
{
  const char *p;
  int cpos = postfix ? 1 : 0;
  ch = tolower (ch);

  for (; *msg; msg++)
    if (tolower (msg[cpos]) == ch)
      for (p = conversion_map; *p; p += 3)
	if (msg[1 - cpos] == *p)
	{
	  msg[0] = p[1];
	  msg[1] = p[2];
	  break;
	}
}

static void
convert_according_to_options (char *msg)
{
  const char *mark = 
    gaim_prefs_get_string (ESP_PREF ("mark"));
  int postfix = g_ascii_strcasecmp (gaim_prefs_get_string
				    (ESP_PREF ("position")),
				    "prefix");
  convert_esperanto_characters (msg,
				*mark < 1 ? '^' : *mark,
				postfix);
}

static gboolean 
writing_convert_callback (GaimAccount *account, const char *receiver,
			  char **message)
{
  if (gaim_prefs_get_bool (ESP_PREF ("outgoing")))
    convert_according_to_options (*message);

  return FALSE;
}

static gboolean
receiving_convert_callback (GaimAccount *account, char **sender,
			    char **message, GaimConversation *conv)
{
  if (gaim_prefs_get_bool (ESP_PREF ("incoming")))
  {
    convert_according_to_options (*sender);
    convert_according_to_options (*message);
  }

  return FALSE;
}

static gboolean
plugin_load (GaimPlugin *plugin)
{
  void *handle;

  handle = gaim_conversations_get_handle ();

  gaim_signal_connect (handle, "writing-im-msg",
		       plugin, GAIM_CALLBACK (writing_convert_callback), NULL);
  gaim_signal_connect (handle, "writing-chat-msg",
		       plugin, GAIM_CALLBACK (writing_convert_callback), NULL);
  gaim_signal_connect (handle, "receiving-im-msg",
		       plugin, GAIM_CALLBACK (receiving_convert_callback),
		       NULL);
  gaim_signal_connect (handle, "receiving-chat-msg",
		       plugin, GAIM_CALLBACK (receiving_convert_callback), 
		       NULL);
  
  return TRUE;
}

static GtkWidget *
get_config_frame (GaimPlugin *plugin)
{
  GList *marks = NULL;
  GtkWidget *box, *fbox;
  int i;

  box = gtk_vbox_new (FALSE, 18);
  gtk_container_set_border_width (GTK_CONTAINER (box), 12);

  fbox = gaim_gtk_make_frame (box, _("Input method"));

  gaim_gtk_prefs_dropdown (fbox, _("Type:"),
			   GAIM_PREF_STRING,
			   ESP_PREF ("position"),
			   _("Prefix"), "prefix",
			   _("Postfix"), "postfix",
			   NULL);

  for (i = 0; characters[i]; i++)
    marks = g_list_append (marks, (char *) characters[i]);
  gaim_gtk_prefs_dropdown_from_list (fbox, _("Hat character:"),
				     GAIM_PREF_STRING,
				     ESP_PREF ("mark"),
				     marks);
  g_list_free (marks);

  fbox = gaim_gtk_make_frame (box, _("Conversion"));

  gaim_gtk_prefs_checkbox (_("Convert outgoing messages"),
			   ESP_PREF ("outgoing"),
			   fbox);
  gaim_gtk_prefs_checkbox (_("Convert incoming messages"),
			   ESP_PREF ("incoming"),
			   fbox);

  gtk_widget_show_all (box);

  return box;
}

static GaimGtkPluginUiInfo ui_info =
  {
    get_config_frame
  };

static GaimPluginInfo info =
  {
    GAIM_PLUGIN_MAGIC, GAIM_MAJOR_VERSION, GAIM_MINOR_VERSION,
    GAIM_PLUGIN_STANDARD,                             /**< type           */
    GAIM_GTK_PLUGIN_TYPE,                             /**< ui_requirement */
    0,                                                /**< flags          */
    NULL,                                             /**< dependencies   */
    GAIM_PRIORITY_DEFAULT,                            /**< priority       */

    "core-turkey-esperanto",                          /**< id             */
    N_("Esperanto Plugin"),                           /**< name           */
    "0.2",                                            /**< version        */
    /**  summary        */
    N_("Makes it easy to write hats on Esperanto messages."),
    /**  description    */
    N_("Replaces any of the letters cghjsu with "
       "one of \304\211\304\235\304\245\304\265\305\235\305\255 "
       "in messages if it matches one of the standard ways of "
       "writing esperanto characters in ASCII."),
    "Neil Roberts <bpeeluk@yahoo.co.uk>",             /**< author         */
    N_("http://www.busydoingnothing.co.uk/plugin.html"), /**< homepage       */
    
    plugin_load,                                      /**< load           */
    NULL,                                             /**< unload         */
    NULL,                                             /**< destroy        */

    &ui_info,                                         /**< ui_info        */
    NULL                                              /**< extra_info     */
  };

static void
init_plugin(GaimPlugin *plugin)
{
  gaim_prefs_add_none ("/plugins/gtk");
  gaim_prefs_add_none ("/plugins/gtk/X11");
  gaim_prefs_add_none ("/plugins/gtk/X11/esperanto");

  gaim_prefs_add_string (ESP_PREF ("position"), "postfix");
  gaim_prefs_add_bool (ESP_PREF ("incoming"), TRUE);
  gaim_prefs_add_bool (ESP_PREF ("outgoing"), TRUE);
  gaim_prefs_add_string (ESP_PREF ("mark"), "x");
}

GAIM_INIT_PLUGIN(esperanto, init_plugin, info)
