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

import static org.eclipse.core.runtime.IStatus.*;

import org.eclipse.core.runtime.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;

import com.google.eclipse.elt.emulator.impl.TerminalPlugin;

/**
 * A {@code Canvas} showing a virtual object. Virtual: the extent of the total canvas. Screen: the visible client area
 * in the screen.
 */
public abstract class VirtualCanvas extends Canvas {
  private final Rectangle virtualBounds = new Rectangle(0, 0, 0, 0);

  /** Called when the viewed part is changing. */
  private final Rectangle viewRectangle = new Rectangle(0, 0, 0, 0);

  private Rectangle clientArea;

   /** Prevent infinite loop in {@link #updateScrollbars()} */
  private boolean inUpdateScrollbars;

  private static boolean inUpdateScrollbarsLogged;

  public VirtualCanvas(Composite parent, int style) {
    super(parent, style | SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE);
    clientArea = getClientArea();
    addListener(SWT.Paint, new Listener() {
      @Override public void handleEvent(Event event) {
        paint(event.gc);
      }
    });
    addListener(SWT.Resize, new Listener() {
      @Override public void handleEvent(Event event) {
        clientArea = getClientArea();
        onResize();
      }
    });
    getVerticalBar().addListener(SWT.Selection, new Listener() {
      @Override public void handleEvent(Event e) {
        scrollY((ScrollBar) e.widget);
      }
    });
    getHorizontalBar().addListener(SWT.Selection, new Listener() {
      @Override public void handleEvent(Event e) {
        scrollX((ScrollBar) e.widget);
      }
    });
  }

  protected void onResize() {
    updateViewRectangle();
  }

  protected void scrollX(ScrollBar horizontalBar) {
    int selection = horizontalBar.getSelection();
    int destinationX = -selection - virtualBounds.x;
    virtualBounds.x = -selection;
    scrollSmart(destinationX, 0);
    updateViewRectangle();
  }

  protected void scrollXDelta(int delta) {
    getHorizontalBar().setSelection(-virtualBounds.x + delta);
    scrollX(getHorizontalBar());
  }

  protected void scrollY(ScrollBar vBar) {
    int vSelection = vBar.getSelection();
    int destY = -vSelection - virtualBounds.y;
    if (destY != 0) {
      virtualBounds.y = -vSelection;
      scrollSmart(0, destY);
      updateViewRectangle();
    }
  }

  protected void scrollYDelta(int delta) {
    getVerticalBar().setSelection(-virtualBounds.y + delta);
    scrollY(getVerticalBar());
  }

  protected void scrollSmart(int deltaX, int deltaY) {
    if (deltaX != 0 || deltaY != 0) {
      Rectangle rect = getBounds();
      scroll(deltaX, deltaY, 0, 0, rect.width, rect.height, false);
    }
  }

  protected void revealRect(Rectangle rect) {
    Rectangle visibleRect = getScreenRectInVirtualSpace();
    // scroll the X part
    int deltaX = 0;
    if (rect.x < visibleRect.x) {
      deltaX = rect.x - visibleRect.x;
    } else if (visibleRect.x + visibleRect.width < rect.x + rect.width) {
      deltaX = (rect.x + rect.width) - (visibleRect.x + visibleRect.width);
    }
    if (deltaX != 0) {
      getHorizontalBar().setSelection(-virtualBounds.x + deltaX);
      scrollX(getHorizontalBar());
    }
    // scroll the Y part
    int deltaY = 0;
    if (rect.y < visibleRect.y) {
      deltaY = rect.y - visibleRect.y;
    } else if (visibleRect.y + visibleRect.height < rect.y + rect.height) {
      deltaY = (rect.y + rect.height) - (visibleRect.y + visibleRect.height);
    }
    if (deltaY != 0) {
      getVerticalBar().setSelection(-virtualBounds.y + deltaY);
      scrollY(getVerticalBar());
    }
  }

  protected void repaint(Rectangle r) {
    if (isDisposed()) {
      return;
    }
    if (inClipping(r, clientArea)) {
      redraw(r.x, r.y, r.width, r.height, true);
      update();
    }
  }

  abstract protected void paint(GC gc);

  protected Color getTerminalBackgroundColor() {
    return getDisplay().getSystemColor(SWT.COLOR_WIDGET_BACKGROUND);
  }

  protected void paintUnoccupiedSpace(GC gc, Rectangle clipping) {
    int width = virtualBounds.width + virtualBounds.x;
    int height = virtualBounds.height + virtualBounds.y;
    int marginWidth = (clipping.x + clipping.width) - width;
    int marginHeight = (clipping.y + clipping.height) - height;
    if (marginWidth > 0 || marginHeight > 0) {
      Color background = getBackground();
      gc.setBackground(getTerminalBackgroundColor());
      if (marginWidth > 0) {
        gc.fillRectangle(width, clipping.y, marginWidth, clipping.height);
      }
      if (marginHeight > 0) {
        gc.fillRectangle(clipping.x, height, clipping.width, marginHeight);
      }
      gc.setBackground(background);
    }
  }

