/*
 * c_handlers.c
 * (C) Peter Salanki 2002
 * This program is copyright, and covered by the Gnu Public License.
 * The Natasha bot.
 * sorcer@linux.se
 */

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <time.h>
#include <dlfcn.h>
#include <pthread.h>

#include "globals.h"
#include "bottypes.h"

/* Channel levels:
   1: Channel friend
   2: Channel voice
   3: Channel op
   4: Channel master
   5. Channel owner
*/

void setrightmode(char *channel, char *nick)
{
  int chanlev = 0;
  struct activeuser *u;
  struct channel *c;
  struct activechanuser *acu;

  c = findchannel(channel);
  acu = findachanuser(nick, channel);
 
  if(acu == NULL && strcasecmp(channel, HOMECHAN) != 0) return; // User is not on chan, so why bother?

  if(c != NULL && c->isop == 1 && c->arm->id != 1) {
    chanlev = chanuserlevel(nick, channel);
    if (c->autovoice == 1 && chanlev == CHAN_VOICE && acu->voice == 0) voice(channel, nick);
    else if (c->autoop == 1 && chanlev >= CHAN_OP && acu->op == 0) op(channel, nick);
    return;
  }

  if(c == NULL || c->arm->id == 1) {
    u = findauser(nick);
    if (u->auth >= TECHNICIAN && u->auth < BOT_NORMAL && u->auth != IRC_OPERATOR) op(channel, nick);
    else if (u->auth ==  QUEUE_WORKER|| u->auth == HELPER || u->auth == SERVICE_FRIEND) voice(channel, nick);
  }
}

int c_join (char *channame, struct arm *a) {
  char query[MAX_QUERY];
  char *eschanname;

  if(a->channels+1 == MAXCHANS) return 0;
  
  if((strstr(channame, "'") != NULL) || (strstr(channame, "\\") != NULL) || (strstr(channame, ",") != NULL) || strcasecmp(channame, HOMECHAN) == 0) return 0;

  if (findchannel(channame) == NULL) {
    eschanname = escapequery(channame);
    sprintf(query, "SELECT `id`  FROM `channels` WHERE `name` = '%s'", eschanname);
    free(eschanname);

    dbquery(query);
    if((row = mysql_fetch_row(res))) return 0;
    EndDbQuery();

    adddbchannel(channame, a); // We add the channel to the database
    loadchannel(channame); // Load that channel
    joinchannel(findchannel(channame)); // Now we join the channel
    
    return 1;
  } else return 0; // We are already on that channel, stupid
}

int c_part (char *channame, char *reason) {
  struct channel *c;

  c = findchannel(channame);

  if (c != NULL) {

    partchannel(c, reason); // Now we part the channel
    delallachanusers(c); // We delete all active channel users in memory
    deldbchannel(channame); // We remove the channel to the database
    delchannel(c); // Delete the channel from memory
    
    return 1;
  } else return 0; // We are not on that channel, stupid
}

int c_move (char *from, char *to) {
  struct channel *c;
  char reason[512];
  char query[MAX_QUERY];

  c = findchannel(from);

  if (c != NULL) {
    if(findchannel(to) != NULL || strcasecmp(to, HOMECHAN) == 0) return 2;

    sprintf(query, "UPDATE `channels` SET `name` = '%s' WHERE id = '%i'", to, c->id);
    dbquery(query); // Update database
    EndDbQuery();

    snprintf(reason, 512, "Moving to: %s", to);
    delallachanusers(c); // We delete all active channel users in memory
    partchannel(c, reason); // Now we part the channel

    strncpy(c->name, to, CHANNELLEN); // Update memory

    joinchannel(c); // Join the new channel

    return 1;
  } else return 0; // We are not on that channel, stupid
}

void c_setlev (int uid, char *channame, int level) {
  char query[MAX_QUERY];
  struct channel *c;
  struct chanuser *cu;

  c = findchannel(channame);
  if(c == NULL) return;

  cu = findchanuser(uid, c->id);

  if (cu == NULL) {
    /* Oki, the user is not in memory (and the hopefully not in database). What do ve do now? */
    sprintf(query, "INSERT INTO `chanusers` (`cid`, `uid`, `level`, `sid`) VALUES ('%d', '%d', '%d', '%s')", c->id, uid, level, SID);

    dbquery(query);
    EndDbQuery();

    addchanuser(c, uid, level, "");
  } else {
    sprintf(query, "UPDATE `chanusers` SET `level` = '%d' WHERE uid = '%d' AND cid = '%d'", level, uid, c->id);
 
    dbquery(query);
    EndDbQuery();

    cu->level = level;
  }
}

void c_setgreet (int uid, char *channame, char *greet) {
  char query[MAX_QUERY];
  struct channel *c;
  struct chanuser *cu;
  char *esgreet;

  c = findchannel(channame);
  cu = findchanuser(uid, c->id);

  if (cu != NULL) {
    esgreet = escapequery(greet);
    snprintf(query, MAX_QUERY, "UPDATE `chanusers` SET `greet` = '%s' WHERE uid = '%d' AND cid = '%i'", esgreet, uid, c->id);
    free(esgreet);

    dbquery(query);
    EndDbQuery();

    strncpy(cu->greet, greet, 100);
  }
}
