/*******************************************************************************
 * Copyright (c) 2000, 2016 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.examples.paint;

import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.graphics.Region;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

/**
 * Manages a simple drawing surface.
 */
public class PaintSurface {
	private Point currentPosition = new Point(0, 0);
	private Canvas paintCanvas;

	private PaintSession paintSession;
	private Image image;
	private Image paintImage; // buffer for refresh blits
	private int   imageWidth, imageHeight;
	private int   visibleWidth, visibleHeight;

	private FigureDrawContext displayFDC = new FigureDrawContext();
	private FigureDrawContext imageFDC = new FigureDrawContext();
	private FigureDrawContext paintFDC = new FigureDrawContext();

	/* Rubberband */
	private ContainerFigure rubberband = new ContainerFigure();
		// the active rubberband selection
	private int rubberbandHiddenNestingCount = 0;
		// always >= 0, if > 0 rubberband has been hidden

	/* Status */
	private Text statusText;
	private String statusActionInfo, statusMessageInfo, statusCoordInfo;

	/**
	 * Constructs a PaintSurface.
	 * <p>
	 * paintCanvas must have SWT.NO_REDRAW_RESIZE and SWT.NO_BACKGROUND styles,
	 *     and may have SWT.V_SCROLL and/or SWT.H_SCROLL.
	 * </p>
	 * @param paintCanvas the Canvas object in which to render
	 * @param paintStatus the PaintStatus object to use for providing user feedback
	 * @param fillColor the color to fill the canvas with initially
	 */
	public PaintSurface(Canvas paintCanvas, Text statusText, Color fillColor) {
		this.paintCanvas = paintCanvas;
		this.statusText = statusText;
		clearStatus();

		/* Set up the drawing surface */
		Rectangle displayRect = paintCanvas.getDisplay().getClientArea();
		imageWidth = displayRect.width;
		imageHeight = displayRect.height;
		image = new Image(paintCanvas.getDisplay(), imageWidth, imageHeight);

		imageFDC.gc = new GC(image);
		imageFDC.gc.setBackground(fillColor);
		imageFDC.gc.fillRectangle(0, 0, imageWidth, imageHeight);
		displayFDC.gc = new GC(paintCanvas);

		/* Initialize the session */
		setPaintSession(null);

		/* Add our listeners */
		paintCanvas.addDisposeListener(e -> displayFDC.gc.dispose());
		paintCanvas.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseDown(MouseEvent event) {
				processMouseEventCoordinates(event);
				if (paintSession != null) paintSession.mouseDown(event);
			}
			@Override
			public void mouseUp(MouseEvent event) {
				processMouseEventCoordinates(event);
				if (paintSession != null) paintSession.mouseUp(event);
			}
			@Override
			public void mouseDoubleClick(MouseEvent event) {
				processMouseEventCoordinates(event);
				if (paintSession != null) paintSession.mouseDoubleClick(event);
			}
		});
		paintCanvas.addMouseMoveListener(event -> {
			processMouseEventCoordinates(event);
			if (paintSession != null) paintSession.mouseMove(event);
		});
		paintCanvas.addPaintListener(event -> {
			if (rubberband.isEmpty()) {
				// Nothing to merge, so we just refresh
				event.gc.drawImage(image,
					displayFDC.xOffset + event.x, displayFDC.yOffset + event.y, event.width, event.height,
					event.x, event.y, event.width, event.height);
			} else {
				/*
				 * Avoid flicker when merging overlayed objects by constructing the image on
				 * a backbuffer first, then blitting it to the screen.
				 */
				// Check that the backbuffer is large enough
				if (paintImage != null) {
					Rectangle rect1 = paintImage.getBounds();
					if ((event.width + event.x > rect1.width) ||
						(event.height + event.y > rect1.height)) {
						paintFDC.gc.dispose();
						paintImage.dispose();
						paintImage = null;
					}
				}
				if (paintImage == null) {
					Display display = getDisplay();
					Rectangle rect2 = display.getClientArea();
					paintImage = new Image(display,
						Math.max(rect2.width, event.width + event.x),
						Math.max(rect2.height, event.height + event.y));
					paintFDC.gc = new GC(paintImage);
				}
				// Setup clipping and the FDC
				Region clipRegion = new Region();
				event.gc.getClipping(clipRegion);
				paintFDC.gc.setClipping(clipRegion);
				clipRegion.dispose();

				paintFDC.xOffset = displayFDC.xOffset;
				paintFDC.yOffset = displayFDC.yOffset;
				paintFDC.xScale = displayFDC.xScale;
				paintFDC.yScale = displayFDC.yScale;

				// Merge the overlayed objects into the image, then blit
				paintFDC.gc.drawImage(image,
					displayFDC.xOffset + event.x, displayFDC.yOffset + event.y, event.width, event.height,
					event.x, event.y, event.width, event.height);
				rubberband.draw(paintFDC);
				event.gc.drawImage(paintImage,
					event.x, event.y, event.width, event.height,
					event.x, event.y, event.width, event.height);
			}
		});
		paintCanvas.addControlListener(new ControlAdapter() {
			@Override
			public void controlResized(ControlEvent event) {
				handleResize();
			}
		});

		/* Set up the paint canvas scroll bars */
		ScrollBar horizontal = paintCanvas.getHorizontalBar();
		horizontal.setVisible(true);
		horizontal.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				scrollHorizontally((ScrollBar)event.widget);
			}
		});
		ScrollBar vertical = paintCanvas.getVerticalBar();
		vertical.setVisible(true);
		vertical.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent event) {
				scrollVertically((ScrollBar)event.widget);
			}
		});
		handleResize();
	}

	/**
	 * Disposes of the PaintSurface's resources.
	 */
	public void dispose() {
		imageFDC.gc.dispose();
		image.dispose();
		if (paintImage != null) {
			paintImage.dispose();
			paintFDC.gc.dispose();
		}

		currentPosition = null;
		paintCanvas = null;
		paintSession = null;
		image = null;
		paintImage = null;
		displayFDC = null;
		imageFDC = null;
		paintFDC = null;
		rubberband = null;
		statusText = null;
		statusActionInfo = null;
		statusMessageInfo = null;
		statusCoordInfo = null;
	}

	/**
	 * Called when we must grab focus.
	 */
	public void setFocus()  {
		paintCanvas.setFocus();
	}

	/**
	 * Returns the Display on which the PaintSurface resides.
	 * @return the Display
	 */
	public Display getDisplay() {
		return paintCanvas.getDisplay();
	}

	/**
	 * Returns the Shell in which the PaintSurface resides.
	 * @return the Shell
	 */
	public Shell getShell() {
		return paintCanvas.getShell();
	}

	/**
	 * Sets the current paint session.
	 * <p>
	 * If oldPaintSession != paintSession calls oldPaintSession.end()
	 * and paintSession.begin()
	 * </p>
	 *
	 * @param paintSession the paint session to activate; null to disable all sessions
	 */
	public void setPaintSession(PaintSession paintSession) {
		if (this.paintSession != null) {
			if (this.paintSession == paintSession) return;
			this.paintSession.endSession();
		}
		this.paintSession = paintSession;
		clearStatus();
		if (paintSession != null) {
			setStatusAction(paintSession.getDisplayName());
			paintSession.beginSession();
		} else {
			setStatusAction(PaintExample.getResourceString("tool.Null.label"));
			setStatusMessage(PaintExample.getResourceString("session.Null.message"));
		}
	}

	/**
	 * Returns the current paint session.
	 *
	 * @return the current paint session, null if none is active
	 */
	public PaintSession getPaintSession() {
		return paintSession;
	}

	/**
	 * Returns the current paint tool.
	 *
	 * @return the current paint tool, null if none is active (though some other session
	 *         might be)
	 */
	public PaintTool getPaintTool() {
		return (paintSession != null && paintSession instanceof PaintTool) ?
			(PaintTool)paintSession : null;
	}

	/**
	 * Returns the current position in an interactive operation.
	 *
	 * @return the last known position of the pointer
	 */
	public Point getCurrentPosition() {
		return currentPosition;
	}

	/**
	 * Draws a Figure object to the screen and to the backing store permanently.
	 *
	 * @param object the object to draw onscreen
	 */
	public void drawFigure(Figure object) {
		object.draw(imageFDC);
		object.draw(displayFDC);
	}

	/**
	 * Adds a Figure object to the active rubberband selection.
	 * <p>
	 * This object will be drawn to the screen as a preview and refreshed appropriately
	 * until the selection is either cleared or committed.
	 * </p>
	 *
	 * @param object the object to add to the selection
	 */
	public void addRubberbandSelection(Figure object) {
		rubberband.add(object);
		if (! isRubberbandHidden()) object.draw(displayFDC);
	}

	/**
	 * Clears the active rubberband selection.
	 * <p>
	 * Erases any rubberband objects on the screen then clears the selection.
	 * </p>
	 */
	public void clearRubberbandSelection() {
		if (! isRubberbandHidden()) {
			Region region = new Region();
			rubberband.addDamagedRegion(displayFDC, region);
			Rectangle r = region.getBounds();
			paintCanvas.redraw(r.x, r.y, r.width, r.height, true);
			region.dispose();
		}
		rubberband.clear();

	}

	/**
	 * Commits the active rubberband selection.
	 * <p>
	 * Redraws any rubberband objects on the screen as permanent objects then clears the selection.
	 * </p>
	 */
	public void commitRubberbandSelection() {
		rubberband.draw(imageFDC);
		if (isRubberbandHidden()) rubberband.draw(displayFDC);
		rubberband.clear();
	}

	/**
	 * Hides the rubberband (but does not eliminate it).
	 * <p>
	 * Increments by one the rubberband "hide" nesting count.  The rubberband
	 * is hidden from view (but remains active) if it wasn't already hidden.
	 * </p>
	 */
	public void hideRubberband() {
		if (rubberbandHiddenNestingCount++ <= 0) {
			Region region = new Region();
			rubberband.addDamagedRegion(displayFDC, region);
			Rectangle r = region.getBounds();
			paintCanvas.redraw(r.x, r.y, r.width, r.height, true);
			region.dispose();
		}
	}

	/**
	 * Shows (un-hides) the rubberband.
	 * <p>
	 * Decrements by one the rubberband "hide" nesting count.  The rubberband
	 * is only made visible when showRubberband() has been called once for each
	 * previous hideRubberband().  It is not permitted to call showRubberband() if
	 * the rubber band is not presently hidden.
	 * </p>
	 */
	public void showRubberband() {
		if (rubberbandHiddenNestingCount <= 0)
			throw new IllegalStateException("rubberbandHiddenNestingCount > 0");
		if (--rubberbandHiddenNestingCount == 0) {
			rubberband.draw(displayFDC);
		}
	}

	/**
	 * Determines if the rubberband is hidden.
	 *
	 * @return true iff the rubber is hidden
	 */
	public boolean isRubberbandHidden() {
		return rubberbandHiddenNestingCount > 0;
	}

	/**
	 * Handles a horizontal scroll event
	 *
	 * @param scrollbar the horizontal scroll bar that posted this event
	 */
	public void scrollHorizontally(ScrollBar scrollBar) {
		if (image == null) return;
		if (imageWidth > visibleWidth) {
			final int oldOffset = displayFDC.xOffset;
			final int newOffset = Math.min(scrollBar.getSelection(), imageWidth - visibleWidth);
			if (oldOffset != newOffset) {
				paintCanvas.update();
				displayFDC.xOffset = newOffset;
				paintCanvas.scroll(Math.max(oldOffset - newOffset, 0), 0, Math.max(newOffset - oldOffset, 0), 0,
					visibleWidth, visibleHeight, false);
			}
		}
	}

	/**
	 * Handles a vertical scroll event
	 *
	 * @param scrollbar the vertical scroll bar that posted this event
	 */
	public void scrollVertically(ScrollBar scrollBar) {
		if (image == null) return;
		if (imageHeight > visibleHeight) {
			final int oldOffset = displayFDC.yOffset;
			final int newOffset = Math.min(scrollBar.getSelection(), imageHeight - visibleHeight);
			if (oldOffset != newOffset) {
				paintCanvas.update();
				displayFDC.yOffset = newOffset;
				paintCanvas.scroll(0, Math.max(oldOffset - newOffset, 0), 0, Math.max(newOffset - oldOffset, 0),
					visibleWidth, visibleHeight, false);
			}
		}
	}

	/**
	 * Handles resize events
	 */
	private void handleResize() {
		paintCanvas.update();

		Rectangle visibleRect = paintCanvas.getClientArea();
		visibleWidth = visibleRect.width;
		visibleHeight = visibleRect.height;

		ScrollBar horizontal = paintCanvas.getHorizontalBar();
		if (horizontal != null) {
			displayFDC.xOffset = Math.min(horizontal.getSelection(), imageWidth - visibleWidth);
			if (imageWidth <= visibleWidth) {
				horizontal.setEnabled(false);
				horizontal.setSelection(0);
			} else {
				horizontal.setEnabled(true);
				horizontal.setValues(displayFDC.xOffset, 0, imageWidth, visibleWidth,
					8, visibleWidth);
			}
		}

		ScrollBar vertical = paintCanvas.getVerticalBar();
		if (vertical != null) {
			displayFDC.yOffset = Math.min(vertical.getSelection(), imageHeight - visibleHeight);
			if (imageHeight <= visibleHeight) {
				vertical.setEnabled(false);
				vertical.setSelection(0);
			} else {
				vertical.setEnabled(true);
				vertical.setValues(displayFDC.yOffset, 0, imageHeight, visibleHeight,
					8, visibleHeight);
			}
		}
	}

	/**
	 * Virtualizes MouseEvent coordinates and stores the current position.
	 */
	private void processMouseEventCoordinates(MouseEvent event) {
		currentPosition.x = event.x =
			Math.min(Math.max(event.x, 0), visibleWidth - 1) + displayFDC.xOffset;
		currentPosition.y = event.y =
			Math.min(Math.max(event.y, 0), visibleHeight - 1) + displayFDC.yOffset;
	}

	/**
	 * Clears the status bar.
	 */
	public void clearStatus() {
		statusActionInfo = "";
		statusMessageInfo = "";
		statusCoordInfo = "";
		updateStatus();
	}

	/**
	 * Sets the status bar action text.
	 *
	 * @param action the action in progress, null to clear
	 */
	public void setStatusAction(String action) {
		statusActionInfo = (action != null) ? action : "";
		updateStatus();
	}

	/**
	 * Sets the status bar message text.
	 *
	 * @param message the message to display, null to clear
	 */
	public void setStatusMessage(String message) {
		statusMessageInfo = (message != null) ? message : "";
		updateStatus();
	}

	/**
	 * Sets the coordinates in the status bar.
	 *
	 * @param coord the coordinates to display, null to clear
	 */
	public void setStatusCoord(Point coord) {
		statusCoordInfo = (coord != null) ? PaintExample.getResourceString("status.Coord.format", new Object[]
			{ Integer.valueOf(coord.x), Integer.valueOf(coord.y)}) : "";
		updateStatus();
	}

	/**
	 * Sets the coordinate range in the status bar.
	 *
	 * @param a the "from" coordinate, must not be null
	 * @param b the "to" coordinate, must not be null
	 */
	public void setStatusCoordRange(Point a, Point b) {
		statusCoordInfo = PaintExample.getResourceString("status.CoordRange.format", new Object[]
			{ Integer.valueOf(a.x), Integer.valueOf(a.y), Integer.valueOf(b.x), Integer.valueOf(b.y)});
		updateStatus();
	}

	/**
	 * Updates the display.
	 */
	private void updateStatus() {
		statusText.setText(
			PaintExample.getResourceString("status.Bar.format", new Object[]
			{ statusActionInfo, statusMessageInfo, statusCoordInfo }));
	}
}
