/*
 * addchan.c
 * (C) Christian Magnusson 2000, Email: d1mag@dtek.chalmers.se
 * This program is copyright, and covered by the Gnu Public License.
 * The Q bot.
 */

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "settings.h"
#include "bottypes.h"
#include "globals.h"
#include "dl.h"

void m_addchan(char *a);

MODULE_PUBLIC int _init_addchan(void *a, void *b)
{
  dl_command_entry_t *dl = a;
  if(!a) return 0;

  snprintf(dl->help, MAX_COMMAND_HELP_LEN,
	   "/msg %s ADDCHAN <channel> <flags> <owners nick> <channeltype>\nAdd a new channel to the channel-bot. The flags refers to the flags that you set with CHANFLAGS - i.e. Bitch mode (+b) etc. The owner's nick is included to set the founder of the channel.\nSee HELP CHANFLAGS for help on the flags parameter.\n"
	   , BOT_NAME);
  snprintf(dl->summary, MAX_COMMAND_SUMMARY_LEN,
	   "Adds the bot to a new channel");
  dl->level = 900;
#if 0
  dl->func = m_addchan;
#else
  dl->func = (void (*)(char*)) DL_sym(dl->val, "m_addchan");
#endif
  return 1;
}

MODULE_PUBLIC int _remove_addchan(char *a, char *b)
{
  remove_command("addchan");
  return 1;
}

MODULE_PUBLIC void m_addchan(char *a)
{
  int i;
  char channel[CHANNELLEN+1];
  char ownnick[NICKLEN+2];
  char chantypestr[CHANTYPELEN+1];
  char tflags[64+1];
  struct dbaseuser *owner;
  struct chanopts *c;
  struct chanpriv *p;
  unsigned int flags;
  char tmp[BIGBUF+1];
  struct chantype *ct;
  int chantypeid;
  int len;
  ListElem *el;

  struct dbaseuser *db;
  db = sender_au->dbuser;
  if(db) {
    log("From: %s addchan [%s]\n", db->nick, a);
  } else
    return;
  if(!is_oper()) {
    say_sender("You are not an Oper.");
    log("To: %s Is not an Oper\n", db->nick);
    return;
  }

  i=0;
  strncpy(channel,getword(a,&i),CHANNELLEN);
  channel[CHANNELLEN] = '\0';
  if(!strlen(channel)) {
    say_sender("You forgot to type a channel name.");
    say_sender_("/msg %s ADDCHAN <channel> <flags> <nickname> <channeltype>", BOT_NAME);
    say_sender_("/msg %s ADDCHAN <channel> <flags> <#nickname> <channeltype>", BOT_NAME);
    return;
  }
  if (channel[0]!='#') {
    say_sender("Channel MUST start with a '#'");
    return;
  }
  flags=0;
  strncpy(tflags,getword(a,&i),64);
  tflags[64] = '\0';
  if(!strlen(tflags)) {
    say_sender("You forgot to type the channel flags.");
    say_sender_("/msg %s ADDCHAN <channel> <flags> <nickname> <channeltype>", BOT_NAME);
    say_sender_("/msg %s ADDCHAN <channel> <flags> <#nickname> <channeltype>", BOT_NAME);
    return;
  }
  updatemodes(&flags,tflags);
  if((flags & CO_MUST_BE_WRONG)) {
    say_sender("The flags parameter really does refer to flags, NOT the default channel modes! Try HELP CHANFLAGS.");
    return;
  }
#ifdef FORCE_AUTOJOIN
  flags |= CO_AUTO_JOIN;
#endif

  strncpy(ownnick,getword(a,&i),NICKLEN+1);
  ownnick[NICKLEN+1] = '\0';

  if (ownnick[0]!='#') {
    owner = finduserfromnick(ownnick);
    if (owner == NULL) {
      say_sender("Can't find that nick logged on.");
      return;
    }
  } else {
    owner = finduserfromname(ownnick+1);
    if(!owner) {
      say_sender("Can't find that nick in the database.");
      return;
    }
  }

  strncpy(chantypestr, getword(a,&i), CHANTYPELEN);
  chantypestr[CHANTYPELEN] = '\0';
  if(!strlen(chantypestr)) {
    int nrtype = 0;
    len = 0;
    chantypeid = 0;
    tmp[0] = '\0';
    el = GetHead(chantype_list);
    while(el) {
      ct = (struct chantype *)el->data;
      len += sprintf(&tmp[len], "%s ", ct->name);
      nrtype++;
      chantypeid = ct->id;
      el = GetSucc(el);
    }
    if(len > 0) {
      if(nrtype == 1) {
	say_sender("Warning: New parameter is added to ADDCHAN !  For some reason there are only 1 (one) channel-type defined. Will add channel with that type.");
	say_sender_("Channel-type will set to [%s]", tmp);
      } else {
	say_sender("Warning: New parameter is added to ADDCHAN !  A channel-type must be set for the new channel.");
	say_sender("Channel-type could be one of the following:");
	say_sender(tmp);
	say_sender_("Try: /MSG %s %s clan", BOT_NAME, a);
	return;
      }
    } else {
      if(nrtype == 0) {
	say_sender("Warning: New parameter is added to ADDCHAN !  For some reason there are no channel-types defined yet. Will add channel without any type instead.");
	chantypeid = 0;  /* isn't needed */
      }
    }
  } else {
    chantypeid = 0;
    el = GetHead(chantype_list);
    while(el) {
      ct = (struct chantype *)el->data;
      if(!strcasecmp(ct->name, chantypestr)) {
	chantypeid = ct->id;
	break;
      }
      el = GetSucc(el);
    }
    if(!el) {
      say_sender_("Couldn't find any channel-type called [%s]", chantypestr);
      return;
    }
  }

  c = findchannel(channel);
  if(c) {
    say_sender("That channel already exists.");
    return;
  }
  c = addchannel(channel,flags,0,owner->userid,channel);

  /* set which operator added the channel */
  c->created_by = sender_au->userid;
  c->type = chantypeid;

  if(userlevelonchan_d(owner, channel) == 0) { 
    p = (struct chanpriv *)Malloc(sizeof(struct chanpriv));
    strncpy(p->channel,channel,CHANNELLEN);
    p->channel[CHANNELLEN] = '\0';
    p->chanlevel=CHAN_MASTER+CHAN_OWNER+CHAN_VOICE+CHAN_OPER+CHAN_AUTOOP;
    p->next=owner->privs;
    owner->privs=p;
  } else {
    p = owner->privs;
    while(p) {
      if(!strcasecmp(channel,p->channel)) break;
      p = p->next;
    }
    if(p) {
      p->chanlevel=CHAN_OWNER+CHAN_MASTER+CHAN_OPER+CHAN_VOICE+CHAN_AUTOOP;
    }
  }
  say_sender("Join channel.");
  joinchannel(c);
  say_sender("Done.");
  return;
}
