#include "boot.clh"

object SYS_OBJ
    parents	ROOT_OBJ;

    name = "The System Object";

    list	players = { WIZARD } , connected_players;
    list	connected_servers;
    list	wizards = { WIZARD };
    list	visitors;	/* remote objects contained in local objects */
    obj		player_class;
    num		dbtop;

    method init
	if (caller != SYS_OBJ)
	    raise(E_PERM);
	else
	    this.add_owner(WIZARD);
	endif
    endmethod /* init */

    method boot_server
	if (caller != SYS_OBJ)
	    raise(E_PERM);
	endif
	connected_players = {};
	connected_servers = { SYS_OBJ };
	player_class = PROGRAMMER;
    endmethod /* boot_server */

    method resynch
	var	item, dummy;

	if (caller != SYS_OBJ)
	    raise(E_PERM);
	endif
	for item in (visitors)
	  /* if visiting object is no longer in a local object, */
	    if (serverof(item[1].location))
		dummy = item[2].remove(item[1]);	      /* remove it */
		visitors = visitors - item;
	    endif
	endfor
    endmethod /* resynch */

    method add_wizard
	if (!(caller in wizards))
	    player.tell("Permission denied.");
	else
	    wizards = wizards + args[1];
	    player.tell("Wizard added.");
	endif
    endmethod /* add_wizard */

    method rm_wizard
	if (!(caller in wizards))
	    player.tell("Permission denied.");
	else
	    wizards = wizards - args[1];
	    player.tell("Wizard removed.");
	endif
    endmethod /* rm_wizard */

    method wizards
	return wizards;
    endmethod /* wizards */

    method convtime
	var	r, time, howmany;

	if (lengthof(args) != 1)
	    raise(E_RANGE);
	elseif (typeof(args[1]) != NUM)
	    raise(E_TYPE);
	else
	    time = args[1];
	    if (time > (24 * 60 * 60))
		r = " day";
		howmany = time / (24 * 60 * 60);
	    elseif (time > (60 * 60))
		r = " hour";
		howmany = time / (60 * 60);
	    elseif (time > 60)
		r = " minute";
		howmany = time / 60;
	    else
		r = " second";
		howmany = time;
	    endif
	    if(howmany != 1)
		r = r + "s";
	    endif
	    return tostr(howmany) + r;
	endif
    endmethod
	    
    method who
	var	dude;
/*
 * show connected players
 */
	if (args)
	    player.tell(args[1]);
	endif
	player.tell("Player Name       On For      Idle");
	for dude in (connected_players)
	    player.tell(pad(dude.name, 17) + " "
		+ pad(this.convtime(time() - dude.connected_at), 11) + " "
		+ pad(this.convtime(time() - dude.last_cmd_at), 11));
	endfor
    endmethod /* who */

    method add_visitor
	visitors = visitors + {args[1], args[2]};
    endmethod /* add_visitor */

    method rm_visitor
	visitors = visitors + {args[1], args[2]};
    endmethod /* rm_visitor */

    method visitors
	return visitors;
    endmethod /* visitors */

    method connect_player
	if (caller != SYS_OBJ)
	    raise E_PERM;
	else
	    connected_players = connected_players + args[1];
	    args[1].connect();
	endif
    endmethod /* connect_player */

    method create_player
	ignore E_METHODNF;

	if (caller != SYS_OBJ)
	    raise E_PERM;
	else
	    connected_players = connected_players + args[1];
	    players = players + args[1];
	    args[1].connect();
	endif
    endmethod /* create_player */

    method disconnect_player
	if (caller != SYS_OBJ)
	    raise E_PERM;
	else
	    connected_players = connected_players - args[1];
	    args[1].disconnect();
	endif
    endmethod /* disconnect_player */

    method rm_player
	if ((caller in wizards) || caller == args[1])
	    players = players - args[1];
	else
	    raise E_PERM;
	endif
    endmethod /* rm_player */

    method players
	return players;
    endmethod /* players */

    method connected_players
	return connected_players;
    endmethod /* connected_players */

    method find_player
	var	dude;

	for dude in (players)
	    if (dude.name == args[1])
		return dude;
	    endif
	endfor
	return NOTHING;
    endmethod /* find_player */

    method find_connected_player
	var	dude;

	for dude in (connected_players)
	    if (dude.name == args[1])
		return dude;
	    endif
	endfor
	return NOTHING;
    endmethod /* find_connected_player */

    method connect_server
	connected_servers = connected_servers + args[1];
	SYS_OBJ.resynch();
    endmethod /* connect_server */

    method disconnect_server
	connected_servers = connected_servers - args[1];
    endmethod /* disconnect_server */

endobject /* SYS_OBJ */