/*******************************************************************************
 * 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.elt.emulator.textcanvas;

import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.Composite;

/**
 * A cell oriented Canvas. Maintains a list of "cells". It can either be vertically or horizontally scrolled. The
 * CellRenderer is responsible for painting the cell.
 */
public class TextCanvas extends GridCanvas {
  private final ITextCanvasModel cellCanvasModel;
  private final ILinelRenderer cellRenderer;
  private boolean scrollLockOn;
  private Point draggingStart;
  private Point draggingEnd;
  private boolean hasSelection;
  private ResizeListener resizeListener;

  // The minSize is meant to determine the minimum size of the backing store (grid) into which remote data is rendered.
  // If the viewport is smaller than that minimum size, the backing store size remains at the minSize,and a scrollbar is
  // shown instead. In reality, this has the following issues or effects today:
  //
  // (a) Bug 281328: For very early data coming in before the widget is realized, the minSize determines into what
  // initial grid that is rendered. See also {@link #addResizeHandler(ResizeListener)}.
  //
  // (b) Bug 294468: Since we have redraw and size computation problems with horizontal scrollers, for now the
  // minColumns must be small enough to avoid a horizontal scroller appearing in most cases.
  //
  // (c) Bug 294327: Since we have problems with the vertical scroller showing the correct location, minLines must be
  // small enough to avoid a vertical scroller or new data may be rendered off-screen.
  //
  // As a compromise, we have been working with a 20x4 since the terminal inception, though many users would want a
  // 80x24 minSize and backing store.

  // Pros and cons of the small minsize:
  // + consistent "remote size==viewport size", vi works as expected
  // - dumb terminals which expect 80x24 render garbled on small viewport
  //
  // If bug 294468 were resolved, an 80 wide minSize would be preferrable since it allows switching the terminal
  // viewport small/large as needed, without destroying the backing store. For a complete solution, bug 196462 tracks
  // the request for a user-defined fixed-widow-size-mode.
  private int minColumns = 80;

  private int minLines = 4;
  private boolean cursorEnabled;
  private boolean resizing;

  /**
   * Create a new CellCanvas with the given SWT style bits. (SWT.H_SCROLL and SWT.V_SCROLL are automatically added).
   */
  public TextCanvas(Composite parent, ITextCanvasModel model, int style, ILinelRenderer cellRenderer) {
    super(parent, style | SWT.H_SCROLL | SWT.V_SCROLL);
    this.cellRenderer = cellRenderer;
    setCellWidth(cellRenderer.getCellWidth());
    setCellHeight(cellRenderer.getCellHeight());
    cellCanvasModel = model;
    cellCanvasModel.addCellCanvasModelListener(new ITextCanvasModelListener() {
      @Override public void rangeChanged(int col, int line, int width, int height) {
        repaintRange(col, line, width, height);
      }

      @Override public void dimensionsChanged(int cols, int rows) {
        calculateGrid();
      }

      @Override public void terminalDataChanged() {
        if (!isDisposed() && !resizing) {
          // scroll to end (unless scroll lock is active)
          calculateGrid();
          scrollToEnd();
        }
      }
    });
    // let the cursor blink if the text canvas gets the focus...
    addFocusListener(new FocusListener() {
      @Override public void focusGained(FocusEvent e) {
        cellCanvasModel.setCursorEnabled(cursorEnabled);
      }

      @Override public void focusLost(FocusEvent e) {
        cellCanvasModel.setCursorEnabled(false);
      }
    });
    addMouseListener(new MouseAdapter() {
      @Override public void mouseDown(MouseEvent e) {
        if (e.button == 1) { // left button
          draggingStart = screenPointToCell(e.x, e.y);
          hasSelection = false;
          if ((e.stateMask & SWT.SHIFT) != 0) {
            Point anchor = cellCanvasModel.getSelectionAnchor();
            if (anchor != null) {
              draggingStart = anchor;
            }
          } else {
            cellCanvasModel.setSelectionAnchor(draggingStart);
          }
          draggingEnd = null;
        }
      }

      @Override public void mouseUp(MouseEvent e) {
        if (e.button == 1) { // left button
          updateHasSelection(e);
          if (hasSelection) {
            setSelection(screenPointToCell(e.x, e.y));
          } else {
            cellCanvasModel.setSelection(-1, -1, -1, -1);
          }
          draggingStart = null;
        }
      }
    });
    addMouseMoveListener(new MouseMoveListener() {
      @Override public void mouseMove(MouseEvent e) {
        if (draggingStart != null) {
          updateHasSelection(e);
          setSelection(screenPointToCell(e.x, e.y));
        }
      }
    });
    serVerticalBarVisible(true);
    setHorizontalBarVisible(false);
  }

