/*******************************************************************************
 * Copyright (c) 2003, 2011 Wind River Systems, Inc. and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *******************************************************************************/
package com.google.eclipse.elt.emulator.core;

import java.io.*;
import java.util.List;

import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.swt.events.*;

import com.google.eclipse.elt.emulator.impl.*;
import com.google.eclipse.elt.emulator.model.*;
import com.google.eclipse.elt.emulator.provisional.api.*;

/**
 * This class processes character data received from the remote host and displays it to the user using the Terminal
 * view's StyledText widget. This class processes ANSI control characters, including NUL, backspace, carriage return,
 * line-feed, and a subset of ANSI escape sequences sufficient to allow use of screen-oriented applications, such as vi,
 * Emacs, and any GNU readline-enabled application (bash, bc, ncftp, etc.).
 * <p>
 */
public class VT100Emulator implements ControlListener {
  // This is a character processing state: Initial state.
  private static final int ANSISTATE_INITIAL = 0;

  // This is a character processing state: We've seen an escape character.
  private static final int ANSISTATE_ESCAPE = 1;

  // Character processing state: We've seen a '[' after an escape character. Expecting a parameter character or a
  // command character next.
  private static final int ANSISTATE_EXPECTING_PARAMETER_OR_COMMAND = 2;

  // Character processing state: We've seen a ']' after an escape character. We are now expecting an operating system
  // command that reprograms an intelligent terminal.
  private static final int ANSISTATE_EXPECTING_OS_COMMAND = 3;

  /**
   * This field holds the current state of the Finite Terminal State Automaton (FSA) that recognizes ANSI escape
   * sequences.
   *
   * @see #processNewText()
   */
  private int ansiState = ANSISTATE_INITIAL;

  // Holds a reference to the {@link TerminalControl} object that instantiates this class.
  private final ITerminalControlForText terminal;

  // Holds a reference to the StyledText widget that is used to display text to the user.
  private final IVT100EmulatorBackend text;

  // Holds the saved absolute line number of the cursor when processing the "ESC 7" and "ESC 8" command sequences.
  private int savedCursorLine = 0;

  // Holds the saved column number of the cursor when processing the "ESC 7" and "ESC 8" command sequences.
  private int savedCursorColumn = 0;

  // Holds an array of StringBuffer objects, each of which is one parameter from the current ANSI escape
  // sequence. For example, when parsing the escape sequence "\e[20;10H", this array holds the strings "20" and "10".
  private final StringBuffer[] parameters = new StringBuffer[16];

  // Holds the OS-specific command found in an escape sequence of the form "\e]...\u0007".
  private final StringBuffer ansiOsCommand = new StringBuffer(128);

  // Holds the index of the next unused element of the array stored in field 'parameters'.
  private int nextAnsiParameter = 0;

  private int nextChar = -1;

  private Reader reader;

  private boolean crAfterNewLine;

  /**
   * The constructor.
   */
  public VT100Emulator(ITerminalTextData data, ITerminalControlForText terminal, Reader reader) {
    super();
    this.terminal = terminal;
    for (int i = 0; i < parameters.length; ++i) {
      parameters[i] = new StringBuffer();
    }
    setInputStreamReader(reader);
    if (TerminalPlugin.isOptionEnabled("com.google.eclipse.tm.terminal/debug/log/VT100Backend")) {
      text = new VT100BackendTraceDecorator(new VT100EmulatorBackend(data), System.out);
    } else {
      text = new VT100EmulatorBackend(data);
    }
  }

  /**
   * Set the reader that this terminal gets its input from.
   *
   * The reader can be changed while the Terminal is running, but a change of the reader likely loses some characters
   * which have not yet been fully read. Changing the reader can be done in order to change the selected Encoding,
   * though. This is typically done when the Terminal is constructed, i.e. before it really starts operation; or, when
   * the user manually selects a different encoding and thus doesn't care about losing old characters.
   *
   * @param reader the new reader.
   */
  public void setInputStreamReader(Reader reader) {
    this.reader = reader;
  }

