/*
 * WebAware (version 0.0.2) libpurple plugin.
 *
 * Copyright (C) 2007 Vishal Rao <vishal.rao@lahsiv.net>
 *
 * 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 of the License, 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.
 * http://www.gnu.org/copyleft/gpl.html
 */

/** 
 * This is a libpurple plugin which places your IM status on FTP or local directories.
 * It is useful for displaying your status on your website.
 */

/*
Changelog:

0.0.2 (Oct 9th, 2007) :
Now just listens to account-status-changed signals.

0.0.1 (Oct 9th, 2007) :
First cut based on helloworld.c hardcoded only for MSN, Yahoo and GoogleTalk.
Can only listen to signed-on and signed-off signals.
Does not store status anywhere in this version.
*/

/*
TODO :

1. Actually place status on multiple FTP and local dirs.
2. Handle all available protocols not just MSN, Yahoo and GoogleTalk.
3. Use Pref API to load/store config along with UI.
*/

#define PURPLE_PLUGINS

#include <glib.h>

#ifndef G_GNUC_NULL_TERMINATED
  #if __GNUC__ >= 4
    #define G_GNUC_NULL_TERMINATED __attribute__((__sentinel__))
  #else
    #define G_GNUC_NULL_TERMINATED
  #endif /* __GNUC__ >= 4 */
#endif /* G_GNUC_NULL_TERMINATED */

#include "plugin.h"
#include "version.h"
#include "request.h"
#include "notify.h"
#include "connection.h"
#include "signals.h"
#include "util.h"

PurplePlugin * g_plugin = NULL;

/*
 * Connection protocol_id list:
 * MSN is "prpl-msn"
 * Yahoo is "prpl-yahoo"
 * GTalk is "prpl-jabber"
 */

PurpleConnection * g_msn = NULL;
PurpleConnection * g_yahoo = NULL;
PurpleConnection * g_gtalk = NULL;

gulong g_statusid = 0;

char g_msnstatus[100] = {0};
char g_yahoostatus[100] = {0};
char g_gtalkstatus[100] = {0};

static void
check_connection(PurpleConnection * conn)
{
  const char * msn = NULL;
  const char * yahoo = NULL;
  const char * gtalk = NULL;

  if (!g_msn)
  {
    msn = purple_strcasestr(conn->account->protocol_id, "prpl-msn");

    if (msn)
    {
      g_msn = conn;
      return;
    }
  }

  if (!g_yahoo)
  {
    yahoo = purple_strcasestr(conn->account->protocol_id, "prpl-yahoo");

    if (yahoo)
    {
      g_yahoo = conn;
      return;
    }
  }

  if (!g_gtalk)
  {
    gtalk = purple_strcasestr(conn->account->protocol_id, "prpl-jabber");

    if (gtalk)
    {
      g_gtalk = conn;
      return;
    }
  }
}

static void
update_status(PurpleConnection * conn, char * gstatus)
{
  GList * statuses = NULL;
  GList * statusitem = NULL;
  PurpleStatus * status = NULL;
  PurpleStatusType * statustype = NULL;
  PurpleStatusPrimitive statusprimitive = PURPLE_STATUS_UNSET;
  
  g_strlcpy(gstatus, "Unknown", 99);
  
  statuses = purple_presence_get_statuses(conn->account->presence);
  
  statusitem = g_list_first(statuses);
  
  while (statusitem)
  {
    status = (PurpleStatus *) statusitem->data;
    
    if (purple_status_is_active(status))
    {
      statustype = purple_status_get_type(status);
      
      statusprimitive = purple_status_type_get_primitive(statustype);
      
      /*
      purple_notify_message(g_plugin, PURPLE_NOTIFY_MSG_INFO, conn->account->protocol_id,
        purple_primitive_get_name_from_type(statusprimitive), NULL, NULL, NULL);
      */
      g_strlcpy(gstatus, purple_primitive_get_name_from_type(statusprimitive), 99);
    }
    
    statusitem = g_list_next(statusitem);
  }  
}

static void
save_status(const char * gstatus)
{
  // TODO : Read prefs and save status to FTP and/or local dir.
  /*
  purple_notify_message(g_plugin, PURPLE_NOTIFY_MSG_INFO, "Save Status",
    gstatus, NULL, NULL, NULL);  
  */
}

