/
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/
/* /global/line_ed.c */
#include "ed.h"
/*
 * Expansion of the editor.  We will now allow the player to use any
 * or three different editors.  One of them is the default (the old
 * one) one of them is ed and the other I am going to write in a
 * few secs....
 *
 * cute line editor thing.  Which even a player could use!
 */

static string *lines, end_func;
static object end_object;
static int insertion_point;
string  editor;			/* The editor to use... */

void    main_bit( string str );
void    editor_do_quit( string str );

void    create()
{
    editor = "menu";
}				/* create() */

void    editor_commands()
{
    add_action( "set_editor", "editor" );
}				/* edito_commands() */

int     do_edit( string str, string end_f, object end_o )
{

    if( !end_f )
    {
	write( "Someone has stuffed up.\n" );
	return 0;
    }
    end_func = end_f;
    if( !end_o )
	end_object = previous_object();
    else
	end_object = end_o;
    if( !str )
	str = "";
    switch( editor )
    {
	case "menu":
	    lines = explode( str, "\n" ) - ({ 0 });
	    write( "Ok, enter your text.  ** on a line by itself to exit.\n" );
	    insertion_point = sizeof( lines );
	    printf( "%-2d] ", insertion_point + 1 );
	    input_to( "editor_loop" );
	    return 1;
	case "ed":
	    if( stringp( str ) && str != "" )
		write_file( TMP_FILE, str );
	    ed( TMP_FILE, "editor_finish_ed" );
	    return 1;
	case "command":
	    lines = explode( str, "\n" ) - ({ 0 });
	    write( "Ok, enter your text.  ** on a line by itself to quit.  ~h for help.\n" );
	    insertion_point = sizeof( lines );
	    printf( "%-2d] ", insertion_point + 1 );
	    input_to( "editor_loop" );
	    return 1;
    }
}				/* do_edit() */

void    main_bit( string str )
{
    int     i;
    string  s;

    if( str != "" )
    {
	while( str[ 0 ] == ' ' )
	    str = str[ 1..100 ];
	switch( str[ 0 ] )
	{
	    case 'i':
	    case 'I':
		write( "Insert before line : " );
		input_to( "editor_insert" );
		return;
	    case 'd':
	    case 'D':
		write( "Delete (line no, or n..m ie 1..2) : " );
		input_to( "editor_delete" );
		return;
	    case 'l':
	    case 'L':
		s = "";
		for( i = 0; i < sizeof( lines ); i++ )
		    s += sprintf( "%3d: %s\n", i + 1, lines[ i ] );
		this_player()->set_finish_func( "end_of_edit_more" );
		this_player()->more_string( s );
		return;
	    case 'm':
	    case 'M':
		write( "Modify which line (line no, or n..m ie 1..2) : " );
		input_to( "editor_modify" );
		return;
	    case 'c':
	    case 'C':
		write( sprintf( "Ok, back into insertion mode, ** on a line by " +
				"itself to exit.\n%-2d] ", insertion_point + 1 ) );
		insertion_point = sizeof( lines );
		input_to( "editor_loop" );
		return;
	    case 'e':
	    case 'E':
		write( "Entering ed....  Use 'q' to quit, 'x' to save and " +
		       "exit, 'Q' to quit without saveing changes and 'h' " +
		       "for help.\n" );
		write_file( TMP_FILE, implode( lines, "\n" ) );
		ed( TMP_FILE, "editor_exit_ed" );
		return;
	    case 's':
	    case 'S':
		write( "Quiting and saving.\n" );
		editor_do_quit( implode( lines, "\n" ) );
		return;
	    case 'q':
	    case 'Q':
		write( "Are you sure you want to quit (Y/N)? " );
		input_to( "editor_check_quit" );
		return;
	    case 'h':
	    case 'H':
		s = read_file( ED_HELP_FILE );
		this_player()->set_finish_func( "end_of_edit_more" );
		this_player()->more_string( s );
		return;
	    default:
		write( "I do not understand you.  Try " + (editor == "command" ?
							   "~h" : "h") + " for help.\n" );
		main_bit( "" );
		return;
	}
    }
    if( editor == "menu" )
    {
	write( sizeof( lines ) + " lines - Choose from IDLMCESQ H for help. " );
	input_to( "main_bit" );
    }
    else
    {
	printf( "%-2d] ", insertion_point + 1 );
	input_to( "editor_loop" );
    }
    return;
}				/* editor_loop() */