  public void setDimensions(int lines, int cols) {
    text.setDimensions(lines, cols);
    ITerminalConnector telnetConnection = getConnector();
    if (telnetConnection != null) {
      telnetConnection.setTerminalSize(text.getColumns(), text.getLines());
    }
  }

  public void dispose() {
  }

  @Override public void controlMoved(ControlEvent event) {
  }

  @Override public void controlResized(ControlEvent event) {
    adjustTerminalDimensions();
  }

  public void clearTerminal() {
    text.clearAll();
  }

  public void fontChanged() {
    if (text != null) {
      adjustTerminalDimensions();
    }
  }

  public void processText() {
    try {
      // Find the width and height of the terminal, and resize it to display an integral number of lines and columns.
      adjustTerminalDimensions();
      // Restore the caret offset, process and display the new text, then save
      // the caret offset. See the documentation for field caretOffset for
      // details.
      // ISSUE: Is this causing the scroll-to-bottom-on-output behavior?
      try {
        processNewText();
      } catch (IOException e) {
        Logger.logException(e);
      }
    } catch (RuntimeException e) {
      Logger.logException(e);
    }
  }

  /**
   * This method scans the newly received text, processing ANSI control characters and escape sequences and displaying
   * normal text.
   *
   * @throws IOException if something goes wrong.
   */
  private void processNewText() throws IOException {
    // Scan the newly received text.
    while (hasNextChar()) {
      char character = getNextChar();
      switch (ansiState) {
      case ANSISTATE_INITIAL:
        switch (character) {
        case '\u0000':
          break; // NUL character. Ignore it.
        case '\u0007':
          processBEL(); // BEL (Control-G)
          break;
        case '\b':
          processBackspace(); // Backspace
          break;
        case '\t':
          processTab(); // Tab.
          break;
        case '\n':
          processNewline(); // Newline (Control-J)
          if (crAfterNewLine) {
            processCarriageReturn(); // Carriage Return (Control-M)
          }
          break;
        case '\r':
          processCarriageReturn(); // Carriage Return (Control-M)
          break;
        case '\u001b':
          ansiState = ANSISTATE_ESCAPE; // Escape.
          break;
        default:
          processNonControlCharacters(character);
          break;
        }
        break;
      case ANSISTATE_ESCAPE:
        // We've seen an escape character. Here, we process the character immediately following the escape.
        switch (character) {
        case '[':
          ansiState = ANSISTATE_EXPECTING_PARAMETER_OR_COMMAND;
          nextAnsiParameter = 0;
          // Erase the parameter strings in preparation for optional parameter characters.
          for (int i = 0; i < parameters.length; ++i) {
            parameters[i].delete(0, parameters[i].length());
          }
          break;
        case ']':
          ansiState = ANSISTATE_EXPECTING_OS_COMMAND;
          ansiOsCommand.delete(0, ansiOsCommand.length());
          break;
        case '7':
          // Save cursor position and character attributes.
          ansiState = ANSISTATE_INITIAL;
          savedCursorLine = relativeCursorLine();
          savedCursorColumn = getCursorColumn();
          break;
        case '8':
          // Restore cursor and attributes to previously saved position.
          ansiState = ANSISTATE_INITIAL;
          moveCursor(savedCursorLine, savedCursorColumn);
          break;
        case 'c':
          // Reset the terminal.
          ansiState = ANSISTATE_INITIAL;
          resetTerminal();
          break;
        default:
          Logger.log("Unsupported escape sequence: escape '" + character + "'");
          ansiState = ANSISTATE_INITIAL;
          break;
        }
        break;
      case ANSISTATE_EXPECTING_PARAMETER_OR_COMMAND:
        // Parameters can appear after the '[' in an escape sequence, but they are optional.
        if (character == '@' || (character >= 'A' && character <= 'Z') || (character >= 'a' && character <= 'z')) {
          ansiState = ANSISTATE_INITIAL;
          processAnsiCommandCharacter(character);
        } else {
          processAnsiParameterCharacter(character);
        }
        break;
      case ANSISTATE_EXPECTING_OS_COMMAND:
        // A BEL (\u0007) character marks the end of the OSC sequence.
        if (character == '\u0007') {
          ansiState = ANSISTATE_INITIAL;
          processAnsiOsCommand();
        } else {
          ansiOsCommand.append(character);
        }
        break;
      default:
        // This should never happen! If it does happen, it means there is a bug in the FSA. For robustness, we return to
        // the initial state.
        Logger.log("INVALID ANSI FSA STATE: " + ansiState);
        ansiState = ANSISTATE_INITIAL;
        break;
      }
    }
  }

