#include "boot.clh"

object BUILDER
    parents	PLAYER;

    verb	"@addo*wner" : "on to onto" = addowner_cmd;
    verb	"@addo*wner" = addowner_cmd;
    verb	"@addp*arent" : "on to onto" = addparent_cmd;
    verb	"@addp*arent" = addparent_cmd;
    verb	"@clone" = clone_cmd;
    verb	"@clone" : "named" = clone_cmd;
    verb	"@create" = create_cmd;
    verb	"@destroy" = destroy_cmd;
    verb	"@dig" = dig_cmd;
    verb	"@find" = find_cmd;
    verb	"@link" = link_cmd;
    verb	"@link" : "to" = link_cmd;
    verb	"@list" : "on" = list_cmd;
    verb	"@list" = list_cmd;
    verb	"@open" = open_cmd;
    verb	"@open" : "to" = open_cmd;
    verb	"@methods" = methods_cmd;
    verb	"@mutate" : "to into" = mutate_cmd;
    verb	"@mutate" = mutate_cmd;
    verb	"@nick*name" : "is as to" = nickname_cmd;
    verb	"@nick*name" = nickname_cmd;
    verb	"@pub*lish" = publish_cmd;
    verb	"@unpub*lish" = unpublish_cmd;
    verb	"@rmp*arent" : "from on to onto" = rmparent_cmd;
    verb	"@rmp*arent" = rmparent_cmd;
    verb	"@rmo*wner" : "from on to onto" = rmowner_cmd;
    verb	"@rmo*wner" = rmowner_cmd;
    verb	"@show" = show_cmd;
    verb	"@spew" : "on" = spew_cmd;
    verb 	"@spew" = spew_cmd;
    verb	"@tel*eport" : "to" = teleport_cmd;
    verb	"@ve*rbs" = verbs_cmd;

    name = "Generic Builder";

    method init
	if (this == BUILDER)
	    this.add_owner(WIZARD);
	else
	    pass();
	endif
    endmethod /* init */

    method clone_cmd
	var	parent, new;

	if (caller != this)
	    return 1;
	elseif (!args[2] || (args[3] && !args[4]))
	    echo("Usage:  @clone <thing>");
	    echo("        @clone <thing> named <name>");
	    return 0;
	endif
	parent = this.match_env(args[2]);
	if (!parent)
	    echo("I don't see that here.");
	else
	    new = parent.clone(args[4]);	/* SSPOT */
	    if (!new)
		echo("You can't clone that.");
	    else
		echo("New \"" + parent.name + "\" cloned:  " + new.id);
	    endif
	endif
    endmethod /* clone_cmd */

    method mutate_cmd
	var	r, what, newparent;
	ignore	E_MAXREC, E_RANGE, E_INVIND, E_OBJNF, E_PERM;

	if (caller != this)
	    return 1;
	elseif (!args[2] || !args[3] || !args[4])
	    echo("Usage:  @mutate <thing> into <what>");
	    return 0;
	endif
	what = this.match_env(args[2]);
	newparent = this.match_env(args[4]);
	if (!what || !newparent)
	    echo("I don't see that here.");
	else
	    r = what.chparents({newparent});
	    if (typeof(r) == ERR && r != E_NONE)
		this.parent_result(r);
	    else
		echo("Mutated.");
	    endif
	endif
    endmethod

    method nickname_cmd
	var	what;
	if (caller != this)
	    return 1;
	elseif (!args[2] || !args[3] || !args[4])
	    echo("Usage:  @nickname <thing> is <nickname>");
	    return 0;
	endif
	what = this.match_env(args[2]);
	if (!what)
	    echo("I don't see that here.");
	else
	    setvar("nick_" + args[4], what);
	    echo("Nickname set.");
	endif
    endmethod

    method publish_cmd
	var	what;

	if (caller != this)
	    return 1;
	elseif (!args[2])
	    echo("Usage:  @publish <thing>");
	    return 0;
	endif
	what = this.match_env(args[2]);
	if (!what)
	    echo("I don't see that here.");
	elseif (what.publish())
	    echo("You can't publish that.");
	else
	    echo(what.id + " published.");
	endif
    endmethod

    method unpublish_cmd
	var	what;

	if (caller != this)
	    return 1;
	elseif (!args[2])
	    echo("Usage:  @unpublish <thing>");
	    return 0;
	endif
	what = this.match_env(args[2]);
	if (!what)
	    echo("I don't see that here.");
	elseif (what.unpublish())
	    echo("You can't publish that.");
	else
	    echo(what.id + " unpublished.");
	endif
    endmethod

    method addowner_cmd
	var	what, owner;
	ignore	E_PERM;

	if (caller != this)
	    return 1;
	elseif (!args[2] || !args[3] || !args[4])
	    echo("Usage:  @addowner <what> to <thing>");
	    return 0;
	endif
	owner = SYS_OBJ.find_player(args[2]);
	what = this.match_env(args[4]);
	if (!owner)
	    echo("\"" + args[2] + "\" is not the name of any player.");
	elseif (!what)
	    echo("I don't see that here.");
	elseif (what.add_owner(owner) == E_PERM)
	    echo("Permission denied.");
	else
	    echo("Owner added.");
	endif
    endmethod

    method rmowner_cmd
	var	what, owner;
	ignore	E_PERM;

	if (caller != this)
	    return 1;
	elseif (!args[2] || !args[3] || !args[4])
	    echo("Usage:  @rmowner <what> from <thing>");
	    return 0;
	endif
	owner = SYS_OBJ.find_player(args[2]);
	what = this.match_env(args[4]);
	if (!owner)
	    echo("\"" + args[2] + "\" is not the name of any player.");
	elseif (!what)
	    echo("I don't see that here.");
	elseif (what.rm_owner(owner) == E_PERM)
	    echo("Permission denied");
	else
	    echo("Owner removed.");
	endif
    endmethod

    method addparent_cmd
	var	r, what, parent;
	ignore	E_MAXREC, E_RANGE, E_INVIND, E_OBJNF, E_PERM;
	if (caller != this)
	    return 1;
	elseif (!args[2] || !args[3] || !args[4])
	    echo("Usage:  @addparent <what> to <thing>");
	    return 0;
	endif
	what = this.match_env(args[4]);
	parent = this.match_env(args[2]);
	if (!what || !parent)
	    echo("I don't see that here.");
	else
	    r = what.add_parent(parent);
	    if (typeof(r) == ERR && r != E_NONE)
		this.parent_result(r);
	    else
		echo("Parent added.");
	    endif
	endif
    endmethod

    method rmparent_cmd
	var	r, what, parent;
	ignore	E_MAXREC, E_RANGE, E_INVIND, E_OBJNF, E_PERM;
	if (caller != this)
	    return 1;
	elseif (!args[2] || !args[3] || !args[4])
	    echo("Usage:  @rmparent <what> from <thing>");
	    return 0;
	endif
	what = this.match_env(args[4]);
	parent = this.match_env(args[2]);
	if (!what || !parent)
	    echo("I don't see that here.");
	else
	    r = what.rm_parent(parent);
	    if (typeof(r) == ERR && r != E_NONE)
		this.parent_result(r);
	    else
		echo("Parent removed.");
	    endif
	endif
    endmethod

    method parent_result
	if (args[1] == E_OBJNF)
	    echo("Parent does not exist.");
	elseif (args[1] == E_INVIND)
	    echo("Parent must be local.");
	elseif (args[1] == E_PERM)
	    echo("Parent permission denied.");
	elseif (args[1] == E_RANGE)
	    echo("Object must have at least one parent.");
	elseif (args[1] == E_MAXREC)
	    echo("New parent would cause a loop.");
	else
	    echo("Parent invalid.");
	endif
    endmethod

    method create_cmd
	var	new;

	if (caller != this)
	    return 1;
	elseif (!args[2]) 
	    echo("Usage:  @create <name>");
	else
	    new = THING.clone(args[2]);
	    echo("Thing created:  " + new.id);
	endif
    endmethod /* create_cmd */

    method destroy_cmd
	var    what;

	if (caller != this)
	    return 1;
	endif
	what = this.match_env(args[2]);
	if (!what)
	    echo("What's a " + args[2] + "?");
	else
	    what.destroy();
	    echo("Destroyed.");
	endif
    endmethod /* destroy_cmd */

    method dig_cmd
	var	new;

	if (caller != this)
	    return 1;
	elseif (!args[2])
	    echo("Dig what?");
	    return 0;
	endif
	new = ROOM.clone(args[2]);
	echo("Room dug:  " + new.id);
    endmethod /* dig_cmd */

    method spew_cmd
	var	what;

	if (caller != this)
	    return 1;
	elseif (!args[2] || !args[4])
	    echo("Usage:  @spew <method> on <object>");
	else
	    what = this.match_env(args[4]);
	    if (!what)
		echo("I don't see that here.");
	    else
		echo(what.spew_method(args[2]));
	    endif
	endif
    endmethod /* dump_cmd */
	
    method link_cmd
	var	exit;

	if (caller != this)
	    return 1;
	elseif (!args[2])
	    echo("Link what?");
	elseif (!args[3])	/* no preposition */
	    echo("Usage:  @link <exit name> to <room #>");
	else
	    exit = location.match_exit(args[2]);
	    if (!exit)
		echo("I don't know what you want to link!");
	    else
		this.link(exit, args[4]);
	    endif
	endif
    endmethod /* link_cmd */

    method link
	var	new_dest;
	ignore	E_METHODNF;

	if (!PERMS_OK)
	    echo("Permission denied.");
	else
	    new_dest = this.match_env(args[2]);
	    if (!new_dest)
		echo("Link to where?");
	    elseif (!new_dest.link_ok)
		echo("You can't link to that!");
	    else
		args[1].set_dest(new_dest);
		echo("Linked.");
	    endif
	endif
    endmethod /* link */

    method find_cmd
	var	nm, thing;
	ignore	E_METHODNF;

	if (caller != this)
	    return 1;
	endif
	for thing in (creations)
	    if (args[2])
		nm = thing.name;
		if (lengthof(args[2]) > lengthof(nm))
		    if (args[2][1..lengthof(nm)] == nm)
			echo(thing.id);
		    endif
		elseif (nm[1..lengthof(args[2])] == args[2])
		    echo(thing.id);
		endif
	    else
		echo(thing.id);
	    endif
	endfor
	echo("---");
    endmethod /* find */

    method list_cmd
	var	what;

	if (caller != this)
	    return 1;
	elseif (!args[2] || !args[4])
	    echo("Usage:  @list <method> on <object>");
	else
	    what = this.match_env(args[4]);
	    if (!what)
		echo("I don't see that here.");
	    else
		echo(what.list_method(args[2]));
	    endif
	endif
    endmethod /* list_cmd */

    method open_cmd
	var	exit;

	if (caller != this)
	    return 1;
	elseif (!args[2])
	    player.tell("Open an exit in what direction?");
	else
	    if (!location.open_ok)
		echo("You can't open an exit here!");
	    else
		exit = EXIT.clone(args[2]);
		location.add_exit(exit);
		exit.set_source(location);
		echo("Exit " + exit.id + " opened.");
		if (args[3])	/* if there's a preposition ("to") */
		    this.link(exit, args[4]);
		endif
	    endif
	endif
    endmethod /* open */

    method methods_cmd
	var	what, m;

	if (caller != this)
	    return 1;
	elseif (!args[2])
	    echo("Usage:  @methods <object>");
	    return 0;
	endif
	what = this.match_env(args[2]);
	if (!what)
	    echo("I don't see that here.");
	else
	    for m in (what.methods)
		echo("  " + m);
	    endfor
	    echo("---");
	endif
    endmethod /* methods_cmd */

    method show_cmd
	var	r, what;
	ignore	E_SERVERDN, E_METHODNF, E_OBJNF;

	if (caller != this)
	    return 1;
	elseif (!args[2])
	    echo("Usage:  @show <object>");
	    return 0;
	endif
	what = this.match_env(args[2]);
	if (!what || what.name == E_OBJNF)
	    echo("I don't see that here.");
	else
	    r = what.show(args[1], args[2]);		/* SSPOT */
	    if (r == E_SERVERDN || r == E_METHODNF)
		echo("You can't show that.");
	    endif
	endif
    endmethod /* show_cmd */

    method verbs_cmd
	var	what, v;

	if (caller != this)
	    return 1;
	elseif(!args[2])
	    echo("Usage:  @verbs <object>");
	    return 0;
	endif
	what = this.match_env(args[2]);
	if (!what)
	    echo("I don't see that here.");
	else
	    for v in (what.verbs)
		if (v[2])
		    echo("  " + v[1] + " : " + v[2] + " = " + v[3]);
		else
		    echo("  " + v[1] + " = " + v[3]);
		endif
	    endfor
	    echo("---");
	endif
    endmethod /* verbs_cmd */

endobject /* BUILDER */