/
LIB3/
LIB3/D/ADMIN/
LIB3/D/ADMIN/OBJ/
LIB3/D/ADMIN/ROOM/W/
LIB3/D/HOME/
LIB3/D/HOME/CITY/ARENA/
LIB3/D/HOME/CITY/ITEMS/
LIB3/D/HOME/CITY/POSTOFFI/
LIB3/DOC/
LIB3/GLOBAL/SPECIAL/
LIB3/GLOBAL/VIRTUAL/
LIB3/NET/
LIB3/NET/CONFIG/
LIB3/NET/DAEMON/CHARS/
LIB3/NET/GOPHER/
LIB3/NET/INHERIT/
LIB3/NET/OBJ/
LIB3/NET/SAVE/
LIB3/NET/VIRTUAL/
LIB3/OBJ/B_DAY/
LIB3/OBJ/HANDLERS/TERM_TYP/
LIB3/PLAYERS/B/
LIB3/PLAYERS/N/
LIB3/ROOM/
LIB3/SAVE/
LIB3/SAVE/BOARDS/
LIB3/SAVE/ENVIRON/
LIB3/SAVE/POST/
LIB3/STD/COMMANDS/SHADOWS/
LIB3/STD/CREATOR/
LIB3/STD/DOM/
LIB3/STD/EFFECTS/
LIB3/STD/EFFECTS/HEALING/
LIB3/STD/EFFECTS/OTHER/
LIB3/STD/EFFECTS/POISONS/
LIB3/STD/ENVIRON/
LIB3/STD/GUILDS/
LIB3/STD/LIQUIDS/
LIB3/STD/ROOM/
LIB3/STD/TRIGGER/SHADOW/
LIB3/W/
LIB3/W/BANNOR/
LIB3/W/NEWSTYLE/
/*
 * We are sent the line of the menu...
 * From this, we are supposed to figure out whats actually here...
 */
#include "gopher.h"

#define VOID_OB "/room/void"

#undef DEBUG

#define TP(STR) tell_object(find_player("brandobas"), STR)

inherit "/std/room";

mixed  *my_menu, *junk, *my_junk;
string  room_long, rabbit;
int     search_room;
mapping blue, pending;

void    setup()
{
    blue = ([ ]);
    pending = ([ ]);
    my_menu = ({ });
    add_exit( "up", "who_cares", "corridor" );
    modify_exit( "up", ({ "function", "do_up" }) );
    add_exit( "out", "/w/common", "corridor" );
    modify_exit( "out", ({ "function", "do_out" }) );
    room_long = "";
}				/* create() */

void    init()
{
    if( rabbit )
	write( long( "", 0 ) );

    ::init();
    if( blue[ this_player() ] )
    {
	this_player()->more_string( blue[ this_player() ] );
	map_delete( blue, this_player() );
    }
/*
   for (i=0;i<sizeof(my_menu);i++)
   add_action("handle_item", (i+1)+"");
 */
    add_action( "do_refresh", "refresh" );
    add_action( "do_jump", "gopher" );
    add_action( "do_show", "show" );
}				/* init() */

long    ()
{
    object *obs;
    string *cont, str;
    int     i, cols;

    if( this_player() )
	cols = this_player()->query_cols();
    else
	cols = 78;
    return "You are in the gopher maze.\n" + sprintf( "%-*#s", cols, room_long ) +
	"\n'gopher <dest> [port]' to jump to another server, " +
	"and 'refresh'" +
	" to refresh the room.\n" + ::long();
}				/* query_long() */

void    setup_room( mixed *junk, string arg )
{
    set_short( junk[ TEXT ] );
    if( !arg )
	if( junk[ NAME ] == "1" )
	    GOPHER_CONTROL->add_connection( "\t" + junk[ MACHINE ] + "\t" +
					    junk[ PORT ], this_object() );
	else
	    GOPHER_CONTROL->add_connection( junk[ NAME ] + "\t" + junk[ MACHINE ] + "\t" +
					    junk[ PORT ], this_object() );
    if( arg || junk[ TEXT ] == "who" )
    {
	search_room = 1;
	set_heart_beat( 1 );
    }
    my_junk = junk;
    set_long( "Connecting.\n" );
    GOPHERD->do_connect( MENU, junk[ NAME ], junk[ MACHINE ], junk[ PORT ],
			 "finish_lookup", arg );
}				/* setup() */