  private void resetTerminal() {
    text.eraseAll();
    text.setCursor(0, 0);
    text.setStyle(text.getDefaultStyle());
  }

  // This method is called when we have parsed an OS Command escape sequence. The only one we support is
  // "\e]0;...\u0007", which sets the terminal title.
  private void processAnsiOsCommand() {
    if (ansiOsCommand.charAt(0) != '0' || ansiOsCommand.charAt(1) != ';') {
      Logger.log("Ignoring unsupported ANSI OSC sequence: '" + ansiOsCommand + "'");
      return;
    }
    terminal.setTerminalTitle(ansiOsCommand.substring(2));
  }

  // Dispatches control to various processing methods based on the command character found in the most recently received
  // ANSI escape sequence. This method only handles command characters that follow the ANSI standard Control Sequence
  // Introducer (CSI), which is "\e[...", where "..." is an optional ';'-separated sequence of numeric parameters.
  private void processAnsiCommandCharacter(char ansiCommandCharacter) {
    // If the width or height of the terminal is ridiculously small (one line or column or less), don't even try to
    // process the escape sequence. This avoids throwing an exception (SPR 107450). The display will be messed up, but
    // what did you user expect by making the terminal so small?
    switch (ansiCommandCharacter) {
    case '@':
      // Insert character(s).
      processAnsiCommand_atsign();
      break;
    case 'A':
      // Move cursor up N lines (default 1).
      processAnsiCommand_A();
      break;
    case 'B':
      // Move cursor down N lines (default 1).
      processAnsiCommand_B();
      break;
    case 'C':
      // Move cursor forward N columns (default 1).
      processAnsiCommand_C();
      break;
    case 'D':
      // Move cursor backward N columns (default 1).
      processAnsiCommand_D();
      break;
    case 'E':
      // Move cursor to first column of Nth next line (default 1).
      processAnsiCommand_E();
      break;
    case 'F':
      // Move cursor to first column of Nth previous line (default 1).
      processAnsiCommand_F();
      break;
    case 'G':
      // Move to column N of current line (default 1).
      processAnsiCommand_G();
      break;
    case 'H':
      // Set cursor Position.
      processAnsiCommand_H();
      break;
    case 'J':
      // Erase part or all of display. Cursor does not move.
      processAnsiCommand_J();
      break;
    case 'K':
      // Erase in line (cursor does not move).
      processAnsiCommand_K();
      break;
    case 'L':
      // Insert line(s) (current line moves down).
      processAnsiCommand_L();
      break;
    case 'M':
      // Delete line(s).
      processAnsiCommand_M();
      break;
    case 'm':
      // Set Graphics Rendition (SGR).
      processAnsiCommand_m();
      break;
    case 'n':
      // Device Status Report (DSR).
      processAnsiCommand_n();
      break;
    case 'P':
      // Delete character(s).
      processAnsiCommand_P();
      break;
    case 'S':
      // Scroll up.
      // Emacs, vi, and GNU readline don't seem to use this command, so we ignore it for now.
      break;
    case 'T':
      // Scroll down.
      // Emacs, vi, and GNU readline don't seem to use this command, so we ignore it for now.
      break;
    case 'X':
      // Erase character.
      // Emacs, vi, and GNU readline don't seem to use this command, so we ignore it for now.
      break;
    case 'Z':
      // Cursor back tab.
      // Emacs, vi, and GNU readline don't seem to use this command, so we ignore it for now.
      break;

    default:
      Logger.log("Ignoring unsupported ANSI command character: '" + ansiCommandCharacter + "'");
      break;
    }
  }

