/*******************************************************************************
 * Copyright (c) 2007, 2010 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.textcanvas;

import java.util.*;

import org.eclipse.core.runtime.Assert;
import org.eclipse.swt.graphics.Point;

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

public abstract class AbstractTextCanvasModel implements ITextCanvasModel {
  private final List<ITextCanvasModelListener> listeners = new ArrayList<ITextCanvasModelListener>();
  private final Point selectionAnchor = new Point(0, 0);

  private final ITerminalTextDataSnapshot snapshot;

  private int cursorLine;
  private int cursorColumn;
  private boolean showCursor;
  private long cursorTime;
  private boolean cursorIsEnabled;
  private int lines;

  private int selectionStartLine = -1;
  private int seletionEndLine;
  private int selectionStartCoumn;
  private int selectionEndColumn;
  private ITerminalTextDataSnapshot selectionSnapshot;
  private String currentSelection = "";

  // do not update while update is running
  boolean inUpdate;

  private int columns;
  private boolean useBlinkingCursor;

  public AbstractTextCanvasModel(ITerminalTextDataSnapshot snapshot) {
    this.snapshot = snapshot;
    lines = this.snapshot.getHeight();
  }

  @Override public void addCellCanvasModelListener(ITextCanvasModelListener listener) {
    listeners.add(listener);
  }

  @Override public void removeCellCanvasModelListener(ITextCanvasModelListener listener) {
    listeners.remove(listener);
  }

  private void fireCellRangeChanged(int x, int y, int width, int height) {
    for (ITextCanvasModelListener listener : listeners) {
      listener.rangeChanged(x, y, width, height);
    }
  }

  private void fireDimensionsChanged(int width, int height) {
    for (ITextCanvasModelListener listener : listeners) {
      listener.dimensionsChanged(width, height);
    }
  }

  private void fireTerminalDataChanged() {
    for (ITextCanvasModelListener listener : listeners) {
      listener.terminalDataChanged();
    }
  }

  @Override public ITerminalTextDataReadOnly getTerminalText() {
    return snapshot;
  }

  protected ITerminalTextDataSnapshot getSnapshot() {
    return snapshot;
  }

  private void updateSnapshot() {
    if (!inUpdate && snapshot.isOutOfDate()) {
      inUpdate = true;
      try {
        snapshot.updateSnapshot(false);
        if (snapshot.hasTerminalChanged()) {
          fireTerminalDataChanged();
        }
        // TODO why does hasDimensionsChanged not work?
        // if (snapshot.hasDimensionsChanged()) fireDimensionsChanged();
        if (lines != snapshot.getHeight() || columns != snapshot.getWidth()) {
          fireDimensionsChanged(snapshot.getWidth(), snapshot.getHeight());
          lines = snapshot.getHeight();
          columns = snapshot.getWidth();
        }
        int y = snapshot.getFirstChangedLine();
        // has any line changed?
        if (y < Integer.MAX_VALUE) {
          int height = snapshot.getLastChangedLine() - y + 1;
          fireCellRangeChanged(0, y, snapshot.getWidth(), height);
        }
      } finally {
        inUpdate = false;
      }
    }
  }

  /**
   * This method must be called from the UI thread.
   */
  public void update() {
    updateSnapshot();
    updateSelection();
    updateCursor();
  }

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

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

  @Override public boolean isCursorOn() {
    return showCursor && cursorIsEnabled;
  }

  @Override public void setBlinkingCursor(boolean useBlinkingCursor) {
    this.useBlinkingCursor = useBlinkingCursor;
    updateCursor();
  }

  // TODO: should be called regularly to draw an update of the blinking cursor?
  private void updateCursor() {
    if (!cursorIsEnabled) {
      return;
    }
    int cursorLine = getSnapshot().getCursorLine();
    int cursorColumn = getSnapshot().getCursorColumn();
    // If cursor at the end put it to the end of the last line.
    if (cursorLine >= getSnapshot().getHeight()) {
      cursorLine = getSnapshot().getHeight() - 1;
      cursorColumn = getSnapshot().getWidth() - 1;
    }
    // Has the cursor moved?
    if (this.cursorLine != cursorLine || this.cursorColumn != cursorColumn) {
      // Hide the old cursor!
      showCursor = false;
      // Clean the previous cursor. Bug 206363: paint also the char to the left and right of the cursor
      int col = this.cursorColumn;
      int width = 2;
      if (col > 0) {
        col--;
        width++;
      }
      fireCellRangeChanged(col, this.cursorLine, width, 1);
      // The cursor is shown when it moves.
      showCursor = true;
      cursorTime = System.currentTimeMillis();
      this.cursorLine = cursorLine;
      this.cursorColumn = cursorColumn;
      // Draw the new cursor
      fireCellRangeChanged(this.cursorColumn, this.cursorLine, 1, 1);
    } else {
      if (useBlinkingCursor) {
        long time = System.currentTimeMillis();
        // TODO Make the cursor blink time customizable.
        if (time - cursorTime > 500) {
          showCursor = !showCursor;
          cursorTime = time;
          // On some windows machines, there is some leftover when updating the cursor.
          // https://bugs.eclipse.org/bugs/show_bug.cgi?id=206363
          int col = this.cursorColumn;
          int width = 2;
          if (col > 0) {
            col--;
            width++;
          }
          fireCellRangeChanged(col, this.cursorLine, width, 1);
        }
      }
    }
  }

  @Override public void setVisibleRectangle(int startLine, int startCol, int height, int width) {
    snapshot.setInterestWindow(Math.max(0, startLine), Math.max(1, height));
    update();
  }

  protected void showCursor(boolean show) {
    showCursor = true;
  }

  @Override public void setCursorEnabled(boolean visible) {
    cursorTime = System.currentTimeMillis();
    showCursor = visible;
    cursorIsEnabled = visible;
    fireCellRangeChanged(cursorColumn, cursorLine, 1, 1);
  }

  @Override public boolean isCursorEnabled() {
    return cursorIsEnabled;
  }

  @Override public Point getSelectionEnd() {
    if (selectionStartLine < 0) {
      return null;
    }
    return new Point(selectionEndColumn, seletionEndLine);
  }

  @Override public Point getSelectionStart() {
    if (selectionStartLine < 0) {
      return null;
    }
    return new Point(selectionStartCoumn, selectionStartLine);
  }

  @Override public Point getSelectionAnchor() {
    if (selectionStartLine < 0) {
      return null;
    }
    return new Point(selectionAnchor.x, selectionAnchor.y);
  }

  @Override public void setSelectionAnchor(Point anchor) {
    selectionAnchor.x = anchor.x;
    selectionAnchor.y = anchor.y;
  }

  @Override public void setSelection(int startLine, int endLine, int startColumn, int endColumn) {
    doSetSelection(startLine, endLine, startColumn, endColumn);
    currentSelection = extractSelectedText();
  }

  private void doSetSelection(int startLine, int endLine, int startColumn, int endColumn) {
    Assert.isTrue(startLine < 0 || startLine <= endLine);
    if (startLine >= 0) {
      if (selectionSnapshot == null) {
        selectionSnapshot = snapshot.getTerminalTextData().makeSnapshot();
        selectionSnapshot.updateSnapshot(true);
      }
    } else if (selectionSnapshot != null) {
      selectionSnapshot.detach();
      selectionSnapshot = null;
    }
    int oldStart = selectionStartLine;
    int oldEnd = seletionEndLine;
    selectionStartLine = startLine;
    seletionEndLine = endLine;
    selectionStartCoumn = startColumn;
    selectionEndColumn = endColumn;
    if (selectionSnapshot != null) {
      selectionSnapshot.setInterestWindow(0, selectionSnapshot.getHeight());
    }
    int changedStart;
    int changedEnd;
    if (oldStart < 0) {
      changedStart = selectionStartLine;
      changedEnd = seletionEndLine;
    } else if (selectionStartLine < 0) {
      changedStart = oldStart;
      changedEnd = oldEnd;
    } else {
      changedStart = Math.min(oldStart, selectionStartLine);
      changedEnd = Math.max(oldEnd, seletionEndLine);
    }
    if (changedStart >= 0) {
      fireCellRangeChanged(0, changedStart, snapshot.getWidth(), changedEnd - changedStart + 1);
    }
  }

  @Override public boolean hasLineSelection(int line) {
    if (selectionStartLine < 0) {
      return false;
    }
    return line >= selectionStartLine && line <= seletionEndLine;
  }

  @Override public String getSelectedText() {
    return currentSelection;
  }

  /**
   * Calculates the currently selected text
   * @return the currently selected text
   */
  private String extractSelectedText() {
    if (selectionStartLine < 0 || selectionStartCoumn < 0 || selectionSnapshot == null) {
      return "";
    }
    StringBuilder buffer = new StringBuilder();
    for (int line = selectionStartLine; line <= seletionEndLine; line++) {
      String text;
      char[] chars = selectionSnapshot.getChars(line);
      if (chars != null) {
        text = new String(chars);
        if (line == seletionEndLine && selectionEndColumn >= 0) {
          text = text.substring(0, Math.min(selectionEndColumn + 1, text.length()));
        }
        if (line == selectionStartLine) {
          text = text.substring(Math.min(selectionStartCoumn, text.length()));
        }
        // get rid of the empty space at the end of the lines
        text = text.replaceAll("\000+$","");
        // null means space
        text = text.replace('\000', ' ');
      } else {
        text = "";
      }
      buffer.append(text);
      if (line < seletionEndLine) {
        buffer.append('\n');
      }
    }
    return buffer.toString();
  }

  private void updateSelection() {
    if (selectionSnapshot != null && selectionSnapshot.isOutOfDate()) {
      selectionSnapshot.updateSnapshot(true);
      // Has the selection moved?
      if (selectionSnapshot != null && selectionStartLine >= 0 && selectionSnapshot.getScrollWindowSize() > 0) {
        int start = selectionStartLine + selectionSnapshot.getScrollWindowShift();
        int end = seletionEndLine + selectionSnapshot.getScrollWindowShift();
        if (start < 0) {
          if (end >= 0) {
            start = 0;
          } else {
            start = -1;
          }
        }
        doSetSelection(start, end, selectionStartCoumn, selectionEndColumn);
      }
      // Check if the content of the selection has changed. If the content has changed, clear the selection.
      if (currentSelection.length() > 0 && selectionSnapshot != null
          && selectionSnapshot.getFirstChangedLine() <= seletionEndLine
          && selectionSnapshot.getLastChangedLine() >= selectionStartLine) {
        // Has the selected text changed?
        if (!currentSelection.equals(extractSelectedText())) {
          setSelection(-1, -1, -1, -1);
        }
      }
      // Update the observed window...
      if (selectionSnapshot != null) {
        // TODO make -1 to work!
        selectionSnapshot.setInterestWindow(0, selectionSnapshot.getHeight());
      }
    }
  }
}