/*******************************************************************************
 * 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 
 * 
 * Contributors: 
 * Michael Scharf (Wind River) - initial API and implementation
 * Anton Leherbauer (Wind River) - [294468] Fix scroller and text line rendering
 *******************************************************************************/
package org.eclipse.tm.internal.terminal.textcanvas;


import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.ScrollBar;

/**
 * A Grid based Canvas. The canvas has rows and columns.
 * CellPainting is done with the abstract method drawCell
 */
abstract public class GridCanvas extends VirtualCanvas {
	/** width of a cell */
	private int fCellWidth;
	/** height of a cell */
	private int fCellHeight;

	public GridCanvas(Composite parent, int style) {
		super(parent, style);
		addListener(SWT.MouseWheel, new Listener() {
			public void handleEvent(Event event) {
				if(getVerticalBar().isVisible()) {
					int delta=-fCellHeight;
					if(event.count<0)
						delta=-delta;
					scrollYDelta(delta);
				}
				event.doit=false;
			}
		});

	}

	/** template method paint.
	 * iterates over all cells in the clipping rectangle and paints them.
	 */
	protected void paint(GC gc) {
		Rectangle clipping=gc.getClipping();
		if(clipping.width==0 || clipping.height==0)
			return;
		Rectangle clientArea= getScreenRectInVirtualSpace();
		// Beginning coordinates
		int xOffset=clientArea.x;
		int yOffset=clientArea.y;
		int colFirst=virtualXToCell(xOffset+clipping.x);
		if(colFirst>getCols())
			colFirst=getCols();
		else if (colFirst < 0) {
			colFirst = 0;
		}
		int rowFirst=virtualYToCell(yOffset+clipping.y);
		// End coordinates
		int colLast=virtualXToCell(xOffset+clipping.x+clipping.width+fCellWidth);
		if(colLast>getCols())
			colLast=getCols();
		int rowLast=virtualYToCell(yOffset+clipping.y+clipping.height+fCellHeight);
		if(rowLast>getRows())
			rowLast=getRows();
		// System.out.println(rowFirst+"->"+rowLast+" "+System.currentTimeMillis());
		// draw the cells
		for(int row=rowFirst;row<=rowLast;row++) {
			int cx=colFirst*fCellWidth-xOffset;
			int cy=row*fCellHeight-yOffset;
			drawLine(gc,row,cx,cy,colFirst,colLast);
		}
		paintUnoccupiedSpace(gc,clipping);
	}
	/**
	 * @param gc
	 * @param row the line to draw
	 * @param x coordinate on screen
	 * @param y coordinate on screen
	 * @param colFirst first column to draw
	 * @param colLast last column to draw
	 */
	abstract void drawLine(GC gc, int row, int x, int y, int colFirst, int colLast);

	abstract protected int getRows();
	abstract protected int getCols();

	protected void setCellWidth(int cellWidth) {
		fCellWidth = cellWidth;
		getHorizontalBar().setIncrement(fCellWidth);
	}

	public int getCellWidth() {
		return fCellWidth;
	}

	protected void setCellHeight(int cellHeight) {
		fCellHeight = cellHeight;
		getVerticalBar().setIncrement(fCellHeight);
	}

	public int getCellHeight() {
		return fCellHeight;
	}

	int virtualXToCell(int x) {
		return x/fCellWidth;
	}

	int virtualYToCell(int y) {
		return y/fCellHeight;
	}

	protected Point screenPointToCell(int x, int y) {
		x=screenXtoVirtual(x)/fCellWidth;
		y=screenYtoVirtual(y)/fCellHeight;
		return new Point(x,y);
	}

	Point screenPointToCell(Point point) {
		return screenPointToCell(point.x,point.y);
	}

	protected Point cellToOriginOnScreen(int x, int y) {
		x=virtualXtoScreen(fCellWidth*x);
		y=virtualYtoScreen(fCellHeight*y);
		return new Point(x,y);
	}

	Point cellToOriginOnScreen(Point cell) {
		return cellToOriginOnScreen(cell.x,cell.y);
	}

	Rectangle getCellScreenRect(Point cell) {
		return getCellScreenRect(cell.x,cell.y);
	}

	Rectangle getCellScreenRect(int x, int y) {
		x=fCellWidth*virtualXtoScreen(x);
		y=fCellHeight*virtualYtoScreen(y);
		return new Rectangle(x,y,fCellWidth,fCellHeight);
	}

	protected Rectangle getCellVirtualRect(Point cell) {
		return getCellVirtualRect(cell.x,cell.y);
	}

	Rectangle getCellVirtualRect(int x, int y) {
		x=fCellWidth*x;
		y=fCellHeight*y;
		return new Rectangle(x,y,fCellWidth,fCellHeight);
	}
	protected void viewRectangleChanged(int x, int y, int width, int height) {
		int cellX=virtualXToCell(x);
		int cellY=virtualYToCell(y);
		// End coordinates
		int xE=virtualXToCell(x+width);
//		if(xE>getCols())
//			xE=getCols();
		int yE=virtualYToCell(y+height);
//		if(yE>getRows())
//			yE=getRows();
		visibleCellRectangleChanged(cellX,cellY,xE-cellX,yE-cellY);
	}
	
	/**
	 * Called when the viewed part has changed.
	 * Override when you need this information....
	 * Is only called if the values change (well, almost)
	 * @param x origin of visible cells
	 * @param y origin of visible cells
	 * @param width number of cells visible in x direction
	 * @param height number of cells visible in y direction
	 */
	protected void visibleCellRectangleChanged(int x, int y, int width, int height) {
	}
	
	protected void setVirtualExtend(int width, int height) {
		int cellHeight = getCellHeight();
		if (cellHeight > 0) {
			height -= height % cellHeight;
		}
		super.setVirtualExtend(width, height);
	}
	
	protected void setVirtualOrigin(int x, int y) {
		int cellHeight = getCellHeight();
		if (cellHeight > 0) {
			int remainder = y % cellHeight;
			if (remainder < 0) {
				y -= (cellHeight + remainder);
			} else {
				y -= remainder;
			}
		}
		super.setVirtualOrigin(x, y);
	}
	
	protected void scrollY(ScrollBar vBar) {
		int vSelection = vBar.getSelection ();
		Rectangle bounds = getVirtualBounds();
		int y = -vSelection;
		int cellHeight = getCellHeight();
		if (cellHeight > 0) {
			int remainder = y % cellHeight;
			if (remainder < 0) {
				y -= (cellHeight + remainder);
			} else {
				y -= remainder;
			}
		}
		int deltaY = y - bounds.y;
		if(deltaY!=0) {
			scrollSmart(0,deltaY);
			setVirtualOrigin(bounds.x, bounds.y += deltaY);
		}
		if (-bounds.y + getRows() * getCellHeight() >= bounds.height) {
			// scrolled to bottom - need to redraw bottom area
			Rectangle clientRect = getClientArea();
			redraw(0, clientRect.height - fCellHeight, clientRect.width, fCellHeight, false);
		}
	}
}
