/*
** j###t ########## #### ####
** j###t ########## #### ####
** j###T "###L J###"
** ######P' ########## #########
** ######k, ########## T######T
** ####~###L ####
** #### q###L ########## .#####
** #### \###L ########## #####"
**
** $Id$
**
** Class History
**
** Date Name Description
** ---------|------------|-----------------------------------------------
** 01Jun96 adamb added all the commands in.
** the loop for some of them isn't
** available yet, but will be.
**
** 02Jun96 paulm fixed a bug which meant blank
** lines were added to the end of
** the buffer during the edit
**
** 03Jun96 adamb merged Paul's update with the
** editor.
**
** 05Jun96 adamb fixed the stringBuffer to StringTokenizer
** code so that blank lines are niether
** added nor deleted.
**
** 05Jun96 adamb added the looping for some commands and
** also the elimination of the .g command.
** ie: .5 to goto line #5.
** Added .s(tats) command.
*/
package key;
import key.util.LinkedList;
import java.util.*;
import java.lang.*;
/**
* Kind of hacked to edit paragraphs - doesn't do them
* properly, but then, what does?
*/
public class Editor
{
public static final MultiParagraph intro;
static
{
MultiParagraph.Generator i = new MultiParagraph.Generator();
i.append( LineParagraph.LINE );
i.append( new TextParagraph( TextParagraph.LEFT, "Entering the forest editor <footnote 10>:", 0, 0, 0, 0 ) );
i.append( new TextParagraph( TextParagraph.LEFT, "If you're not sure how to use the editor, enter '.quit' immediately (without the quotes), and read 'help editor'", 2, 0, 0, 0 ) );
i.append( BlankLineParagraph.BLANKLINE );
intro = i.getParagraph();
}
static public Paragraph edit( Player p, Paragraph buffer, InteractiveConnection ic, int maxLines, int maxBytes )
{
String startBuffer;
int alignment = TextParagraph.LEFT;
LinkedList lines = new LinkedList();
int currentBytes=0;
if( buffer instanceof TextParagraph )
startBuffer = ((TextParagraph)buffer).getText();
else
{
//ic.sendError( "This editor can only edit single text paragraphs at the moment - previous data cleared" );
//startBuffer = "";
ic.sendError( "This editor can only edit single text paragraphs." );
return( buffer );
}
//
// The StringTokenizer when delim return is set to true, returns in 1
// entry the line and the next contains the delim.
// If the line is (null) then the line is NOT returned, only the delim.
// Therefore, if you use the line, you then have to remove the delim.
// so if you get a delim, it isn't treated as a delim, it's treated as
// a blank line.
//
StringTokenizer st = new StringTokenizer( startBuffer, "\n", true );
if( !st.hasMoreTokens() )
lines.append( "" );
while( st.hasMoreTokens() )
{
String strToken=st.nextToken();
if(!strToken.startsWith("\n"))
{
lines.append(strToken);
if(st.hasMoreTokens())
{
strToken=st.nextToken();
}
}
else
{
lines.append(""); // a CR in the text means a blank line
}
}
ic.send( intro, false );
ic.sendFeedback( "Limitations: " + maxLines + " lines, " + maxBytes + " characters." );
ic.sendLine();
String entered=null;
LinkedList.Iterator cline=lines.iterator();
cline.last();
// if there isn't a CR at the end, place one there.
if(!((String)cline.element()).equals(""))
{
cline.insertAfter("");
cline.last();
}
display( ic, lines, alignment );
ic.sendLine();
currentBytes = countBytes( lines );
while( true )
{
try
{
entered = ic.input( "+ " );
}
catch( NetworkException e )
{
System.out.println( "disconnect from editor" );
return( buffer );
}
if( entered.startsWith( "." ) )
{
//
// first all the singlar commands not affected by numerical repeating
//
if(entered.equals(".quit"))
{
//
// Quit - Abort and Exit
//
ic.sendFeedback( "Aborting edit..." );
return( buffer );
}
else if( entered.equals( ".end" ) )
{
//
// End - Save and Exit
//
ic.sendFeedback("Saving editor buffer...");
StringBuffer r = new StringBuffer( "" );
for( Enumeration e = lines.elements(); e.hasMoreElements(); )
{
r.append( (String) e.nextElement() );
if( e.hasMoreElements() )
r.append( '\n' );
}
return( new TextParagraph( alignment, r.toString() ) );
}
else if( entered.equalsIgnoreCase( ".centrealign" ) || entered.equalsIgnoreCase( ".centeralign" ) )
{
alignment = TextParagraph.CENTERALIGNED;
ic.sendFeedback( "This paragraph will now be centre aligned" );
}
else if( entered.equalsIgnoreCase( ".leftalign" ) )
{
alignment = TextParagraph.LEFT;
ic.sendFeedback( "This paragraph will now be left aligned" );
}
else if(entered.startsWith(".l"))
{
//
// Look - view the current line
//
ic.sendRaw((String)cline.element());
}
else if( entered.startsWith( ".v" ) )
{
//
// View - view the entire buffer
//
display( ic, lines, alignment );
}
else if(entered.startsWith(".w"))
{
//
// Wipe - Erase the entire buffer
//
cline.first();
lines.clear();
cline.first();
lines.append( "" );
cline.last();
alignment = TextParagraph.LEFT;
ic.sendFeedback( "Editing Buffer Cleared." );
currentBytes = 0;
}
else if(entered.startsWith(".t"))
{
//
// Top - Go to the top of the buffer
//
cline.first();
ic.sendFeedback( "At Top of Buffer." );
}
else if(entered.startsWith(".b"))
{
//
// Bottom - Go to the end of the buffer
//
cline.last();
ic.sendFeedback( "At Bottom of Buffer." );
}
else if(entered.startsWith(".s"))
{
//
// Stats - Some statistic about your edit buffer
//
ic.sendFeedback( "Total Number of lines: " + lines.count() +" (max " + maxLines + "), total bytes: " + currentBytes + " (max " + maxBytes + ")" );
}
else if(entered.startsWith(".g"))
{
//
// Go - Go to a given line No.
//
if(entered.length()>2)
{
if(Character.isDigit(entered.charAt(2)))
{
Integer lineNo;
try
{
lineNo=Integer.valueOf(entered.substring(2));
}
catch(java.lang.NumberFormatException e)
{
ic.sendError("Invalid Line No: " + e.getMessage());
continue;
}
// Integer lineNo=Integer.valueOf(entered.substring(2));
if(lines.count()>=lineNo.intValue())
{
cline.first();
for(int i=0;i<lineNo.intValue()-1;i++)
{
cline.next();
}
ic.sendRaw((String)cline.element());
}
else
{
ic.sendError("Line Number " + lineNo.intValue() + " out of range. Total Lines in buffer: " + lines.count());
}
}
else
{
ic.sendError("Usage: .g<n> ... where <n> is the line no. to go to.");
}
}
else
{
ic.sendError("Usage: .g<n> ... where <n> is the line no. to go to.");
}
}
else
{
//
// Now for the numerical looping commands, ie .5d
//
int loop;
String numberString=extractNumber(entered);
if(numberString.length() > 0)
{
Integer intLoop=Integer.valueOf(numberString);
loop=intLoop.intValue();
if(numberString.length()+1==entered.length())
{
if(lines.count()>=loop)
{
cline.first();
for(int i=0;i<loop-1;i++)
{
cline.next();
}
ic.sendRaw((String)cline.element());
}
else
{
ic.sendError("Line Number " + loop + " out of range. Total Lines in buffer: " + lines.count());
}
loop=0;
}
}
else
{
loop=1;
}
for(int i=0;i<loop;i++)
{
if( entered.endsWith( "+" ) )
{
//
// Go forward 1 line
//
if( cline.isLast() )
{
ic.sendError( "Already at the end of the buffer - can't go forward" );
}
else
{
cline.next();
ic.sendFeedback( (String) cline.element() );
}
}
else if( entered.endsWith( "-" ) )
{
//
// Go back one line
//
if( cline.isFirst() )
{
ic.sendError( "Already at the start of the buffer - can't go back" );
}
else
{
cline.previous();
ic.sendFeedback( (String) cline.element() );
}
}
else if( entered.endsWith( "d" ) || entered.endsWith( "del" ) )
{
//
// delete - Delete the current line
//
if( cline.isLast() )
{
ic.sendError( "At end of buffer - cannot delete" );
}
else
{
cline.remove();
ic.sendFeedback( "Line deleted" );
}
}
else
{
//
// Okay ... command not found/
//
ic.sendError("Command: " + entered + " not found.");
break;
}
}
currentBytes = countBytes( lines );
}
}
else
{
if( lines.count() > maxLines )
{
ic.sendError( "Too many lines, line NOT added." );
}
else if( currentBytes + entered.length() > maxBytes )
{
ic.sendError( "Too many characters in buffer, line NOT added." );
}
else
{
cline.insertBefore( entered );
ic.send( entered );
currentBytes += entered.length();
}
}
}
}
static private void display( InteractiveConnection ic, LinkedList lines, int alignment )
{
StringBuffer sb = new StringBuffer();
for( Enumeration e = lines.elements(); e.hasMoreElements(); )
{
String s = (String)e.nextElement();
if( e.hasMoreElements() )
{
sb.append( s );
sb.append( '\n' );
}
}
ic.send( new TextParagraph( alignment, sb.toString() ) );
}
static private int countBytes( LinkedList lines )
{
int b = 0;
for( Enumeration e = lines.elements(); e.hasMoreElements(); )
{
String s = (String) e.nextElement();
b += s.length();
}
return( b );
}
static private String extractNumber(String entered)
{
int i;
for( i = 1; i < entered.length(); i++ )
{
if( !Character.isDigit(entered.charAt(i)) )
{
break;
}
}
return( entered.substring( 1, i ) );
}
}