/*

  This module adds the command "invite", which when executed in pvt with the
bot, makes it invite you to a specified channel. Activate this with:

set invite_channel <#channel>

*/

#include "mbot.h"

#define LEVEL_INVITE_PVT 0

struct invite_type {
  CNetServer *s;
  CString name;
  invite_type (CNetServer *server) : s (server), name (CHANNEL_MAX) {}
};
CList *invite_list;

///////////////
// prototypes
///////////////

static void invite_cmd_invite (CNetServer *);

static invite_type *server2invite (CNetServer *);
static void invite_var (CNetServer *, const char *, char *, size_t);
static void invite_conf (CNetServer *, const char *);
static void invite_stop (CModule *);
static void invite_start (CModule *);

/////////////
// commands
/////////////

// invite
static void
invite_cmd_invite (CNetServer *s)
{
  invite_type *invite = server2invite (s);
  if (invite == NULL)
    return;
  // doesn't work inside #'s
  if (invite->name && CMD[3][6] == 0 && strcasecmp (CMD[2], s->nick) == 0)
    {
      int i = CHANNEL_INDEX (invite->name);	// if the bot is there..
      if (i != -1)
        CHANNELS[i]->irc_invite (s->script.source);	// ..invite
      return;
    }
}

////////////////////
// module managing
////////////////////

// returns the invite channel for a given server, NULL if nonexistant
static invite_type *
server2invite (CNetServer *s)
{
  invite_type *a;
  invite_list->rewind ();
  while ((a = (invite_type *)invite_list->next ()) != NULL)
    if (a->s == s)
      return a;
  return NULL;
}

static void
invite_var (CNetServer *s, const char *name, char *data, size_t n)
{
  invite_type *buf = server2invite (s);
  if (buf == NULL)
    return;
  if (strcasecmp (name, "invite_channel") == 0)
    {
      if (n != 0)
        my_strncpy (data, buf->name, n);
      else
        buf->name = data;
    }
}

// configuration file's local parser
static void
invite_conf (CNetServer *s, const char *bufread)
{
  char buf[2][MSG_SIZE+1];

  strsplit (bufread, buf, 1);

  if (strcasecmp (buf[0], "bot") == 0)
    {
      if (server2invite (s) == NULL)
        {
          invite_type *invite = new invite_type (s);
          if (invite == NULL)
            s->bot->conf_error ("error initializing invite");
          invite_list->add ((void *)invite);
          s->script.bind_cmd (invite_cmd_invite, LEVEL_INVITE_PVT, "invite");
          s->vars.var_add ("invite_channel", invite_var);
        }
      else
        s->bot->conf_error ("invite already defined in this server.");
    }
}

// module termination
static void
invite_stop (CModule *m)
{
  invite_type *invite;
  invite_list->rewind ();
  while ((invite = (invite_type *)invite_list->next ()) != NULL)
    {
      invite->s->vars.var_del ("invite_channel");
      invite->s->script.unbind_cmd ("invite");
      delete invite;
    }
  delete invite_list;
}

// module initialization
static void
invite_start (CModule *m)
{
  invite_list = new CList ();
}

struct CModule::module_type module = {
  MODULE_VERSION,
  "invite",
  invite_start,
  invite_stop,
  invite_conf,
  invite_var
};

