EditableBufferedReader.java 5.16 KB
package pad.prac1;
import java.io.*;


public class EditableBufferedReader extends BufferedReader 
{
	/*
	 * MODE DEFINITIONS
	 */
	
	public static final int INSERT = 0;
	public static final int OVERWRITE = 1;
	public static final int DEL_BACKWARD = 0;
	public static final int DEL_FORWARD = 1;
	
	/*
	 * TYPE DEFINITIONS
	 */
	
	public static final int ESCAPE_SEQUENCE = 0;
	public static final int PRINTABLE = 1;
	public static final int NON_PRINTABLE = 2;
	
	/* KEY DEFINITIONS
	 * ESC (0x1B) starts an escape sequence
	 * ESC+[+C (0x1B 0x5B 0x43) Cursor Forward
	 * ESC+[+D (0x1B 0x5B 0x44) Cursor Backward
	 * ESC+[+2+~ (0x1B 0x5B 0x32 0x7E) Insert
	 * ESC+[+3+~ (0x1B 0x5B 0x33 0x7E) Delete forward
	 * ESC+O+H (0x1B 0x4F 0x48) Home
	 * ESC+O+F (0x1B 0x4F 0x46) End
	 */
	
	public static final int RETURN_KEY 		= 0x0D;
	public static final int BACKSPACE 		= 0x08;
	public static final int BACKSPACE_DEL 	= 0x7B;
	public static final int ESC 			= 0x1B;
	public static final int ESC_SEQ 		= 0x5B;
	public static final int FORWARD_C 		= 0x43;
	public static final int BACKWARD_D		= 0x44;
	public static final int DEL_3 			= 0x33;
	public static final int TILDE 			= 0x7E;
	public static final int HOME_END 		= 0x4F;
	public static final int HOME 			= 0x48;
	public static final int END 			= 0x46;
	public static final int INSERT_2		= 0x32;
	
	private String line = "";
	private int lineLength = 0;
	private int cursorPosition = 1;
	private boolean returnKey = false;
	private int writeMode = INSERT;
	
	
	public EditableBufferedReader(Reader in)
	{
		super(in);
	}
	
	public EditableBufferedReader(Reader in, int sz)
	{
		super(in,sz);
	}
	
	private void setRaw() throws IOException, InterruptedException
	{
		String[] cmd = {"/bin/sh", "-c", "stty raw -echo </dev/tty"};
		Runtime.getRuntime().exec(cmd).waitFor();
	}
	
	private void unsetRaw() throws IOException, InterruptedException
	{
		String[] cmd = {"/bin/sh", "-c", "stty -raw echo </dev/tty"};
		Runtime.getRuntime().exec(cmd).waitFor();
	}
	
	private int parseKey(int key)
	{
		//TO IMPLEMENT BOTH MODES
		return PRINTABLE;
	}
	
	public void addChar(char character)
	{
		//switch writemode
		//if insert
			//print space
			//moveto cursorPosition-1
			//print char
			//add to string
			//update string length
			//update cursor position
		//if overwrite
			//just print char
			//add to string
			//update string length
			//update cursor position
	}
	
	public void delChar(int mode)
	{
		//switch mode
		//if back
			//del char using backspace
			//remove char from line string
			//update cursor position
			//update line length
		//if forward
			//moveto cursorPosition+1
			//del char using backspace
			//remove char from line string
			//update line length
	}
	
	private void moveCursorForward()
	{
		System.out.print((char)ESC);
		System.out.print((char)ESC_SEQ);
		System.out.print((char)FORWARD_C);
	}
	
	private void moveCursorBackward()
	{
		System.out.print((char)ESC);
		System.out.print((char)ESC_SEQ);
		System.out.print((char)BACKWARD_D);
	}
	
	public void moveCursorTo(int pos)
	{
		if((pos <= lineLength) && (pos >= 1))
		{
			if(pos > cursorPosition)
			{
				for(int i = 0; i < (pos - cursorPosition); i++)
				{
					moveCursorForward();
				}
			}
			
			else if(pos < cursorPosition)
			{
				for(int i = 0; i < (cursorPosition - pos); i++)
				{
					moveCursorBackward();
				}
			}
			cursorPosition = pos;
		}
	}
	
	public int read() throws IOException
	{
		return super.read();
	}
	
	public String readLine()
	{
		try 
		{
			setRaw();
		} 
		catch (Exception e) 
		{
			System.out.println("Couldn't set terminal in raw mode");
			return "";
		}
		while(!returnKey)
		{
			try 
			{
				int character = read();
				System.out.println("\n\n" + character + "\n");
				switch(parseKey(character))
				{
					case ESCAPE_SEQUENCE:
						if(read() == ESC_SEQ)
						{
							switch(read())
							{
								case FORWARD_C:
									moveCursorTo(cursorPosition+1);
									break;
									
								case BACKWARD_D:
									moveCursorTo(cursorPosition-1);
									break;
								
								case DEL_3:
									if(read() == TILDE)
									{
										delChar(DEL_FORWARD);
									}
									break;
									
								case INSERT_2:
									if(read() == TILDE)
									{
										writeMode = 1-writeMode;
									}
									break;
									
								case HOME_END:
									switch(read())
									{
										case HOME:
											moveCursorTo(1);
											break;
											
										case END:
											moveCursorTo(lineLength+1);
											break;
									}
									break;
							}
						}
						break;
						
					case PRINTABLE:
						switch(character)
						{
							case RETURN_KEY:
								returnKey = true;
								break;
							
							case BACKSPACE:
							case BACKSPACE_DEL:
								delChar(DEL_BACKWARD);
								break;
															
							default:
								addChar((char)character);
								break;
						}
						break;
						
					case NON_PRINTABLE:
						//ignore
						break;
				}
				
			} 
			catch (IOException e)
			{
				System.out.println("Couldn't unset raw mode");
				break;
			}
		}
		try 
		{
			unsetRaw();
		} 
		catch (Exception e) 
		{
			System.out.println("Couldn't unset raw mode");
			return "";
		}
		System.out.println("");
		return line;
	}
}