/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.examples.paint;


import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Display;

/**
 * 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.
	 */
	@Override
	public void beginSession() {
		getPaintSurface().
			setStatusMessage(PaintExample.getResourceString("session.ContinuousPaint.message"));
		dragInProgress = false;
	}

	/**
	 * Deactivates the tool.
	 */
	@Override
	public void endSession() {
		abortRetrigger();
	}

	/**
	 * Aborts the current operation.
	 */
	@Override
	public void resetSession() {
		abortRetrigger();
	}

	/**
	 * Handles a mouseDown event.
	 *
	 * @param event the mouse event detail information
	 */
	@Override
	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
	 */
	@Override
	public final void mouseDoubleClick(MouseEvent event) {
	}

	/**
	 * Handles a mouseUp event.
	 *
	 * @param event the mouse event detail information
	 */
	@Override
	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
	 */
	@Override
	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() {
				@Override
				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);
}