mixed * query_my_junk()
{
    return my_junk;
}
mixed * query_my_menu()
{
    return my_menu;
}

void    finish_lookup( mixed *junk, mixed *called )
{
    int     i, my_number, exit_no;
    string  my_path, *bits, cont, ret;
    object *obs;

    if( !junk )
    {
	tell_room( this_object(), "Failed to connect.\n" );
	return 0;
    }
    bits = explode( file_name( this_object() ), "/" );
    cont = implode( bits[ 0..sizeof( bits ) - 2 ], "/" ) + "/gopher_cont";
    tell_room( this_object(), "Connection completed.\n" );
    ret = "";
    my_menu = junk;
    for( i = 0; i < sizeof( junk ); i++ )
    {
	reset_eval_cost();
	switch( junk[ i ][ TYPE ] )
	{
	    case FILE:
		ret += sprintf( "%2d: %s\n", i + 1, junk[ i ][ DATA ][ TEXT ] );
		break;
	    case MENU:
		ret += sprintf( "%2d: %s/\n", i + 1, junk[ i ][ DATA ][ TEXT ] );
		break;
	    case SEARCH:
		ret += sprintf( "%2d: %s <?>\n", i + 1, junk[ i ][ DATA ][ TEXT ] );
		break;
	}
	add_exit( (i + 1) + "", "hmmmm", "corridor" );
	modify_exit( (i + 1) + "", ({ "function", "handle_item", "obvious", 0 }) );
    }
    room_long = ret;
    set_long( "" );
    rabbit = 1;
    (obs = all_inventory())->move( VOID_OB );
    obs->move( this_object() );
    rabbit = 0;
}				/* finish_lookup() */

void    text_finish( string text, mixed *junk )
{
    string  tmp;
    int     i;
    object *obs;

    TP( sprintf( "%O\n", junk ) );
    tmp = junk[ 0 ] + "\t" + junk[ 1 ];
    if( !pending[ tmp ] )
    {
	tell_room( this_object(), "Something weird.\n" );
	return;
    }
    TP( sprintf( "BING?, %O", pending[ tmp ] ) );
    for( i = 0; i < sizeof( pending[ tmp ] ); i++ )
    {
	blue[ pending[ tmp ][ i ] ] = text;
	map_delete( pending, pending[ tmp ][ i ] );
    }
    map_delete( pending, tmp );
    TP( "Doing move...\n" );
    (obs = all_inventory())->move( VOID_OB );
    obs->move( this_object() );
}				/* text_finish() */

int     handle_item()
{
    int     num;
    object  dest;
    mixed * tmp;
    string  bip;

    sscanf( query_verb(), "%d", num );
    num--;
    if( pending[ this_player() ] )
    {
	notify_fail( "You have a pending transaction.\n" );
	return 0;
    }
    switch( my_menu[ num ][ TYPE ] )
    {
	case FILE:
	    pending[ this_player() ] = 1;
	    bip = my_menu[ num ][ DATA ][ NAME ] + "\t" + my_menu[ num ][ DATA ][ PORT ];
	    if( !pending[ bip ] )
	    {
		GOPHERD->do_connect( FILE, my_menu[ num ][ DATA ][ NAME ],
				     my_menu[ num ][ DATA ][ MACHINE ],
				     my_menu[ num ][ DATA ][ PORT ],
				     "text_finish" );
		pending[ bip ] = ({ this_player() });
	    }
	    else		/* Someone is already getting it. */
		pending[ bip ] += ({ this_player() });
/* We dont actually want to move them... */
	    notify_fail( "Connecting....\n" );
	    return 0;
	    break;
	case MENU:
	    if( my_menu[ num ][ DATA ][ NAME ] == "1" )
		my_menu[ num ][ DATA ][ NAME ] = "";
	    if( !(dest = GOPHER_CONTROL->query_connection( my_menu[ num ][ DATA ][ NAME ] +
							   "\t" + my_menu[ num ][ DATA ][ MACHINE ] + "\t" + my_menu[ num ][ DATA ][ PORT ] )) )
	    {
/* Need a new room... */
		dest = clone_object( GOPHER_ROOM );
		dest->setup_room( my_menu[ num ][ DATA ] );
	    }
	    modify_exit( query_verb(), ({ "dest", dest }) );
	    tmp = this_player()->query_property( "gopher" );
	    if( !tmp )
		tmp = ({ });
	    tmp = tmp - ({ 0 });
	    this_player()->add_property( "gopher", tmp + ({ this_object() }) );
	    break;
	case SEARCH:
/* Now a search requires a room, but an unregistered one. */
	    write( "You need to give the magic incantation to pass this exit.\n: " );
	    input_to( "do_gopher_search", 0, num );
	    notify_fail( "" );
	    return 0;
    }
    return 1;
}				/* handle_item() */