  // The user has to drag the mouse to at least one character to make a selection. Once this is done, even a one char
  // selection is OK.
  private void updateHasSelection(MouseEvent e) {
    if (draggingStart != null) {
      Point p = screenPointToCell(e.x, e.y);
      if (draggingStart.x != p.x || draggingStart.y != p.y) {
        hasSelection = true;
      }
    }
  }

  void setSelection(Point p) {
    if (draggingStart != null && !p.equals(draggingEnd)) {
      draggingEnd = p;
      if (compare(p, draggingStart) < 0) {
        // bug 219589 - make sure selection start coordinates are non-negative
        int startColumn = Math.max(0, p.x);
        int startRow = Math.max(p.y, 0);
        cellCanvasModel.setSelection(startRow, draggingStart.y, startColumn, draggingStart.x);
      } else {
        cellCanvasModel.setSelection(draggingStart.y, p.y, draggingStart.x, p.x);
      }
    }
  }

  int compare(Point p1, Point p2) {
    if (p1.equals(p2)) {
      return 0;
    }
    if (p1.y == p2.y) {
      return p1.x > p2.x ? 1 : -1;
    }
    return p1.y > p2.y ? 1 : -1;
  }

  public ILinelRenderer getCellRenderer() {
    return cellRenderer;
  }

  public int getMinColumns() {
    return minColumns;
  }

  public void setMinColumns(int minColumns) {
    this.minColumns = minColumns;
  }

  public int getMinLines() {
    return minLines;
  }

  public void setMinLines(int minLines) {
    this.minLines = minLines;
  }

  protected void onResize(boolean init) {
    if (resizeListener != null) {
      Rectangle bonds = getClientArea();
      int cellHeight = getCellHeight();
      int cellWidth = getCellWidth();
      int lines = bonds.height / cellHeight;
      int columns = bonds.width / cellWidth;
      // When the view is minimized, its size is set to 0 we don't sent this to the terminal!
      if ((lines > 0 && columns > 0) || init) {
        if (columns < minColumns) {
          if (!isHorizontalBarVisble()) {
            setHorizontalBarVisible(true);
            bonds = getClientArea();
            lines = bonds.height / cellHeight;
          }
          columns = minColumns;
        } else if (columns >= minColumns && isHorizontalBarVisble()) {
          setHorizontalBarVisible(false);
          bonds = getClientArea();
          lines = bonds.height / cellHeight;
          columns = bonds.width / cellWidth;
        }
        if (lines < minLines) {
          lines = minLines;
        }
        resizeListener.sizeChanged(lines, columns);
      }
    }
    super.onResize();
    calculateGrid();
  }

  @Override protected void onResize() {
    resizing = true;
    try {
      onResize(false);
    } finally {
      resizing = false;
    }
  }

  private void calculateGrid() {
    Rectangle virtualBounds = getVirtualBounds();
    setRedraw(false);
    try {
      setVirtualExtend(getCols() * getCellWidth(), getRows() * getCellHeight());
      getParent().layout();
      if (resizing) {
        // scroll to end if view port was near last line
        Rectangle viewRect = getViewRectangle();
        if (virtualBounds.height - (viewRect.y + viewRect.height) < getCellHeight() * 2) {
          scrollToEnd();
        }
      }
    } finally {
      setRedraw(true);
    }
  }

  void scrollToEnd() {
    if (!scrollLockOn) {
      int y = -(getRows() * getCellHeight() - getClientArea().height);
      if (y > 0) {
        y = 0;
      }
      Rectangle v = getViewRectangle();
      if (v.y != -y) {
        setVirtualOrigin(v.x, y);
      }
      // make sure the scroll area is correct.
      scrollY(getVerticalBar());
      scrollX(getHorizontalBar());
    }
  }

  public boolean isScrollLockOn() {
    return scrollLockOn;
  }