  // Makes room for N characters on the current line at the cursor position. Text under the cursor moves right without
  // wrapping at the end of the line.
  private void processAnsiCommand_atsign() {
    int charactersToInsert = getAnsiParameter(0);
    text.insertCharacters(charactersToInsert);
  }

  // Moves the cursor up by the number of lines specified by the escape sequence parameter (default 1).
  private void processAnsiCommand_A() {
    moveCursorUp(getAnsiParameter(0));
  }

  // Moves the cursor down by the number of lines specified by the escape sequence parameter (default 1).
  private void processAnsiCommand_B() {
    moveCursorDown(getAnsiParameter(0));
  }

  // Moves the cursor forward by the number of columns specified by the escape sequence parameter (default 1).
  private void processAnsiCommand_C() {
    moveCursorForward(getAnsiParameter(0));
  }

  // Moves the cursor backward by the number of columns specified by the escape sequence parameter (default 1).
  private void processAnsiCommand_D() {
    moveCursorBackward(getAnsiParameter(0));
  }

  // Moves the cursor to the first column of the Nth next line, where N is specified by the ANSI parameter (default 1).
  private void processAnsiCommand_E() {
    int linesToMove = getAnsiParameter(0);
    moveCursor(relativeCursorLine() + linesToMove, 0);
  }

  // Moves the cursor to the first column of the Nth previous line, where N is specified by the ANSI parameter
  // (default 1).
  private void processAnsiCommand_F() {
    int linesToMove = getAnsiParameter(0);
    moveCursor(relativeCursorLine() - linesToMove, 0);
  }

  // Moves the cursor within the current line to the column specified by the ANSI parameter (default is column 1).
  private void processAnsiCommand_G() {
    int targetColumn = 1;
    if (parameters[0].length() > 0) {
      targetColumn = getAnsiParameter(0) - 1;
    }
    moveCursor(relativeCursorLine(), targetColumn);
  }

  // Sets the cursor to a position specified by the escape sequence parameters (default is the upper left corner of the
  // screen).
  private void processAnsiCommand_H() {
    moveCursor(getAnsiParameter(0) - 1, getAnsiParameter(1) - 1);
  }

  // Deletes some (or all) of the text on the screen without moving the cursor.
  private void processAnsiCommand_J() {
    int parameter;
    if (parameters[0].length() == 0) {
      parameter = 0;
    } else {
      parameter = getAnsiParameter(0);
    }
    switch (parameter) {
    case 0:
      text.eraseToEndOfScreen();
      break;
    case 1:
      // Erase from beginning to current position (inclusive).
      text.eraseToCursor();
      break;
    case 2:
      // Erase entire display.
      text.eraseAll();
      break;
    default:
      Logger.log("Unexpected J-command parameter: " + parameter);
      break;
    }
  }

  // Deletes some (or all) of the text in the current line without moving the cursor.
  private void processAnsiCommand_K() {
    int parameter = getAnsiParameter(0);
    switch (parameter) {
    case 0:
      // Erase from beginning to current position (inclusive).
      text.eraseLineToCursor();
      break;
    case 1:
      // Erase from current position to end (inclusive).
      text.eraseLineToEnd();
      break;
    case 2:
      // Erase entire line.
      text.eraseLine();
      break;
    default:
      Logger.log("Unexpected K-command parameter: " + parameter);
      break;
    }
  }

  // Inserts one or more blank lines. The current line of text moves down. Text that falls off the bottom of the screen
  // is deleted.
  private void processAnsiCommand_L() {
    text.insertLines(getAnsiParameter(0));
  }

  // Deletes one or more lines of text. Any lines below the deleted lines move up, which we implement by appending
  // new lines to the end of the text.
  private void processAnsiCommand_M() {
    text.deleteLines(getAnsiParameter(0));
  }

