/*******************************************************************************
 * Copyright (c) 2007, 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.tm.internal.terminal.emulator;

import static java.util.Collections.emptyList;

import java.util.*;

import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.hyperlink.IHyperlink;

import com.google.eclipse.tm.internal.terminal.hyperlink.*;
import com.google.eclipse.tm.terminal.model.*;

public class VT100EmulatorBackend implements IVT100EmulatorBackend {
  // This field holds the number of the column in which the cursor is logically positioned. The left-most column on the
  // screen is column 0, and column numbers increase to the right. The maximum value of this field is
  // widthInColumns - 1. We track the cursor column using this field to avoid having to recompute it repeatly using
  // StyledText method calls.
  //
  // The StyledText widget that displays text has a vertical bar (called the "caret") that appears _between_ character
  // cells, but ANSI terminals have the concept of a cursor that appears _in_ a character cell, so we need a convention
  // for which character cell the cursor logically occupies when the caret is physically between two cells. The
  // convention used in this class is that the cursor is logically in column N when the caret is physically positioned
  // immediately to the _left_ of column N.
  //
  // When cursorColumn is N, the next character output to the terminal appears in column N. When a character is output
  // to the rightmost column on a given line (column widthInColumns - 1), the cursor moves to column 0 on the next line
  // after the character is drawn (this is how line wrapping is implemented). If the cursor is in the bottom-most line
  // when line wrapping occurs, the topmost visible line is scrolled off the top edge of the screen.
  private int cursorColumn;

  private int cursorLine;
  private Style defaultStyle;
  private Style style;
  private int lines;
  private int columns;

  private final ITerminalTextData terminal;

  private final IHyperlinkFactory httpHyperlinkFactory = new HttpHyperlinkFactory();
  private final Map<Integer, List<IHyperlink>> hyperlinks = new HashMap<Integer, List<IHyperlink>>();

  public VT100EmulatorBackend(ITerminalTextData terminal) {
    this.terminal = terminal;
  }

  @Override public void clearAll() {
    synchronized (terminal) {
      // clear the history
      int n = terminal.getHeight();
      for (int line = 0; line < n; line++) {
        terminal.cleanLine(line);
      }
      terminal.setDimensions(lines, terminal.getWidth());
      setStyle(getDefaultStyle());
      setCursor(0, 0);
    }
  }

  @Override public void setDimensions(int lines, int columns) {
    synchronized (terminal) {
      if (lines == this.lines && columns == this.columns) {
        return; // nothing to do
      }
      // relative cursor line
      int cursorLine = getCursorLine();
      int cursorColumn = getCursorColumn();
      int height = terminal.getHeight();
      // absolute cursor line
      int absoluteCursorLine = cursorLine + height - this.lines;
      int newLines = Math.max(lines, height);
      if (lines < this.lines) {
        if (height == this.lines) {
          // if the terminal has no history, then resize by setting the size to the new size.
          // TODO We are assuming that cursor line points at end of text.
          newLines = Math.max(lines, cursorLine + 1);
        }
      }
      this.lines = lines;
      this.columns = columns;
      // Make the terminal at least as high as we need lines.
      terminal.setDimensions(newLines, this.columns);
      // Compute relative cursor line.
      cursorLine = absoluteCursorLine - (newLines - this.lines);
      setCursor(cursorLine, cursorColumn);
    }
  }

  int toAbsoluteLine(int line) {
    synchronized (terminal) {
      return terminal.getHeight() - this.lines + line;
    }
  }

  @Override public void insertCharacters(int charactersToInsert) {
    synchronized (terminal) {
      int line = toAbsoluteLine(cursorLine);
      int n = charactersToInsert;
      for (int column = columns - 1; column >= cursorColumn + n; column--) {
        char c = terminal.getChar(line, column - n);
        Style style = terminal.getStyle(line, column - n);
        terminal.setChar(line, column, c, style);
      }
      int last = Math.min(cursorColumn + n, columns);
      for (int col = cursorColumn; col < last; col++) {
        terminal.setChar(line, col, '\000', null);
      }
    }
  }

  @Override public void eraseToEndOfScreen() {
    synchronized (terminal) {
      eraseLineToEnd();
      for (int line = toAbsoluteLine(cursorLine + 1); line < toAbsoluteLine(lines); line++) {
        terminal.cleanLine(line);
      }
    }
  }

  @Override public void eraseToCursor() {
    synchronized (terminal) {
      for (int line = toAbsoluteLine(0); line < toAbsoluteLine(cursorLine); line++) {
        terminal.cleanLine(line);
      }
      eraseLineToCursor();
    }
  }

  @Override public void eraseAll() {
    synchronized (terminal) {
      for (int line = toAbsoluteLine(0); line < toAbsoluteLine(lines); line++) {
        terminal.cleanLine(line);
      }
    }
  }

  @Override public void eraseLine() {
    synchronized (terminal) {
      terminal.cleanLine(toAbsoluteLine(cursorLine));
    }
  }

  @Override public void eraseLineToEnd() {
    synchronized (terminal) {
      int line = toAbsoluteLine(cursorLine);
      for (int col = cursorColumn; col < columns; col++) {
        terminal.setChar(line, col, '\000', null);
      }
    }
  }

  @Override public void eraseLineToCursor() {
    synchronized (terminal) {
      int line = toAbsoluteLine(cursorLine);
      for (int col = 0; col <= cursorColumn; col++) {
        terminal.setChar(line, col, '\000', null);
      }
    }
  }

  @Override public void insertLines(int lineCount) {
    synchronized (terminal) {
      if (!isCursorInScrollingRegion()) {
        return;
      }
      Assert.isTrue(lineCount > 0);
      int line = toAbsoluteLine(cursorLine);
      int nLines = terminal.getHeight() - line;
      terminal.scroll(line, nLines, lineCount);
    }
  }

  @Override public void deleteCharacters(int charCount) {
    synchronized (terminal) {
      int line = toAbsoluteLine(cursorLine);
      for (int col = cursorColumn + charCount; col < columns; col++) {
        char c = terminal.getChar(line, col);
        Style style = terminal.getStyle(line, col);
        terminal.setChar(line, col - charCount, c, style);
      }
      int first = Math.max(cursorColumn, columns - charCount);
      for (int col = first; col < columns; col++) {
        terminal.setChar(line, col, '\000', null);
      }
    }
  }

  @Override public void deleteLines(int lineCount) {
    synchronized (terminal) {
      if (!isCursorInScrollingRegion()) {
        return;
      }
      Assert.isTrue(lineCount > 0);
      int line = toAbsoluteLine(cursorLine);
      int currentLineCount = terminal.getHeight() - line;
      terminal.scroll(line, currentLineCount, -lineCount);
    }
  }

  private boolean isCursorInScrollingRegion() {
    return true;
  }

  @Override public Style getDefaultStyle() {
    synchronized (terminal) {
      return defaultStyle;
    }
  }

  @Override public void setDefaultStyle(Style defaultStyle) {
    synchronized (terminal) {
      this.defaultStyle = defaultStyle;
    }
  }

  @Override public Style getStyle() {
    synchronized (terminal) {
      if (style == null) {
        return defaultStyle;
      }
      return style;
    }
  }

  @Override public void setStyle(Style style) {
    synchronized (terminal) {
      this.style = style;
    }
  }

  @Override public void appendString(String buffer) {
    synchronized (terminal) {
      char[] chars = buffer.toCharArray();
      int line = toAbsoluteLine(cursorLine);
      int originalLine = line;
      List<IHyperlink> found = emptyList();
      if (buffer != null) {
        found = httpHyperlinkFactory.hyperlinksIn(cursorColumn, buffer);
        hyperlinks.put(new Integer(line), found);
      }
      int i = 0;
      while (i < chars.length) {
        int n = Math.min(columns - cursorColumn, chars.length - i);
        terminal.setChars(line, cursorColumn, chars, i, n, style);
        int col = cursorColumn + n;
        i += n;
        // wrap needed?
        if (col >= columns) {
          doNewline();
          line = toAbsoluteLine(cursorLine);
          setCursorColumn(0);
        } else {
          setCursorColumn(col);
        }
      }
      drawHyperlinks(found, originalLine);
    }
  }

  private void drawHyperlinks(List<IHyperlink> hyperlinks, int line) {
    for (IHyperlink hyperlink : hyperlinks) {
      IRegion region = hyperlink.getHyperlinkRegion();
      int start = region.getOffset();
      int end = start + region.getLength();
      for (int column = start; column < end; column++) {
        Style style = terminal.getStyle(line, column);
        if (style != null) {
          style = style.setUnderline(true);
          terminal.setChar(line, column, terminal.getChar(line, column), style);
        }
      }
    }
  }

  // MUST be called from a synchronized block!
  private void doNewline() {
    if (cursorLine + 1 >= lines) {
      int h = terminal.getHeight();
      terminal.addLine();
      if (h != terminal.getHeight()) {
        setCursorLine(cursorLine + 1);
      }
    } else {
      setCursorLine(cursorLine + 1);
    }
  }

  @Override public void processNewline() {
    synchronized (terminal) {
      doNewline();
    }
  }

  @Override public int getCursorLine() {
    synchronized (terminal) {
      return cursorLine;
    }
  }

  @Override public int getCursorColumn() {
    synchronized (terminal) {
      return cursorColumn;
    }
  }

  @Override public void setCursor(int targetLine, int targetColumn) {
    synchronized (terminal) {
      setCursorLine(targetLine);
      setCursorColumn(targetColumn);
    }
  }

  @Override public void setCursorColumn(int targetColumn) {
    synchronized (terminal) {
      if (targetColumn < 0) {
        targetColumn = 0;
      } else if (targetColumn >= columns) {
        targetColumn = columns - 1;
      }
      cursorColumn = targetColumn;
      // We make the assumption that nobody is changing the
      // terminal cursor except this class!
      // This assumption gives a huge performance improvement
      terminal.setCursorColumn(targetColumn);
    }
  }

  @Override public void setCursorLine(int targetLine) {
    synchronized (terminal) {
      if (targetLine < 0) {
        targetLine = 0;
      } else if (targetLine >= lines) {
        targetLine = lines - 1;
      }
      cursorLine = targetLine;
      // We make the assumption that nobody is changing the terminal cursor except this class!
      // This assumption gives a huge performance improvement.
      terminal.setCursorLine(toAbsoluteLine(targetLine));
    }
  }

  @Override public int getLines() {
    synchronized (terminal) {
      return lines;
    }
  }

  @Override public int getColumns() {
    synchronized (terminal) {
      return columns;
    }
  }

  @Override public List<IHyperlink> hyperlinksAt(int line) {
    List<IHyperlink> found = hyperlinks.get(new Integer(line));
    if (found == null) {
      return emptyList();
    }
    return found;
  }
}