  public void setScrollLockOn(boolean on) {
    scrollLockOn = on;
  }

  protected void repaintRange(int col, int line, int width, int height) {
    Point origin = cellToOriginOnScreen(col, line);
    Rectangle r = new Rectangle(origin.x, origin.y, width * getCellWidth(), height * getCellHeight());
    repaint(r);
  }

  @Override protected void drawLine(GC gc, int line, int x, int y, int colFirst, int colLast) {
    cellRenderer.drawLine(cellCanvasModel, gc, line, x, y, colFirst, colLast);
  }

  @Override protected Color getTerminalBackgroundColor() {
    return cellRenderer.getDefaultBackgroundColor();
  }

  @Override protected void visibleCellRectangleChanged(int x, int y, int width, int height) {
    cellCanvasModel.setVisibleRectangle(y, x, height, width);
    update();
  }

  @Override protected int getCols() {
    return cellCanvasModel.getTerminalText().getWidth();
  }

  @Override protected int getRows() {
    return cellCanvasModel.getTerminalText().getHeight();
  }

  public String getSelectionText() {
    // TODO -- create a hasSelectionMethod!
    return cellCanvasModel.getSelectedText();
  }

  public void copy() {
    Clipboard clipboard = new Clipboard(getDisplay());
    clipboard.setContents(new Object[] { getSelectionText() }, new Transfer[] { TextTransfer.getInstance() });
    clipboard.dispose();
  }

  public void selectAll() {
    cellCanvasModel.setSelection(
        0, cellCanvasModel.getTerminalText().getHeight(), 0, cellCanvasModel.getTerminalText().getWidth());
    cellCanvasModel.setSelectionAnchor(new Point(0, 0));
  }

  public boolean isEmpty() {
    return false;
  }

  /**
   * Gets notified when the visible size of the terminal changes. This should update the model!
   */
  public static interface ResizeListener {
    void sizeChanged(int lines, int columns);
  }

  public void addResizeHandler(ResizeListener listener) {
    if (resizeListener != null) {
      throw new IllegalArgumentException("There can be at most one listener at the moment!");
    }
    resizeListener = listener;
    // Bug 281328: The very first few characters might be missing in the terminal control if opened and connected
    // programmatically.
    //
    // In case the terminal had not been visible yet or is too small (less than one line visible), the terminal should
    // have a minimum size to avoid RuntimeExceptions.
    Rectangle bonds = getClientArea();
    if (bonds.height < getCellHeight() || bonds.width < getCellWidth()) {
      // Widget not realized yet, or minimized to < 1 item. Just tell the listener our min size.
      resizeListener.sizeChanged(getMinLines(), getMinColumns());
    } else {
      // Widget realized: compute actual size and force telling the listener
      onResize(true);
    }
  }

  public void onFontChange() {
    cellRenderer.onFontChange();
    setCellWidth(cellRenderer.getCellWidth());
    setCellHeight(cellRenderer.getCellHeight());
    calculateGrid();
  }

  public void setInvertedColors(boolean invert) {
    cellRenderer.setInvertedColors(invert);
    redraw();
  }

  /**
   * Indicates whether the cursor is enabled (blinking.) By default the cursor is not enabled.
   *
   * @return {@code true} if the cursor is enabled, {@code false} otherwise.
   */
  public boolean isCursorEnabled() {
    return cursorEnabled;
  }

  /**
   * Enables or disables the cursor (enabling means that the cursor blinks.)
   *
   * @param enabled indicates whether the cursor should be enabled.
   */
  public void setCursorEnabled(boolean enabled) {
    if (enabled != cursorEnabled) {
      cursorEnabled = enabled;
      cellCanvasModel.setCursorEnabled(cursorEnabled);
    }
  }

  public void setColors(RGB background, RGB foreground) {
    cellRenderer.setColors(background, foreground);
    redraw();
  }

  @Override public void setFont(Font font) {
    super.setFont(font);
    cellRenderer.setFont(font);
    redraw();
  }

  @Override public Point screenPointToCell(int x, int y) {
    return super.screenPointToCell(x, y);
  }

  public void setBlinkingCursor(boolean useBlinkingCursor) {
    cellCanvasModel.setBlinkingCursor(useBlinkingCursor);
  }
}