  // Sets a new graphics rendition mode, such as foreground/background color, bold/normal text, and reverse video.
  private void processAnsiCommand_m() {
    if (parameters[0].length() == 0) {
      // This a special case: when no ANSI parameter is specified, act like a single parameter equal to 0 was specified.
      parameters[0].append('0');
    }
    Style style = text.getStyle();
    // There are a non-zero number of ANSI parameters. Process each one in order.
    int parameterCount = parameters.length;
    int parameterIndex = 0;
    while (parameterIndex < parameterCount && parameters[parameterIndex].length() > 0) {
      int parameter = getAnsiParameter(parameterIndex);
      switch (parameter) {
      case 0:
        // Reset all graphics modes.
        style = text.getDefaultStyle();
        break;
      case 1:
        style = style.setBold(true);
        break;
      case 4:
        style = style.setUnderline(true);
        break;
      case 5:
        style = style.setBlink(true);
        break;
      case 7:
        style = style.setReverse(true);
        break;
      case 10: // Set primary font. Ignored.
        break;
      case 21:
      case 22:
        style = style.setBold(false);
        break;
      case 24:
        style = style.setUnderline(false);
        break;
      case 25:
        style = style.setBlink(false);
        break;
      case 27:
        style = style.setReverse(false);
        break;
      case 30:
        style = style.setForground("BLACK");
        break;
      case 31:
        style = style.setForground("RED");
        break;
      case 32:
        style = style.setForground("GREEN");
        break;
      case 33:
        style = style.setForground("YELLOW");
        break;
      case 34:
        style = style.setForground("BLUE");
        break;
      case 35:
        style = style.setForground("MAGENTA");
        break;
      case 36:
        style = style.setForground("CYAN");
        break;
      case 37:
        style = style.setForground("WHITE_FOREGROUND");
        break;
      case 40:
        style = style.setBackground("BLACK");
        break;
      case 41:
        style = style.setBackground("RED");
        break;
      case 42:
        style = style.setBackground("GREEN");
        break;
      case 43:
        style = style.setBackground("YELLOW");
        break;
      case 44:
        style = style.setBackground("BLUE");
        break;
      case 45:
        style = style.setBackground("MAGENTA");
        break;
      case 46:
        style = style.setBackground("CYAN");
        break;
      case 47:
        style = style.setBackground("WHITE");
        break;
      default:
        Logger.log("Unsupported graphics rendition parameter: " + parameter);
        break;
      }
      ++parameterIndex;
    }
    text.setStyle(style);
  }

  // Responds to an ANSI Device Status Report (DSR) command from the remote endpoint requesting the cursor position.
  // Requests for other kinds of status are ignored.
  private void processAnsiCommand_n() {
    // Do nothing if the numeric parameter was not 6 (which means report cursor position).
    if (getAnsiParameter(0) != 6) {
      return;
    }
    // Send the ANSI cursor position (which is 1-based) to the remote endpoint.
    String positionReport = "\u001b[" + (relativeCursorLine() + 1) + ";" + (getCursorColumn() + 1) + "R";
    try {
      // TODO(alruiz): use same encoding as terminal.
      OutputStreamWriter streamWriter = new OutputStreamWriter(terminal.getOutputStream(), "ISO-8859-1");
      streamWriter.write(positionReport, 0, positionReport.length());
      streamWriter.flush();
    } catch (IOException ex) {
      Logger.log("Caught IOException!");
    }
  }

  // Deletes one or more characters starting at the current cursor position. Characters on the same line and to the
  // right of the deleted characters move left. If there are no characters on the current line at or to the right of the
  // cursor column, no text is deleted.
  private void processAnsiCommand_P() {
    text.deleteCharacters(getAnsiParameter(0));
  }

