package org.eclipse.swt.examples.paint;

/*
 * (c) Copyright IBM Corp. 2000, 2002.
 * This file is made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 */

import org.eclipse.swt.events.*;import org.eclipse.swt.graphics.*;import org.eclipse.swt.widgets.*;

/**
 * The superclass for paint tools that draw continuously along the path
 * traced by the mouse's movement while the button is depressed
 */
public abstract class ContinuousPaintSession extends BasicPaintSession {
	/**
	 * True if a click-drag is in progress.
	 */
	private boolean dragInProgress = false;
	
	/**
	 * A cached Point array for drawing.
	 */
	private Point[] points = new Point[] { new Point(-1, -1), new Point(-1, -1) };

	/**
	 * The time to wait between retriggers in milliseconds.
	 */
	private int retriggerInterval = 0;
	
	/**
	 * The currently valid RetriggerHandler
	 */
	protected Runnable retriggerHandler = null;

	/**
	 * Constructs a ContinuousPaintSession.
	 * 
	 * @param paintSurface the drawing surface to use
	 */
	protected ContinuousPaintSession(PaintSurface paintSurface) {
		super(paintSurface);
	}

	/**
	 * Sets the retrigger timer.
	 * <p>
	 * After the timer elapses, if the mouse is still hovering over the same point with the
	 * drag button pressed, a new render order is issued and the timer is restarted.
	 * </p>
	 * @param interval the time in milliseconds to wait between retriggers, 0 to disable
	 */
	public void setRetriggerTimer(int interval) {
		retriggerInterval = interval;
	}

	/**
	 * Activates the tool.
	 */
	public void beginSession() {
		getPaintSurface().
			setStatusMessage(PaintPlugin.getResourceString("session.ContinuousPaint.message"));
		dragInProgress = false;
	}
	
	/**
	 * Deactivates the tool.
     */
	public void endSession() {
		abortRetrigger();
	}
	
	/**
	 * Aborts the current operation.
	 */
	public void resetSession() {
		abortRetrigger();
	}

	/**
	 * Handles a mouseDown event.
	 * 
	 * @param event the mouse event detail information
	 */
	public final void mouseDown(MouseEvent event) {
		if (event.button != 1) return;
		if (dragInProgress) return; // spurious event
		dragInProgress = true;

		points[0].x = event.x;
		points[0].y = event.y;
		render(points[0]);
		prepareRetrigger();
	}

	/**
	 * Handles a mouseDoubleClick event.
	 * 
	 * @param event the mouse event detail information
	 */
	public final void mouseDoubleClick(MouseEvent event) {
	}

	/**
	 * Handles a mouseUp event.
	 * 
	 * @param event the mouse event detail information
	 */
	public final void mouseUp(MouseEvent event) {
		if (event.button != 1) return;
		if (! dragInProgress) return; // spurious event
		abortRetrigger();
		mouseSegmentFinished(event);
		dragInProgress = false;
	}
	
	/**
	 * Handles a mouseMove event.
	 * 
	 * @param event the mouse event detail information
	 */
	public final void mouseMove(MouseEvent event) {
		final PaintSurface ps = getPaintSurface();
		ps.setStatusCoord(ps.getCurrentPosition());
		if (! dragInProgress) return;
		mouseSegmentFinished(event);
		prepareRetrigger();
	}
	
	/**
	 * Handle a rendering segment
	 * 
	 * @param event the mouse event detail information
	 */
	private final void mouseSegmentFinished(MouseEvent event) {
		if (points[0].x == -1) return; // spurious event
		if (points[0].x != event.x || points[0].y != event.y) {
			// draw new segment
			points[1].x = event.x;
			points[1].y = event.y;
			renderContinuousSegment();
		}
	}

	/**
	 * Draws a continuous segment from points[0] to points[1].
	 * Assumes points[0] has been drawn already.
	 * 
	 * @post points[0] will refer to the same point as points[1]
	 */
	protected void renderContinuousSegment() {
		/* A lazy but effective line drawing algorithm */
		final int dX = points[1].x - points[0].x;
		final int dY = points[1].y - points[0].y;
		int absdX = Math.abs(dX);
		int absdY = Math.abs(dY);

		if ((dX == 0) && (dY == 0)) return;
		
		if (absdY > absdX) {
			final int incfpX = (dX << 16) / absdY;
			final int incY = (dY > 0) ? 1 : -1;
			int fpX = points[0].x << 16; // X in fixedpoint format

			while (--absdY >= 0) {
				points[0].y += incY;
				points[0].x = (fpX += incfpX) >> 16;
				render(points[0]);
			}
			if (points[0].x == points[1].x) return;
			points[0].x = points[1].x;
		} else {
			final int incfpY = (dY << 16) / absdX;
			final int incX = (dX > 0) ? 1 : -1;
			int fpY = points[0].y << 16; // Y in fixedpoint format

			while (--absdX >= 0) {
				points[0].x += incX;
				points[0].y = (fpY += incfpY) >> 16;
				render(points[0]);
			}
			if (points[0].y == points[1].y) return;
			points[0].y = points[1].y;
		}
		render(points[0]);
	}		

	/**
	 * Prepare the retrigger timer
	 */
	private final void prepareRetrigger() {
		if (retriggerInterval > 0) {
			/*
			 * timerExec() provides a lightweight mechanism for running code at intervals from within
			 * the event loop when timing accuracy is not important.
			 *
			 * Since it is not possible to cancel a timerExec(), we remember the Runnable that is
			 * active in order to distinguish the valid one from the stale ones.  In practice,
			 * if the interval is 1/100th of a second, then creating a few hundred new RetriggerHandlers
			 * each second will not cause a significant performance hit.
			 */
			Display display = getPaintSurface().getDisplay();
			retriggerHandler = new Runnable() {
				public void run() {
					if (retriggerHandler == this) {
						render(points[0]);
						prepareRetrigger();
					}
				}
			};			
			display.timerExec(retriggerInterval, retriggerHandler);
		}
	}

	/**
	 * Aborts the retrigger timer
	 */
	private final void abortRetrigger() {
		retriggerHandler = null;
	}
	
	/**
	 * Template method: Renders a point.
	 * @param point, the point to render
	 */
	protected abstract void render(Point point);
}