void    do_gopher_search( string str, int num )
{
    object  dest;
    mixed * tmp;

    printf( "In here.\n" );
    dest = clone_object( GOPHER_ROOM );
    dest->setup_room( my_menu[ num ][ DATA ], str );
    tmp = this_player()->query_property( "gopher" );
    if( !tmp )
	tmp = ({ });
    tmp = tmp - ({ 0 });
    this_player()->add_property( "gopher", tmp + ({ this_object() }) );
    modify_exit( (num + 1) + "", ({ "dest", dest }) );
    this_player()->move_player( "X", dest );
}				/* do_search() */

int     do_refresh( string str )
{
    if( search_room && !str )
    {
	notify_fail( "Syntax: refresh <text>\n" );
	return 0;
    }
    if( search_room )
	setup_room( my_junk, str );
    else
	setup_room( my_junk, 0 );
    write( "Refreshing...\n" );
    return 1;
}				/* do_refresh() */

int     do_up()
{
    object  dest, *tmp;
    int     i;

    if( !(tmp = this_player()->query_property( "gopher" )) )
    {
	this_player()->remove_property( "gopher" );
	call_out( "do_exit_command", 0, "out" );
	notify_fail( "" );
	return 0;
    }
    else
    {
	tmp = tmp - ({ 0 });
	for( i = sizeof( tmp ) - 1; i >= 0; i-- )
	    if( tmp[ i ] )
		break;
	if( i < 0 )
	{
	    this_player()->remove_property( "gopher" );
	    call_out( "do_exit_command", 0, "out" );
	    notify_fail( "" );
	    return 0;
	}
	else
	{
	    if( i )
		this_player()->add_property( "gopher", tmp[ 0..i - 1 ] );
	    else
		this_player()->add_property( "gopher", 0 );
	    dest = tmp[ i ];
	}
    }
    modify_exit( "up", ({ "dest", dest }) );
    return 1;
}				/* do_up() */

void    heart_beat()
{
    if( !sizeof( all_inventory() ) )
	dest_me();
}				/* heart_beat() */

int     do_jump( string str )
{
    string  host;
    int     port;
    object  dest;
    mixed * tmp;

    if( !str )
    {
	notify_fail( "Syntax: " + query_verb() + " <site> [port]\n" );
	return 0;
    }
    if( sscanf( str, "%s %d", host, port ) != 2 )
    {
	host = str;
	port = "70";
    }
    dest = GOPHER_CONTROL->query_connection( "\t" + host + "\t" + port );
    if( !dest )
    {
	dest = clone_object( GOPHER_ROOM );
	dest->setup_room( ({ "Root level of " + host, "", host, port + "" }) );
    }
    tmp = this_player()->query_property( "gopher" );
    if( !tmp )
	tmp = ({ });
    this_player()->add_property( "gopher", tmp + ({ this_object() }) );
    this_player()->move_player( "X", dest );
    return 1;
}				/* do_jump() */

/* Get me out of here! */
int     do_out()
{
    this_player()->remove_property( "gopher" );
    return 1;
}				/* do_out() */

int     do_show( string str )
{
    int     num;

    notify_fail( "Syntax: show <num>\n" );
    if( !str )
	return 0;
    if( sscanf( str, "%d", num ) != 1 || num < 1 || num > sizeof( my_menu ) )
	return 0;
    num--;
    write( "Text: " + my_menu[ num ][ DATA ][ TEXT ] + "\n" );
    write( "Name: " + my_menu[ num ][ DATA ][ NAME ] + "\n" );
    write( "Host: " + my_menu[ num ][ DATA ][ MACHINE ] + "\n" );
    write( "Port: " + my_menu[ num ][ DATA ][ PORT ] + "\n" );
    return 1;
}				/* do_who() */