#include "copyright.h"

/* Wizard-only commands */

#include "db.h"
#include "interface.h"
#include "match.h"
#include "externs.h"

void do_teleport(dbref player, const char *arg1, const char *arg2)
{
    dbref victim;
    dbref destination;
    const char *to;

    if(!Wizard(player)) {
	notify(player, "Only a Wizard may teleport at will.");
	return;
    }

    /* get victim, destination */
    if(*arg2 == '\0') {
	victim = player;
	to = arg1;
    } else {
	init_match(player, arg1, NOTYPE);
	match_neighbor();
	match_possession();
	match_me();
	match_absolute();
	match_player();

	if((victim = noisy_match_result()) == NOTHING) {
	    return;
	}
	to = arg2;
    }

    /* get destination */
    init_match(player, to, TYPE_PLAYER);
    match_neighbor();
    match_me();
    match_here();
    match_absolute();
    match_player();

    switch(destination = match_result()) {
      case NOTHING:
	notify(player, "Send it where?");
	break;
      case AMBIGUOUS:
	notify(player, "I don't know which destination you mean!");
	break;
      default:
	/* check victim, destination types, teleport if ok */
	if(Typeof(destination) == TYPE_EXIT
	   || Typeof(destination) == TYPE_THING
	   || Typeof(victim) == TYPE_EXIT
	   || Typeof(victim) == TYPE_ROOM
	   || (Typeof(victim) == TYPE_PLAYER
	       && Typeof(destination) != TYPE_ROOM)) {
	    notify(player, "Bad destination.");
	} else if(Typeof(victim) == TYPE_PLAYER) {
	    notify(victim, "You feel a wrenching sensation...");
	    enter_room(victim, destination);
	} else {
	    moveto(victim, destination);
	}
    }
}

void do_force(dbref player, const char *what, char *command)
{
    dbref victim;

    if(!Wizard(player)) {
	notify(player, "Only Wizards may use this command.");
	return;
    }

    /* get victim */
    if((victim = lookup_player(what)) == NOTHING) {
	notify(player, "That player does not exist.");
	return;
    }

    /* force victim to do command */
    process_command(victim, command);
}

void do_stats(dbref player, const char *name)
{
    dbref rooms;
    dbref exits;
    dbref things;
    dbref players;
    dbref unknowns;
    dbref total;
    dbref i;
    dbref owner;
    char buf[BUFFER_LEN];

    if(!Wizard(player)) {
	sprintf(buf, "The universe contains %d objects.", db_top);
	notify(player, buf);
    } else {
	owner = lookup_player(name);
	total = rooms = exits = things = players = unknowns = 0;
	for(i = 0; i < db_top; i++) {
	    if(owner == NOTHING || owner == db[i].owner) {
		total++;
		switch(Typeof(i)) {
		  case TYPE_ROOM:
		    rooms++;
		    break;
		  case TYPE_EXIT:
		    exits++;
		    break;
		  case TYPE_THING:
		    things++;
		    break;
		  case TYPE_PLAYER:
		    players++;
		    break;
		  default:
		    unknowns++;
		    break;
		}
	    }
	}
	sprintf(buf,
		"%d objects = %d rooms, %d exits, %d things, %d players, %d unknowns.",
		total, rooms, exits, things, players, unknowns);
	notify(player, buf);
    }
}
		
void do_toad(dbref player, const char *name)
{
    dbref victim;
    char buf[BUFFER_LEN];

    if(!Wizard(player)) {
	notify(player, "Only a Wizard can turn a person into a toad.");
	return;
    }

    init_match(player, name, TYPE_PLAYER);
    match_neighbor();
    match_absolute();
    match_player();
    if((victim = noisy_match_result()) == NOTHING) return;

    if(Typeof(victim) != TYPE_PLAYER) {
	notify(player, "You can only turn players into toads!");
    } else if(Wizard(victim)) {
	notify(player, "You can't turn a Wizard into a toad.");
    } else if(db[victim].contents != NOTHING) {
	notify(player, "What about what they are carrying?");
    } else {
	/* we're ok */
	/* do it */
	if(db[victim].password) {
	    free(db[victim].password);
	    db[victim].password = 0;
	}
	db[victim].flags = TYPE_THING;
	db[victim].owner = player; /* you get it */
	db[victim].pennies = 1;	/* don't let him keep his immense wealth */

	/* notify people */
	notify(victim, "You have been turned into a toad.");
	sprintf(buf, "You turned %s into a toad!", db[victim].name);
	notify(player, buf);

	/* reset name */
	sprintf(buf, "a slimy toad named %s", db[victim].name);
	free(db[victim].name);
	db[victim].name = alloc_string(buf);
    }
}