/*******************************************************************************
 * 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(null);
  }

  // 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();
    if (style == null) {
      style = defaultStyle();
    }
    // 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 = defaultStyle();
        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);
  }

  private Style defaultStyle() {
    return Style.getStyle("black", "white");
  }

  // 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(null);
  }

  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);
  }
}