void    end_of_edit_more()
{
    this_player()->set_finish_func( 0 );
    main_bit( "" );
}				/* end_of_edit_more() */


void    editor_delete( string str )
{
    int     num1, num2, tmp;

    if( sscanf( str, "%d..%d", num1, num2 ) == 2 )
    {
	if( num1 > num2 )
	{
	    tmp = num1;
	    num1 = num2;
	    num2 = tmp;
	}
	if( num1 < 1 || num2 > sizeof( lines ) + 1 )
	{
	    write( "Out of bounds.\n" );
	    main_bit( "" );
	}
	write( "Deleteing from line " + num1 + " to line " + num2 + ".\n" );
	lines = delete( lines, num1 - 1, num2 - num1 + 1 );
	write( "Ok.\n" );
	main_bit( "" );
	return;
    }
    if( sscanf( str, "%d", num1 ) == 1 )
    {
	if( num1 < 1 || num1 > sizeof( lines ) )
	{
	    write( "Line number out of range.\n" );
	    main_bit( "" );
	    return;
	}
	write( "Deleteing line " + num1 + ".\n" );
	lines = delete( lines, num1 - 1, 1 );
	write( "Ok.\n" );
	main_bit( "" );
	return;
    }
    write( "Error, invalid data " + str + ".\n" );
    main_bit( "" );
    return;
}				/* editor_delete() */


void    editor_insert( string str )
{
    int     num;

    if( sscanf( str, "%d", num ) != 1 )
    {
	write( "ERROR! Must be a number.\n" );
	main_bit( "" );
	return;
    }
    if( num < 1 || num > sizeof( lines ) + 1 )
    {
	write( "Number out of bounds.\n" );
	main_bit( "" );
	return;
    }
    insertion_point = num - 1;
    write( "Inserting before line " + num + ".  Entering insertion mode, ** on a " +
	   "line by itself to exit\n] " );
    input_to( "editor_loop" );
    return;
}				/* editor_insert() */

void    editor_loop( string str )
{
    if( strlen( str ) > 1 && str[ 0 ] == '~' && editor == "command" )
    {
	main_bit( str[ 1..1000 ] );
	return;
    }
    if( str == "**" )
    {
	if( editor == "menu" )
	    main_bit( "" );
	else
	    if( sizeof( lines ) )
		editor_do_quit( implode( lines, "\n" ) );
	    else
		editor_do_quit( 0 );
	return;
    }
    lines = lines[ 0..insertion_point - 1 ] + ({ str }) +
	lines[ insertion_point..1000 ];
    insertion_point++;
    printf( "%-2d] ", insertion_point + 1 );
    input_to( "editor_loop" );
    return;
}				/* editor_loop() */

static int range1, range2;
static string modify_string;

void    editor_modify( string str )
{
    int     num1, num2, tmp;

    if( sscanf( str, "%d..%d", num1, num2 ) == 2 )
    {
	if( num1 > num2 )
	{
	    tmp = num1;
	    num1 = num2;
	    num2 = tmp;
	}
	if( num1 < 1 || num2 > sizeof( lines ) + 1 )
	{
	    write( "Out of bounds.\n" );
	    main_bit( "" );
	}
	write( "Modifying from line " + num1 + " to line " + num2 + ".\n" );
	write( "Text to change ? " );
	range1 = num1;
	range2 = num2;
	input_to( "editor_modify2" );
	return;
    }
    if( sscanf( str, "%d", num1 ) == 1 )
    {
	if( num1 < 1 || num1 > sizeof( lines ) )
	{
	    write( "Line number out of range.\n" );
	    main_bit( "" );
	    return;
	}
	write( "Modifying line " + num1 + ".\n" );
	write( "Text to change ? " );
	input_to( "editor_modify2" );
	range1 = range2 = num1;
	return;
    }
    write( "Error, invalid data " + str + ".\n" );
    main_bit( "" );
    return;
}				/* editor_modify() */