  // Returns one of the numeric ANSI parameters received in the most recent escape sequence.
  private int getAnsiParameter(int parameterIndex) {
    if (parameterIndex < 0 || parameterIndex >= parameters.length) {
      // This should never happen.
      return -1;
    }
    String parameter = parameters[parameterIndex].toString();
    if (parameter.length() == 0) {
      return 1;
    }
    int parameterValue = 1;
    // Don't trust the remote endpoint to send well formed numeric parameters.
    try {
      parameterValue = Integer.parseInt(parameter);
    } catch (NumberFormatException ex) {
      parameterValue = 1;
    }
    return parameterValue;
  }

  // Processes a single parameter character in an ANSI escape sequence. Parameters are the (optional) characters
  // between the leading "\e[" and the command character in an escape sequence (e.g., in the escape sequence
  // "\e[20;10H", the parameter characters are "20;10"). Parameters are integers separated by one or more ';'s.
  private void processAnsiParameterCharacter(char ch) {
    if (ch == ';') {
      ++nextAnsiParameter;
    } else {
      if (nextAnsiParameter < parameters.length) {
        parameters[nextAnsiParameter].append(ch);
      }
    }
  }

  // Processes a contiguous sequence of non-control characters. This is a performance optimization, so that we don't
  // have to insert or append each non-control character individually to the StyledText widget. A non-control character
  // is any character that passes the condition in the below while loop.
  private void processNonControlCharacters(char character) throws IOException {
    StringBuilder buffer = new StringBuilder();
    buffer.append(character);
    // Identify a contiguous sequence of non-control characters, starting at firstNonControlCharacterIndex in newText.
    while (hasNextChar()) {
      character = getNextChar();
      if (character == '\u0000' || character == '\b' || character == '\t' || character == '\u0007' || character == '\n'
          || character == '\r' || character == '\u001b') {
        pushBackChar(character);
        break;
      }
      buffer.append(character);
    }
    // Now insert the sequence of non-control characters in the StyledText widget
    // at the location of the cursor.
    displayNewText(buffer.toString());
  }

  // Displays a subset of the newly-received text in the Terminal view, wrapping text at the right edge of the screen
  // and overwriting text when the cursor is not at the very end of the screen's text.
  // There are never any ANSI control characters or escape sequences in the text being displayed by this method (this
  // includes newlines, carriage returns, and tabs).
  private void displayNewText(String buffer) {
    text.appendString(buffer);
  }

  // Processes a BEL (Control-G) character.
  private void processBEL() {
    // TODO
    // Display.getDefault().beep();
  }

  // Processes a backspace (Control-H) character.
  private void processBackspace() {
    moveCursorBackward(1);
  }

  // Processes a tab (Control-I) character. We don't insert a tab character into the StyledText widget. Instead, we move
  // the cursor forward to the next tab stop, without altering any of the text. Tab stops are every 8 columns. The
  // cursor will never move past the rightmost column.
  private void processTab() {
    moveCursorForward(8 - (getCursorColumn() % 8));
  }

  // Processes a newline (Control-J) character. A newline (NL) character just moves the cursor to the same column on the
  // next line, creating new lines when the cursor reaches the bottom edge of the terminal. This is counter-intuitive,
  // especially to UNIX programmers who are taught that writing a single NL to a terminal is sufficient to move the
  // cursor to the first column of the next line, as if a carriage return (CR) and a NL were written.
  //
  // UNIX terminals typically display a NL character as a CR followed by a NL because the terminal device typically has
  // the ONLCR attribute bit set (see the termios(4) man page for details), which causes the terminal device driver to
  // translate NL to CR + NL on output. The terminal itself (i.e., a hardware terminal or a terminal emulator, like
  // xterm or this code) _always_ interprets a CR to mean "move the cursor to the beginning of the current
  // line" and a NL to mean "move the cursor to the same column on the next line".
  private void processNewline() {
    text.processNewline();
  }

  // Processes a Carriage Return (Control-M).
  private void processCarriageReturn() {
    text.setCursorColumn(0);
  }