  protected boolean inClipping(Rectangle clipping, Rectangle r) {
    // TODO check if this is OK in all cases (the <=!)
    if (r.x + r.width <= clipping.x) {
      return false;
    }
    if (clipping.x + clipping.width <= r.x) {
      return false;
    }
    if (r.y + r.height <= clipping.y) {
      return false;
    }
    if (clipping.y + clipping.height <= r.y) {
      return false;
    }
    return true;
  }

  protected Rectangle getScreenRectInVirtualSpace() {
    return new Rectangle(
        clientArea.x - virtualBounds.x, clientArea.y - virtualBounds.y, clientArea.width, clientArea.height);
  }

  protected Rectangle getRectInVirtualSpace(Rectangle r) {
    return new Rectangle(r.x - virtualBounds.x, r.y - virtualBounds.y, r.width, r.height);
  }

  protected void setVirtualExtend(int width, int height) {
    virtualBounds.width = width;
    virtualBounds.height = height;
    updateScrollbars();
    updateViewRectangle();
  }

  protected void setVirtualOrigin(int x, int y) {
    if (virtualBounds.x != x || virtualBounds.y != y) {
      virtualBounds.x = x;
      virtualBounds.y = y;
      getHorizontalBar().setSelection(-x);
      getVerticalBar().setSelection(-y);
      updateViewRectangle();
    }
  }

  protected Rectangle getVirtualBounds() {
    return cloneRectangle(virtualBounds);
  }

  protected int virtualXtoScreen(int x) {
    return x + virtualBounds.x;
  }

  protected int virtualYtoScreen(int y) {
    return y + virtualBounds.y;
  }

  protected int screenXtoVirtual(int x) {
    return x - virtualBounds.x;
  }

  protected int screenYtoVirtual(int y) {
    return y - virtualBounds.y;
  }

  protected void updateViewRectangle() {
    if (viewRectangle.x == -virtualBounds.x && viewRectangle.y == -virtualBounds.y
        && viewRectangle.width == clientArea.width && viewRectangle.height == clientArea.height) {
      return;
    }
    viewRectangle.x = -virtualBounds.x;
    viewRectangle.y = -virtualBounds.y;
    viewRectangle.width = clientArea.width;
    viewRectangle.height = clientArea.height;
    viewRectangleChanged(viewRectangle.x, viewRectangle.y, viewRectangle.width, viewRectangle.height);
  }

  protected Rectangle getViewRectangle() {
    return cloneRectangle(viewRectangle);
  }

  private Rectangle cloneRectangle(Rectangle r) {
    return new Rectangle(r.x, r.y, r.width, r.height);
  }

  protected void viewRectangleChanged(int x, int y, int width, int height) {}

  private void updateScrollbars() {
    // don't get into infinite loops....
    if (!inUpdateScrollbars) {
      inUpdateScrollbars = true;
      try {
        doUpdateScrollbar();
      } finally {
        inUpdateScrollbars = false;
      }
    } else {
      if (!inUpdateScrollbarsLogged) {
        inUpdateScrollbarsLogged = true;
        ILog logger = TerminalPlugin.getDefault().getLog();
        logger.log(new Status(WARNING, TerminalPlugin.PLUGIN_ID, OK, "Unexpected Recursion in terminal", null));
      }
    }
  }

  private void doUpdateScrollbar() {
    Rectangle clientArea = getClientArea();
    ScrollBar horizontal = getHorizontalBar();
    // Even if setVisible was called on the scrollbar, isVisible returns false if its parent is not visible.
    if (!isVisible() || horizontal.isVisible()) {
      horizontal.setPageIncrement(clientArea.width - horizontal.getIncrement());
      int max = virtualBounds.width;
      horizontal.setMaximum(max);
      horizontal.setThumb(clientArea.width);
    }
    ScrollBar vertical = getVerticalBar();
    // even if setVisible was called on the scrollbar, isVisible returns false if its parent is not visible.
    if (!isVisible() || vertical.isVisible()) {
      vertical.setPageIncrement(clientArea.height - vertical.getIncrement());
      int max = virtualBounds.height;
      vertical.setMaximum(max);
      vertical.setThumb(clientArea.height);
    }
  }

  protected boolean isVertialBarVisible() {
    return getVerticalBar().isVisible();
  }

  protected void serVerticalBarVisible(boolean showVScrollBar) {
    ScrollBar vertical = getVerticalBar();
    vertical.setVisible(showVScrollBar);
    vertical.setSelection(0);
  }

  protected boolean isHorizontalBarVisble() {
    return getHorizontalBar().isVisible();
  }

  protected void setHorizontalBarVisible(boolean showHScrollBar) {
    ScrollBar horizontal = getHorizontalBar();
    horizontal.setVisible(showHScrollBar);
    horizontal.setSelection(0);
  }
}