static void
update_and_save_status(PurpleConnection * conn)
{
  const char * msn = NULL;
  const char * yahoo = NULL;
  const char * gtalk = NULL;

  msn = purple_strcasestr(conn->account->protocol_id, "prpl-msn");
  yahoo = purple_strcasestr(conn->account->protocol_id, "prpl-yahoo");
  gtalk = purple_strcasestr(conn->account->protocol_id, "prpl-jabber");

  if (msn)
  {
    update_status(g_msn, g_msnstatus);
    save_status(g_msnstatus);
  }
  else if (yahoo)
  {
    update_status(g_yahoo, g_yahoostatus);
    save_status(g_yahoostatus);
  }
  else if (gtalk)
  {
    update_status(g_gtalk, g_gtalkstatus);
    save_status(g_gtalkstatus);
  }
}

static void
account_status_changed(PurpleAccount *account, PurpleStatus *old, PurpleStatus *new, gpointer data)
{
  PurpleConnection * conn = NULL;
  /*
  purple_debug_misc("signals test", "account-status-changed (%s, %s, %s)\n",
          purple_account_get_username(account),
          purple_status_get_name(old),
          purple_status_get_name(new));
  */
  
  /*
  char msg[100] = {0};
  
  g_snprintf(msg, 99, "account: %s, old: %s, new: %s", purple_account_get_protocol_name(account),
    purple_status_get_name(old), purple_status_get_name(new));
  
  purple_notify_message(g_plugin, PURPLE_NOTIFY_MSG_INFO, "Account Status Changed",
    msg, NULL, NULL, NULL);  
  */
  
  conn = purple_account_get_connection(account);
  check_connection(conn);
  update_and_save_status(conn);  
}

static gboolean
plugin_load(PurplePlugin * plugin)
{
  /*
  purple_notify_message(plugin, PURPLE_NOTIFY_MSG_INFO, "WebAware Load",
    "plugin_load() called", NULL, NULL, NULL);
  */

  /*
  g_signonid = purple_signal_connect(purple_connections_get_handle(), "signed-on", g_plugin,
    PURPLE_CALLBACK(signed_on_cb), NULL);

  g_signoffid = purple_signal_connect(purple_connections_get_handle(), "signed-off", g_plugin,
    PURPLE_CALLBACK(signed_off_cb), NULL);
  */

  /*
  g_statusid = purple_signal_connect(purple_connections_get_handle(), "savedstatus-changed", g_plugin,
    PURPLE_CALLBACK(savedstatus_changed_cb), NULL);
  */

  g_statusid = purple_signal_connect(purple_accounts_get_handle(), "account-status-changed", g_plugin,
    PURPLE_CALLBACK(account_status_changed), NULL);

  return TRUE;
}

static gboolean
plugin_unload(PurplePlugin * plugin)
{
  /*
  purple_notify_message(plugin, PURPLE_NOTIFY_MSG_INFO, "WebAware UnLoad",
    "plugin_unload() called", NULL, NULL, NULL);
  */

  purple_signals_disconnect_by_handle(g_plugin);

  return TRUE;
}

static void
plugin_destroy(PurplePlugin * plugin)
{
  /*
  purple_notify_message(plugin, PURPLE_NOTIFY_MSG_INFO, "WebAware Destroy",
    "plugin_destroy() called", NULL, NULL, NULL);
  */

  purple_signals_uninit();
  purple_connections_uninit();
}

static PurplePluginInfo
info =
{
    PURPLE_PLUGIN_MAGIC,
    PURPLE_MAJOR_VERSION,
    PURPLE_MINOR_VERSION,
    PURPLE_PLUGIN_STANDARD,
    NULL,
    0,
    NULL,
    PURPLE_PRIORITY_DEFAULT,

    "core-vishalrao-webaware",
    "WebAware",
    "0.0.2",

    "Web Awareness Plugin",
    "The WebAware plugin places your status information on FTP or local directories."
    " It is useful for being able to display your status on your webpage.",
    "Vishal Rao <vishal.rao@lahsiv.net>",
    "http://lahsiv.net/",

    plugin_load,
    plugin_unload,
    plugin_destroy,

    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL 
};

static void
init_plugin(PurplePlugin * plugin)
{
  g_plugin = plugin;
  purple_signals_init();
  purple_connections_init();
  
  //Note: purple_accounts_init() seems to cause Pidgin to not sign on!
  //purple_accounts_init();
}

PURPLE_INIT_PLUGIN(webaware, init_plugin, info);

// --------- The End ---------