  // Computes the width of the terminal in columns and its height in lines, then adjusts the width and height of the
  // view's StyledText widget so that it displays an integral number of lines and columns of text. The adjustment is
  // always to shrink the widget vertically or horizontally, because if the control were to grow, it would be clipped by
  // the edges of the view window (i.e., the view window does not become larger to accommodate its contents becoming
  // larger).
  //
  // This method must be called immediately before each time text is written to the terminal so that we can properly
  // line wrap text. Because it is called so frequently, it must be fast when there is no resizing to be done.
  private void adjustTerminalDimensions() {
    // Compute how many pixels we need to shrink the StyledText control vertically to make it display an integral number
    // of lines of text.
    //
    // TODO
    // if(text.getColumns()!=80 && text.getLines()!=80) text.setDimensions(24, 80);
    ITerminalConnector connector = getConnector();
    // TODO MSA: send only if dimensions have really changed!
    if (connector != null) {
      connector.setTerminalSize(text.getColumns(), text.getLines());
    }
  }

  private ITerminalConnector getConnector() {
    if (terminal.getTerminalConnector() != null) {
      return terminal.getTerminalConnector();
    }
    return null;
  }

  // Returns the relative line number of the line containing the cursor. The returned line number is relative to the
  // top-most visible line, which has relative line number 0.
  private int relativeCursorLine() {
    return text.getCursorLine();
  }

  // Moves the cursor to the specified line and column. Parameter <i>targetLine</i> is the line number of a screen line,
  // so it has a minimum value of 0 (the topmost screen line) and a maximum value of heightInLines - 1 (the
  // bottom-most screen line). A line does not have to contain any text to move the cursor to any column in that line.
  private void moveCursor(int targetLine, int targetColumn) {
    text.setCursor(targetLine, targetColumn);
  }

  // Moves the cursor down n lines, but won't move the cursor past the bottom of the screen. This method does not cause
  // any scrolling.
  private void moveCursorDown(int lines) {
    moveCursor(relativeCursorLine() + lines, getCursorColumn());
  }

  // Moves the cursor up n lines, but won't move the cursor past the top of the screen. This method does not cause any
  // scrolling.
  private void moveCursorUp(int lines) {
    moveCursor(relativeCursorLine() - lines, getCursorColumn());
  }

  // Method moves the cursor forward n columns, but won't move the cursor past the right edge of the screen, nor will
  // it move the cursor onto the next line. This method does not cause any scrolling.
  private void moveCursorForward(int columnsToMove) {
    moveCursor(relativeCursorLine(), getCursorColumn() + columnsToMove);
  }

  // Moves the cursor backward n columns, but won't move the cursor past the left edge of the screen, nor will it move
  // the cursor onto the previous line. This method does not cause any scrolling.
  private void moveCursorBackward(int columnsToMove) {
    moveCursor(relativeCursorLine(), getCursorColumn() - columnsToMove);
  }

  /**
   * Resets the state of the terminal text (foreground color, background color, font style and other internal state). It
   * essentially makes it ready for new input.
   */
  public void resetState() {
    ansiState = ANSISTATE_INITIAL;
    text.setStyle(text.getDefaultStyle());
  }

  private char getNextChar() throws IOException {
    int c = -1;
    if (nextChar != -1) {
      c = nextChar;
      nextChar = -1;
    } else {
      c = reader.read();
    }
    // TODO: better end of file handling
    if (c == -1) {
      c = 0;
    }
    return (char) c;
  }

  private boolean hasNextChar() throws IOException {
    if (nextChar >= 0) {
      return true;
    }
    return reader.ready();
  }

  /**
   * Put back one character to the stream. This method can push back exactly one character. The character is the next
   * character returned by {@link #getNextChar}.
   *
   * @param c the character to be pushed back.
   */
  private void pushBackChar(char c) {
    nextChar = c;
  }

  private int getCursorColumn() {
    return text.getCursorColumn();
  }

  public boolean isCrAfterNewLine() {
    return crAfterNewLine;
  }

  public void setCrAfterNewLine(boolean crAfterNewLine) {
    this.crAfterNewLine = crAfterNewLine;
  }

  public List<IHyperlink> hyperlinksAt(int line) {
    return text.hyperlinksAt(line);
  }
}
