/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are 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
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.examples.paint;


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);
}