void    editor_modify2( string str )
{
    if( !str || str == "" )
    {
	write( "Aborting.\n" );
	main_bit( "" );
	return;
    }
    write( "Change to ? " );
    input_to( "editor_modify3" );
    modify_string = str;
    return;
}				/* editor_modify2() */


void    editor_modify3( string str )
{
    int     i;
    string  s1, s2, s3;

    write( "Changing all occurances of '" + modify_string + "' to '" + str + "' " +
	   "from " + range1 + " to " + range2 + ".\n" );
    for( i = range1 - 1; i < range2; i++ )
	if( sscanf( lines[ i ], "%s" + modify_string + "%s", s1, s2 ) == 2 )
	{
	    s1 += str;
	    while( sscanf( s2, "%s" + modify_string + "%s", s3, s2 ) == 2 )
		s1 += s3 + str;
	    lines[ i ] = s1 + s2;
	    write( sprintf( "%3d: %s\n", i + 1, lines[ i ] ) );
	}
    write( "Done.\n" );
    main_bit( "" );
    return;
}				/* editor_modify3() */


void    editor_exit_ed()
{
    string  str;

    str = read_file( TMP_FILE );
    if( !rm( TMP_FILE ) )
	log_file( LOG_FILE, "ed: couldn't rm " + TMP_FILE + "\n" );
    lines = explode( "#" + str, "\n" );
    lines[ 0 ] = lines[ 0 ][ 1..1000 ];
/*
   lines[ sizeof( lines ) - 1 ] = lines[ sizeof( lines ) - 1 ]
   [ 0..strlen( lines[ sizeof( lines ) - 1 ] ) - 2 ];
 */
    main_bit( "" );
    return;
}				/* editor_exit_ed() */

void    editor_finish_ed()
{
    string  str;

    str = read_file( TMP_FILE );
    if( !rm( TMP_FILE ) )
	log_file( LOG_FILE, "ed: couldn't rm " + TMP_FILE + "\n" );
    if( !str )
    {
	write( "Aborted.\n" );
	editor_do_quit( 0 );
	return;
    }
    lines = explode( str, "\n" );
    if( sizeof( lines ) )
	editor_do_quit( str );
    else
	editor_do_quit( 0 );
    return;
}				/* editor_finish_ed() */


void    editor_do_quit( string str )
{
    lines = ({ });
if(end_object && end_func)
    call_other( end_object, end_func, str );
    end_object = 0;
}				/* editor_do_quit() */


void    editor_check_quit( string str )
{
    if( str != "" && str[ 0 ] != 'y' && str[ 0 ] != 'Y' )
    {
	write( "Returing to the editor.\n" );
	main_bit( "" );
	return;
    }
    write( "Quiting.\n" );
    editor_do_quit( 0 );
    end_object = 0;
    return;
}				/* editor_check_quit() */


int     set_editor( string str )
{
    if( member_array( str, ({ "menu", "command", "ed" }) ) == -1 )
    {
	notify_fail( "Your editor can be set to one of the following menu, " +
		     "ed and command.  Please do not set your editor to ed " +
		     "unless you know what you are doing.  The menu editor " +
		     "is the default and the command editor is based on " +
		     "using ~ escape characters.\n" );
	return 0;
    }
    editor = str;

    write( "Editor set to " + str + ".\n" );
    return 1;
}				/* set_editor() */


string  append_signature()
{
    mapping sig;

    sig = (mapping)this_player()->query_aliases();
    if( sig[ ".signature" ] )
    {
	return "\n--\n" + replace( (string)"/secure/finger"->make_string( 
									     sig[ ".signature" ] ), ";", "\n" ) + "\n";
    }
    return "";
}				/* append_signature() */


void    editor_check_do_quit()
{
    if( end_object )
    {
	/* Force them to save the thingy they are editing. */
	write( "Saveing what you are editing.\n" );
	if( editor != "ed" )
	    editor_do_quit( implode( lines, "\n" ) );
	else
	    editor_finish_ed();
    }
}				/* editor_check_do_quit() */