/*******************************************************************************
 * 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 static com.google.eclipse.elt.emulator.impl.TerminalPlugin.isOptionEnabled;
import static org.eclipse.core.runtime.Status.OK_STATUS;
import static org.eclipse.jface.bindings.keys.SWTKeySupport.convertEventToUnmodifiedAccelerator;

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

import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.contexts.*;
import org.eclipse.ui.keys.IBindingService;

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

public class VT100TerminalControl implements ITerminalControlForText, ITerminalControl, ITerminalViewControl {
  protected static final String[] LINE_DELIMITERS = { "\n" };

  private static final String DEFAULT_ENCODING =
      new InputStreamReader(new ByteArrayInputStream(new byte[0])).getEncoding();

  // This field holds a reference to a TerminalText object that performs all ANSI text processing on data received from
  // the remote host and controls how text is displayed using the view's StyledText widget.
  private final VT100Emulator terminalText;

  private Display display;
  private TextCanvas textControl;
  private Composite rootControl;
  private Clipboard clipboard;
  private KeyListener keyHandler;
  private final ITerminalListener terminalListener;
  private String message = "";
  private FocusListener focusListener;
  private ITerminalConnector connector;
  private final ITerminalConnector[] connectors;
  private final PipedInputStream inputStream;
  private String encoding = DEFAULT_ENCODING;
  private InputStreamReader inputStreamReader;
  private ICommandInputField commandInputField;
  private volatile TerminalState state;
  private final ITerminalTextData terminalModel;

  volatile private Job job;

  private final EditActionAccelerators editActionAccelerators = new EditActionAccelerators();

  public VT100TerminalControl(ITerminalListener target, Composite wndParent, ITerminalConnector[] connectors) {
    this.connectors = connectors;
    terminalListener = target;
    terminalModel = TerminalTextDataFactory.makeTerminalTextData();
    terminalModel.setMaxHeight(1000);
    inputStream = new PipedInputStream(8 * 1024);
    terminalText = new VT100Emulator(terminalModel, this, null);
    try {
      // Use default Encoding as start, until setEncoding() is called.
      setEncoding(null);
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
      // Fall back to local platform default encoding
      encoding = DEFAULT_ENCODING;
      inputStreamReader = new InputStreamReader(inputStream);
      terminalText.setInputStreamReader(inputStreamReader);
    }
    setUpTerminal(wndParent);
  }

  @Override public void setEncoding(String encoding) throws UnsupportedEncodingException {
    if (encoding == null) {
      encoding = "ISO-8859-1";
    }
    inputStreamReader = new InputStreamReader(inputStream, encoding);
    // remember encoding if above didn't throw an exception
    this.encoding = encoding;
    terminalText.setInputStreamReader(inputStreamReader);
  }

  @Override public String getEncoding() {
    return encoding;
  }

  @Override public ITerminalConnector[] getConnectors() {
    return connectors;
  }

  @Override public void copy() {
    copy(DND.CLIPBOARD);
  }

  private void copy(int clipboardType) {
    String selection = getSelection();
    if (selection == null || selection.isEmpty()) {
      return;
    }
    Object[] data = new Object[] { selection };
    Transfer[] types = new Transfer[] { TextTransfer.getInstance() };
    clipboard.setContents(data, types, clipboardType);
  }

  @Override public void paste() {
    paste(DND.CLIPBOARD);
  }

  private void paste(int clipboardType) {
    TextTransfer textTransfer = TextTransfer.getInstance();
    String strText = (String) clipboard.getContents(textTransfer, clipboardType);
    pasteString(strText);
  }

  @Override public boolean pasteString(String text) {
    if (!isConnected()) {
      return false;
    }
    if (text == null) {
      return false;
    }
    if (!encoding.equals(DEFAULT_ENCODING)) {
      sendString(text);
    } else {
      // TODO I do not understand why pasteString would do this here...
      for (int i = 0; i < text.length(); i++) {
        sendChar(text.charAt(i), false);
      }
    }
    return true;
  }

  @Override public void selectAll() {
    getTextControl().selectAll();
  }

  @Override public void sendKey(char character) {
    Event event;
    KeyEvent keyEvent;
    event = new Event();
    event.widget = getTextControl();
    event.character = character;
    event.keyCode = 0;
    event.stateMask = 0;
    event.doit = true;
    keyEvent = new KeyEvent(event);
    keyHandler.keyPressed(keyEvent);
  }

  @Override public void clearTerminal() {
    getTerminalText().clearTerminal();
  }

  @Override public Clipboard getClipboard() {
    return clipboard;
  }

  @Override public String getSelection() {
    String text = textControl.getSelectionText();
    return text == null ? "" : text;
  }

  @Override public boolean setFocus() {
    return getTextControl().setFocus();
  }

  @Override public boolean isEmpty() {
    return getTextControl().isEmpty();
  }

  @Override public boolean isDisposed() {
    return getTextControl().isDisposed();
  }

  @Override public boolean isConnected() {
    return state == TerminalState.CONNECTED;
  }

  @Override public void disposeTerminal() {
    disconnectTerminal();
    clipboard.dispose();
    getTerminalText().dispose();
  }

  @Override public void connectTerminal() {
    if (getTerminalConnector() == null) {
      return;
    }
    terminalText.resetState();
    if (connector.getInitializationErrorMessage() != null) {
      showErrorMessage(NLS.bind(TerminalMessages.cannotConnectTo, connector.getName(),
          connector.getInitializationErrorMessage()));
      return;
    }
    getTerminalConnector().connect(this);
    // clean the error message
    setErrorMessage("");
    waitForConnect();
  }

  @Override public ITerminalConnector getTerminalConnector() {
    return connector;
  }

  @Override public void disconnectTerminal() {
    Logger.log("entered.");
    // Disconnect the remote side first.
    if (getState() != TerminalState.CLOSED && getTerminalConnector() != null) {
      getTerminalConnector().disconnect();
    }
    // Ensure that a new Job can be started; then clean up old Job.
    Job newJob;
    synchronized (this) {
      newJob = job;
      job = null;
    }
    if (newJob != null) {
      newJob.cancel();
      // Join job to avoid leaving job running after workbench shutdown (333613).
      // Interrupt to be fast enough; cannot close fInputStream since it is re-used (bug 348700).
      Thread t = newJob.getThread();
      if (t != null) {
        t.interrupt();
      }
      try {
        newJob.join();
      } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
      }
    }
  }

  private void waitForConnect() {
    // TODO
    // Eliminate this code
    while (getState() == TerminalState.CONNECTING) {
      if (display.readAndDispatch()) {
        continue;
      }
      display.sleep();
    }
    if (getTextControl().isDisposed()) {
      disconnectTerminal();
      return;
    }
    if (!getMsg().isEmpty()) {
      showErrorMessage(getMsg());
      disconnectTerminal();
      return;
    }
    getTextControl().setFocus();
    startReaderJob();
  }

  private synchronized void startReaderJob() {
    if (job == null) {
      initializeJob();
      job.setSystem(true);
      job.schedule();
    }
  }

  private void initializeJob() {
    job = new Job("Terminal data reader") {
      @Override protected IStatus run(IProgressMonitor monitor) {
        IStatus status = OK_STATUS;
        try {
          while (true) {
            while (inputStream.available() == 0 && !monitor.isCanceled()) {
              try {
                inputStream.waitForAvailable(500);
              } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
              }
            }
            if (monitor.isCanceled()) {
              // Do not disconnect terminal here because another reader job may already be running.
              status = Status.CANCEL_STATUS;
              break;
            }
            try {
              // TODO: should block when no text is available!
              terminalText.processText();
            } catch (Exception e) {
              disconnectTerminal();
              status = new Status(IStatus.ERROR, TerminalPlugin.PLUGIN_ID, e.getLocalizedMessage(), e);
              break;
            }
          }
        } finally {
          // Clean the job: start a new one when the connection gets restarted.
          // Bug 208145: make sure we do not clean an other job that's already started (since it would become a zombie)
          synchronized (VT100TerminalControl.this) {
            if (job == this) {
              job = null;
            }
          }
        }
        return status;
      }
    };
  }

  private void showErrorMessage(String message) {
    String title = TerminalMessages.terminalError;
    MessageBox mb = new MessageBox(getShell(), SWT.ICON_ERROR | SWT.OK);
    mb.setText(title);
    mb.setMessage(message);
    mb.open();
  }

  protected void sendString(String string) {
    try {
      // Send the string after converting it to an array of bytes using the platform's default character encoding.
      //
      // TODO: Find a way to force this to use the ISO Latin-1 encoding.
      // TODO: handle Encoding Errors in a better way
      getOutputStream().write(string.getBytes(encoding));
      getOutputStream().flush();
    } catch (SocketException socketException) {
      displayTextInTerminal(socketException.getMessage());
      String strMsg = TerminalMessages.socketError + "!\n" + socketException.getMessage();
      showErrorMessage(strMsg);
      Logger.logException(socketException);
      disconnectTerminal();
    } catch (IOException ioException) {
      showErrorMessage(TerminalMessages.ioError + "!\n" + ioException.getMessage());
      Logger.logException(ioException);
      disconnectTerminal();
    }
  }

  @Override public Shell getShell() {
    return getTextControl().getShell();
  }

  protected void sendChar(char chKey, boolean altKeyPressed) {
    try {
      String text = Character.toString(chKey);
      byte[] bytes = text.getBytes(getEncoding());
      OutputStream os = getOutputStream();
      if (os == null) {
        // Bug 207785: NPE when trying to send char while no longer connected
        Logger.log("NOT sending '" + text + "' because no longer connected");
      } else {
        if (altKeyPressed) {
          // When the ALT key is pressed at the same time that a character is typed, translate it into an ESCAPE
          // followed by the character. The alternative in this case is to set the high bit of the character being
          // transmitted, but that will cause input such as ALT-f to be seen as the ISO Latin-1 character '�', which
          // can be confusing to European users running Emacs, for whom Alt-f should move forward a word instead of
          // inserting the '�' character.
          //
          // TODO: Make the ESCAPE-vs-highbit behavior user configurable.
          Logger.log("sending ESC + '" + text + "'");
          getOutputStream().write('\u001b');
          getOutputStream().write(bytes);
        } else {
          Logger.log("sending '" + text + "'");
          getOutputStream().write(bytes);
        }
        getOutputStream().flush();
      }
    } catch (SocketException socketException) {
      Logger.logException(socketException);
      displayTextInTerminal(socketException.getMessage());
      String message = TerminalMessages.socketError + "!\n" + socketException.getMessage();
      showErrorMessage(message);
      Logger.logException(socketException);
      disconnectTerminal();
    } catch (IOException ioException) {
      Logger.logException(ioException);
      displayTextInTerminal(ioException.getMessage());
      String message = TerminalMessages.ioError + "!\n" + ioException.getMessage();
      showErrorMessage(message);
      Logger.logException(ioException);
      disconnectTerminal();
    }
  }

  @Override public void setUpTerminal(Composite parent) {
    Assert.isNotNull(parent);
    state = TerminalState.CLOSED;
    setUpControls(parent);
    setupListeners();
  }

  @Override public void setFont(Font font) {
    getTextControl().setFont(font);
    if (commandInputField != null) {
      commandInputField.setFont(font);
    }
    // Tell the TerminalControl singleton that the font has changed.
    textControl.onFontChange();
    getTerminalText().fontChanged();
  }

  @Override public Font getFont() {
    return getTextControl().getFont();
  }

  @Override public Control getControl() {
    return textControl;
  }

  @Override public Control getRootControl() {
    return rootControl;
  }

  protected void setUpControls(Composite parent) {
    // The Terminal view now aims to be an ANSI-conforming terminal emulator, so it can't have a horizontal scroll bar
    // (but a vertical one is ok). Also, do _not_ make the TextViewer read-only, because that prevents it from seeing a
    // TAB character when the user presses TAB (instead, the TAB causes focus to switch to another Workbench control).
    // We prevent local keyboard input from modifying the text in method TerminalVerifyKeyListener.verifyKey().
    rootControl = new Composite(parent, SWT.NONE);
    GridLayout layout = new GridLayout();
    layout.marginWidth = 0;
    layout.marginHeight = 0;
    layout.verticalSpacing = 0;
    rootControl.setLayout(layout);
    ITerminalTextDataSnapshot snapshot = terminalModel.makeSnapshot();
    // TODO how to get the initial size correctly!
    snapshot.updateSnapshot(false);
    ITextCanvasModel canvasModel = new PollingTextCanvasModel(snapshot);
    textControl = new TextCanvas(rootControl, canvasModel, SWT.NONE, new TextLineRenderer(textControl, canvasModel));
    textControl.addMouseListener(new MouseAdapter() {
      @Override public void mouseUp(MouseEvent e) {
        IHyperlink hyperlink = hyperlinkAt(e);
        if (hyperlink != null) {
          hyperlink.open();
        }
      }
    });
    textControl.addMouseMoveListener(new MouseMoveListener() {
      @Override public void mouseMove(MouseEvent e) {
        IHyperlink hyperlink = hyperlinkAt(e);
        int cursorId = (hyperlink == null) ? SWT.CURSOR_IBEAM : SWT.CURSOR_HAND;
        Cursor newCursor = textControl.getDisplay().getSystemCursor(cursorId);
        if (!newCursor.equals(textControl.getCursor())) {
          textControl.setCursor(newCursor);
        }
      }
    });
    textControl.setLayoutData(new GridData(GridData.FILL_BOTH));
    textControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    textControl.addResizeHandler(new TextCanvas.ResizeListener() {
      @Override public void sizeChanged(int lines, int columns) {
        terminalText.setDimensions(lines, columns);
      }
    });
    textControl.addMouseListener(new MouseAdapter() {
      @Override public void mouseUp(MouseEvent e) {
        // update selection used by middle mouse button paste
        if (e.button == 1 && getSelection().length() > 0) {
          copy(DND.SELECTION_CLIPBOARD);
        }
      }
    });
    display = getTextControl().getDisplay();
    clipboard = new Clipboard(display);
    setFont(JFaceResources.getTextFont());
  }

  private IHyperlink hyperlinkAt(MouseEvent e) {
    Point p = textControl.screenPointToCell(e.x, e.y);
    if (p != null) {
      List<IHyperlink> hyperlinks = terminalText.hyperlinksAt(p.y);
      for (IHyperlink hyperlink : hyperlinks) {
        IRegion region = hyperlink.getHyperlinkRegion();
        int start = region.getOffset();
        int end = start + region.getLength() - 1;
        if (p.x >= start && p.x <= end) {
          return hyperlink;
        }
      }
    }
    return null;
  }

  protected void setupListeners() {
    keyHandler = new TerminalKeyHandler();
    focusListener = new TerminalFocusListener();
    getTextControl().addKeyListener(keyHandler);
    getTextControl().addFocusListener(focusListener);
  }

  @Override public void displayTextInTerminal(String text) {
    writeToTerminal("\r\n" + text + "\r\n");
  }

  private void writeToTerminal(String text) {
    try {
      getRemoteToTerminalOutputStream().write(text.getBytes(encoding));
    } catch (UnsupportedEncodingException e) {
      // should never happen!
      e.printStackTrace();
    } catch (IOException e) {
      // should never happen!
      e.printStackTrace();
    }
  }

  @Override public OutputStream getRemoteToTerminalOutputStream() {
    if (Logger.isLogEnabled()) {
      return new LoggingOutputStream(inputStream.getOutputStream());
    }
    return inputStream.getOutputStream();
  }

  protected boolean isLogCharEnabled() {
    return isOptionEnabled(Logger.TRACE_DEBUG_LOG_CHAR);
  }

  protected boolean isLogBufferSizeEnabled() {
    return isOptionEnabled(Logger.TRACE_DEBUG_LOG_BUFFER_SIZE);
  }

  @Override public OutputStream getOutputStream() {
    if (getTerminalConnector() != null) {
      return getTerminalConnector().getTerminalToRemoteStream();
    }
    return null;
  }

  @Override public void setErrorMessage(String message) {
    this.message = message;
  }

  public String getMsg() {
    return message;
  }

  protected TextCanvas getTextControl() {
    return textControl;
  }

  public VT100Emulator getTerminalText() {
    return terminalText;
  }

  protected class TerminalFocusListener implements FocusListener {
    private IContextActivation contextActivation = null;

    @Override public void focusGained(FocusEvent event) {
      // Disable all keyboard accelerators (e.g., Control-B) so the Terminal view can see every key stroke. Without
      // this, Emacs, vi, and Bash are unusable in the terminal view.
      IBindingService bindingService = (IBindingService) PlatformUI.getWorkbench().getAdapter(IBindingService.class);
      bindingService.setKeyFilterEnabled(false);
      // The above code fails to cause Eclipse to disable menu-activation accelerators (e.g., Alt-F for the File menu),
      // so we set the command context to be the Terminal view's command context. This enables us to override
      // menu-activation accelerators with no-op commands in our plugin.xml file, which enables the terminal view to see
      // absolutly _all_ key-presses.
      IContextService contextService = (IContextService) PlatformUI.getWorkbench().getAdapter(IContextService.class);
      contextActivation = contextService.activateContext("com.google.eclipse.elt.emulator.TerminalContext");
    }

    @Override public void focusLost(FocusEvent event) {
      // Enable all key bindings.
      IBindingService bindingService = (IBindingService) PlatformUI.getWorkbench().getAdapter(IBindingService.class);
      bindingService.setKeyFilterEnabled(true);
      // Restore the command context to its previous value.
      IContextService contextService = (IContextService) PlatformUI.getWorkbench().getAdapter(IContextService.class);
      contextService.deactivateContext(contextActivation);
    }
  }

  protected class TerminalKeyHandler extends KeyAdapter {
    @Override public void keyPressed(KeyEvent event) {
      if (getState() == TerminalState.CONNECTING) {
        return;
      }
      int accelerator = convertEventToUnmodifiedAccelerator(event);
      if (editActionAccelerators.isCopyAction(accelerator)) {
        copy();
        return;
      }
      if (editActionAccelerators.isPasteAction(accelerator)) {
        paste();
        return;
      }
      // We set the event.doit to false to prevent any further processing of this key event. The only reason this is
      // here is because I was seeing the F10 key both send an escape sequence (due to this method) and switch focus to
      // the Workbench File menu (forcing the user to click in the terminal view again to continue entering text). This
      // fixes that.
      event.doit = false;
      char character = event.character;
      if (state == TerminalState.CLOSED) {
        // Pressing ENTER while not connected causes us to connect.
        if (character == '\r') {
          connectTerminal();
          return;
        }
        // Ignore all other keyboard input when not connected.
        // Allow other key handlers (such as Ctrl+F1) do their work.
        event.doit = true;
        return;
      }
      // Manage the Del key
      if (event.keyCode == 0x000007f) {
        sendString("\u001b[3~");
        return;
      }
      // If the event character is NUL ('\u0000'), then a special key was pressed (e.g., PageUp, PageDown, an arrow key,
      // a function key, Shift, Alt, Control, etc.). The one exception is when the user presses Control-@, which sends a
      // NUL character, in which case we must send the NUL to the remote endpoint. This is necessary so that Emacs will
      // work correctly, because Control-@ (i.e., NUL) invokes Emacs' set-mark-command when Emacs is running on a
      // terminal. When the user presses Control-@, the keyCode is 50.
      if (character == '\u0000' && event.keyCode != 50) {
        // A special key was pressed. Figure out which one it was and send the appropriate ANSI escape sequence.
        //
        // IMPORTANT: Control will not enter this method for these special keys unless certain <keybinding> tags are
        // present in the plugin.xml file for the Terminal view. Do not delete those tags.
        switch (event.keyCode) {
        case 0x1000001: // Up arrow.
          sendString("\u001b[A");
          break;
        case 0x1000002: // Down arrow.
          sendString("\u001b[B");
          break;
        case 0x1000003: // Left arrow.
          sendString("\u001b[D");
          break;
        case 0x1000004: // Right arrow.
          sendString("\u001b[C");
          break;
        case 0x1000005: // PgUp key.
          sendString("\u001b[5~");
          break;
        case 0x1000006: // PgDn key.
          sendString("\u001b[6~");
          break;
        case 0x1000007: // Home key.
          sendString("\u001b[H");
          break;
        case 0x1000008: // End key.
          sendString("\u001b[F");
          break;
        case 0x1000009: // Insert.
          sendString("\u001b[2~");
          break;
        case 0x100000a: // F1 key.
          if ((event.stateMask & SWT.CTRL) != 0) {
            // Allow Ctrl+F1 to act locally as well as on the remote, because it is typically non-intrusive
            event.doit = true;
          }
          sendString("\u001b[M");
          break;
        case 0x100000b: // F2 key.
          sendString("\u001b[N");
          break;
        case 0x100000c: // F3 key.
          sendString("\u001b[O");
          break;
        case 0x100000d: // F4 key.
          sendString("\u001b[P");
          break;
        case 0x100000e: // F5 key.
          sendString("\u001b[Q");
          break;
        case 0x100000f: // F6 key.
          sendString("\u001b[R");
          break;
        case 0x1000010: // F7 key.
          sendString("\u001b[S");
          break;
        case 0x1000011: // F8 key.
          sendString("\u001b[T");
          break;
        case 0x1000012: // F9 key.
          sendString("\u001b[U");
          break;
        case 0x1000013: // F10 key.
          sendString("\u001b[V");
          break;
        case 0x1000014: // F11 key.
          sendString("\u001b[W");
          break;
        case 0x1000015: // F12 key.
          sendString("\u001b[X");
          break;
        default:
          // Ignore other special keys. Control flows through this case when the user presses SHIFT, CONTROL, ALT, and
          // any other key not handled by the above cases.
          break;
        }
        // It's ok to return here, because we never locally echo special keys.
        return;
      }
      // To fix SPR 110341, we consider the Alt key to be pressed only when the Control key is _not_ also pressed. This
      // works around a bug in SWT where, on European keyboards, the AltGr key being pressed appears to us as Control
      // + Alt being pressed simultaneously.
      Logger.log("stateMask = " + event.stateMask);
      boolean altKeyPressed = (((event.stateMask & SWT.ALT) != 0) && ((event.stateMask & SWT.CTRL) == 0));
      if (!altKeyPressed && (event.stateMask & SWT.CTRL) != 0 && character == ' ') {
        // Send a NUL character -- many terminal emulators send NUL when Control-Space is pressed. This is used to set
        // the mark in Emacs.
        character = '\u0000';
      }
      sendChar(character, altKeyPressed);
      // Special case: When we are in a TCP connection and echoing characters locally, send a LF after sending a CR.
      // ISSUE: Is this absolutely required?
      if (character == '\r' && getTerminalConnector() != null && isConnected() && getTerminalConnector().isLocalEcho()) {
        sendChar('\n', false);
      }
      // Now decide if we should locally echo the character we just sent. We do _not_ locally echo the character if any
      // of these conditions are true:
      //
      // * This is a serial connection.
      // * This is a TCP connection (i.e., m_telnetConnection is not null) and the remote endpoint is not a TELNET
      //   server.
      // * The ALT (or META) key is pressed.
      // * The character is any of the first 32 ISO Latin-1 characters except Control-I or Control-M.
      // * The character is the DELETE character.
      if (getTerminalConnector() == null || getTerminalConnector().isLocalEcho() == false || altKeyPressed
          || (character >= '\u0001' && character < '\t') || (character > '\t' && character < '\r')
          || (character > '\r' && character <= '\u001f') || character == '\u007f') {
        // No local echoing.
        return;
      }
      // Locally echo the character.
      StringBuilder charBuffer = new StringBuilder();
      charBuffer.append(character);
      // If the character is a carriage return, we locally echo it as a CR + LF combination.
      if (character == '\r') {
        charBuffer.append('\n');
      }
      writeToTerminal(charBuffer.toString());
    }
  }

  @Override public void setTerminalTitle(String title) {
    terminalListener.setTerminalTitle(title);
  }

  @Override public TerminalState getState() {
    return state;
  }

  @Override public void setState(TerminalState state) {
    this.state = state;
    terminalListener.setState(state);
    // enable the (blinking) cursor if the terminal is connected
    runAsyncInDisplayThread(new Runnable() {
      @Override public void run() {
        if (textControl != null && !textControl.isDisposed()) {
          textControl.setCursorEnabled(isConnected());
        }
      }
    });
  }

  private void runAsyncInDisplayThread(Runnable runnable) {
    if (Display.findDisplay(Thread.currentThread()) != null) {
      runnable.run();
    } else if (PlatformUI.isWorkbenchRunning()) {
      PlatformUI.getWorkbench().getDisplay().asyncExec(runnable);
      // else should not happen and we ignore it...
    }
  }

  @Override public String getSettingsSummary() {
    if (getTerminalConnector() != null) {
      return getTerminalConnector().getSettingsSummary();
    }
    return "";
  }

  @Override public void setConnector(ITerminalConnector connector) {
    this.connector = connector;
  }

  @Override public ICommandInputField getCommandInputField() {
    return commandInputField;
  }

  @Override public void setCommandInputField(ICommandInputField inputField) {
    if (commandInputField != null) {
      commandInputField.dispose();
    }
    commandInputField = inputField;
    if (commandInputField != null) {
      commandInputField.createControl(rootControl, this);
    }
    if (rootControl.isVisible()) {
      rootControl.layout(true);
    }
  }

  @Override public int getBufferLineLimit() {
    return terminalModel.getMaxHeight();
  }

  @Override public void setBufferLineLimit(int bufferLineLimit) {
    if (bufferLineLimit <= 0) {
      return;
    }
    synchronized (terminalModel) {
      if (terminalModel.getHeight() > bufferLineLimit) {
        terminalModel.setDimensions(bufferLineLimit, terminalModel.getWidth());
      }
      terminalModel.setMaxHeight(bufferLineLimit);
    }
  }

  @Override public boolean isScrollLockOn() {
    return textControl.isScrollLockOn();
  }

  @Override public void setScrollLockOn(boolean on) {
    textControl.setScrollLockOn(on);
  }

  @Override public void setInvertedColors(boolean invert) {
    textControl.setInvertedColors(invert);
  }

  @Override
  public void setColors(RGB background, RGB foreground) {
    textControl.setColors(background, foreground);
  }

  @Override
  public void setBlinkingCursor(boolean useBlinkingCursor) {
    textControl.setBlinkingCursor(useBlinkingCursor);
  }
}
