/*******************************************************************************
 * Copyright (c) 2005 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.ui.examples.undo.views;

import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;

import org.eclipse.ui.IActionBars;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.examples.undo.AddBoxOperation;
import org.eclipse.ui.examples.undo.Box;
import org.eclipse.ui.examples.undo.Boxes;
import org.eclipse.ui.examples.undo.ClearBoxesOperation;
import org.eclipse.ui.examples.undo.MoveBoxOperation;
import org.eclipse.ui.examples.undo.PromptingUserApprover;
import org.eclipse.ui.examples.undo.UndoExampleMessages;
import org.eclipse.ui.examples.undo.UndoPlugin;
import org.eclipse.ui.examples.undo.preferences.PreferenceConstants;
import org.eclipse.ui.operations.RedoActionHandler;
import org.eclipse.ui.operations.UndoActionHandler;
import org.eclipse.ui.part.ViewPart;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.operations.IOperationApprover;
import org.eclipse.core.commands.operations.IOperationHistory;
import org.eclipse.core.commands.operations.IUndoContext;
import org.eclipse.core.commands.operations.ObjectUndoContext;

import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;

import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.SWT;

public class BoxView extends ViewPart {
	/*
	 * The canvas to paint the boxes on.
	 */
	private Canvas paintCanvas;

	/*
	 * The gc used for drawing the rubber band.
	 */
	private GC gc;

	/*
	 * The model, a group of boxes
	 */
	private Boxes boxes = new Boxes();

	/*
	 * Undo and redo actions
	 */
	private UndoActionHandler undoAction;

	private RedoActionHandler redoAction;

	private IAction clearBoxesAction;

	/*
	 * Private undo context for box operations
	 */
	private IUndoContext undoContext;

	/*
	 * Operation approver for approving undo and redo
	 */
	private IOperationApprover operationApprover;

	/*
	 * Property change listener for the undo limit preference.
	 */
	private IPropertyChangeListener propertyChangeListener;

	/*
	 * True if a click-drag is in progress
	 */
	private boolean dragInProgress = false;

	/*
	 * True if a click-move is in progress
	 */
	private boolean moveInProgress = false;

	/*
	 * The box that is being moved.
	 */
	private Box movingBox;

	/*
	 * The diff between a moving box and the track position.
	 */
	int diffX, diffY;

	/*
	 * The position of the first click in a click-drag
	 */
	private Point anchorPosition = new Point(-1, -1);

	/*
	 * A temporary point in a drag or move operation
	 */
	private Point tempPosition = new Point(-1, -1);

	/*
	 * The rubber band position (the last recorded temp position)
	 */
	private Point rubberbandPosition = new Point(-1, -1);

	/*
	 * Construct a BoxView.
	 */
	public BoxView() {
		super();
		initializeOperationHistory();
	}

	/*
	 * Create the canvas on which boxes are drawn and hook up all actions and
	 * listeners.
	 */
	public void createPartControl(Composite parent) {
		paintCanvas = new Canvas(parent, SWT.BORDER | SWT.V_SCROLL
				| SWT.H_SCROLL | SWT.NO_REDRAW_RESIZE);

		// set up a GC for drawing the tracking rectangle
		gc = new GC(paintCanvas);
		gc.setForeground(paintCanvas.getForeground());
		gc.setLineStyle(SWT.LINE_SOLID);

		// add listeners
		addListeners();

		// create actions and hook them up to the menus and toolbar
		makeActions();
		hookContextMenu();
		createGlobalActionHandlers();
		contributeToActionBars();
	}

	/*
	 * Add listeners to the canvas.
	 */
	private void addListeners() {
		paintCanvas.addMouseListener(new MouseAdapter() {
			public void mouseDown(MouseEvent event) {
				if (event.button != 1)
					return;
				if (dragInProgress || moveInProgress)
					return; // spurious event

				tempPosition.x = event.x;
				tempPosition.y = event.y;
				Box box = boxes.getBox(event.x, event.y);
				if (box != null) {
					moveInProgress = true;
					movingBox = box;
					anchorPosition.x = box.x1;
					anchorPosition.y = box.y1;
					diffX = event.x - box.x1;
					diffY = event.y - box.y1;
				} else {
					dragInProgress = true;
					anchorPosition.x = event.x;
					anchorPosition.y = event.y;
				}
			}

			public void mouseUp(MouseEvent event) {
				if (event.button != 1) {
					resetDrag(true); // abort if right or middle mouse button
					// pressed
					return;
				}
				if (anchorPosition.x == -1)
					return; // spurious event

				if (dragInProgress) {
					Box box = new Box(anchorPosition.x, anchorPosition.y,
							tempPosition.x, tempPosition.y);
					if (box.getWidth() > 0 && box.getHeight() > 0) {
						try {
							getOperationHistory().execute(
									new AddBoxOperation(
											UndoExampleMessages.BoxView_Add,
											undoContext, boxes, box, paintCanvas),
									null, null);
						} catch (ExecutionException e) {
						}
						dragInProgress = false;
					}
				} else if (moveInProgress) {
					try {
						getOperationHistory().execute(
								new MoveBoxOperation(
										UndoExampleMessages.BoxView_Move,
										undoContext, movingBox, paintCanvas,
										anchorPosition), null, null);
					} catch (ExecutionException e) {
					}
					moveInProgress = false;
					movingBox = null;
				}
				resetDrag(false);

				// redraw everything to clean up the tracking rectangle
				paintCanvas.redraw();
			}

			public void mouseDoubleClick(MouseEvent event) {
			}
		});
		paintCanvas.addMouseMoveListener(new MouseMoveListener() {
			public void mouseMove(MouseEvent event) {
				if (dragInProgress) {
					clearRubberBandSelection();
					tempPosition.x = event.x;
					tempPosition.y = event.y;
					addRubberBandSelection();
				} else if (moveInProgress) {
					clearRubberBandSelection();
					anchorPosition.x = event.x - diffX;
					anchorPosition.y = event.y - diffY;
					tempPosition.x = anchorPosition.x + movingBox.getWidth();
					tempPosition.y = anchorPosition.y + movingBox.getHeight();
					addRubberBandSelection();
				}
			}
		});
		paintCanvas.addPaintListener(new PaintListener() {
			public void paintControl(PaintEvent event) {
				event.gc.setForeground(paintCanvas.getForeground());
				boxes.draw(event.gc);
			}
		});

		paintCanvas.addDisposeListener(new DisposeListener() {
			public void widgetDisposed(DisposeEvent event) {
				// dispose the gc
				gc.dispose();
				// dispose listeners
				removeListeners();
			}
		});

		// listen for a change in the undo limit
		propertyChangeListener = new IPropertyChangeListener() {
			public void propertyChange(PropertyChangeEvent event) {
				if (event.getProperty() == PreferenceConstants.PREF_UNDOLIMIT) {
					int limit = UndoPlugin.getDefault().getPreferenceStore()
							.getInt(PreferenceConstants.PREF_UNDOLIMIT);
					getOperationHistory().setLimit(undoContext, limit);
				}
			}
		};
		UndoPlugin.getDefault().getPreferenceStore().addPropertyChangeListener(
				propertyChangeListener);

	}

	/*
	 * Remove listeners that were registered. Since the control is being
	 * disposed, we are only removing non-control listeners.
	 */
	private void removeListeners() {
		UndoPlugin.getDefault().getPreferenceStore()
				.removePropertyChangeListener(propertyChangeListener);
		getOperationHistory().removeOperationApprover(operationApprover);
	}

	/*
	 * Hook a listener on the menu showing so we can fill the context menu with
	 * our actions.
	 */
	private void hookContextMenu() {
		MenuManager menuMgr = new MenuManager("#PopupMenu");
		menuMgr.setRemoveAllWhenShown(true);
		menuMgr.addMenuListener(new IMenuListener() {
			public void menuAboutToShow(IMenuManager manager) {
				BoxView.this.fillContextMenu(manager);
			}
		});
		Menu menu = menuMgr.createContextMenu(paintCanvas);
		paintCanvas.setMenu(menu);
	}

	/*
	 * Add our actions to the action bars.
	 */
	private void contributeToActionBars() {
		IActionBars bars = getViewSite().getActionBars();
		fillLocalPullDown(bars.getMenuManager());
		fillLocalToolBar(bars.getToolBarManager());
	}

	/*
	 * Add our undo and redo actions to the local pulldown.
	 */
	private void fillLocalPullDown(IMenuManager manager) {
		manager.add(undoAction);
		manager.add(redoAction);
		manager.add(new Separator());
		manager.add(clearBoxesAction);
	}

	/*
	 * Add our undo and redo actions to the context menu.
	 */
	private void fillContextMenu(IMenuManager manager) {
		manager.add(undoAction);
		manager.add(redoAction);
		manager.add(new Separator());
		manager.add(clearBoxesAction);
		manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
	}

	/*
	 * Add actions to the local toolbar.
	 */
	private void fillLocalToolBar(IToolBarManager manager) {
		manager.add(clearBoxesAction);
	}

	/*
	 * Make any local actions used in the view.
	 */
	private void makeActions() {
		clearBoxesAction = new Action() {
			public void run() {
				try {
					getOperationHistory().execute(
							new ClearBoxesOperation(
									UndoExampleMessages.BoxView_ClearBoxes,
									undoContext, boxes, paintCanvas), null,
							null);
				} catch (ExecutionException e) {
				}
			}
		};
		clearBoxesAction.setText(UndoExampleMessages.BoxView_ClearBoxes);
		clearBoxesAction
				.setToolTipText(UndoExampleMessages.BoxView_ClearBoxesToolTipText);
		clearBoxesAction.setImageDescriptor(PlatformUI.getWorkbench()
				.getSharedImages().getImageDescriptor(
						ISharedImages.IMG_TOOL_DELETE));
	}

	/*
	 * Create the global undo and redo action handlers.
	 */
	private void createGlobalActionHandlers() {
		// set up action handlers that operate on the current context
		undoAction = new UndoActionHandler(this.getSite(), undoContext);
		redoAction = new RedoActionHandler(this.getSite(), undoContext);
		IActionBars actionBars = getViewSite().getActionBars();
		actionBars.setGlobalActionHandler(ActionFactory.UNDO.getId(),
				undoAction);
		actionBars.setGlobalActionHandler(ActionFactory.REDO.getId(),
				redoAction);
	}

	/*
	 * Set focus to the canvas.
	 */
	public void setFocus() {
		paintCanvas.setFocus();
	}

	/*
	 * Reset the drag operation.
	 */
	private void resetDrag(boolean clearRubberband) {
		if (clearRubberband) {
			clearRubberBandSelection();
		}
		dragInProgress = false;
		moveInProgress = false;
		movingBox = null;
		anchorPosition.x = anchorPosition.y = tempPosition.x = tempPosition.y = rubberbandPosition.x = rubberbandPosition.y = -1;
	}

	/*
	 * Clear the existing rubber band selection.
	 */
	private void clearRubberBandSelection() {
		gc.setForeground(paintCanvas.getBackground());
		gc.drawRectangle(anchorPosition.x, anchorPosition.y,
				rubberbandPosition.x - anchorPosition.x, rubberbandPosition.y
						- anchorPosition.y);
		paintCanvas.redraw(anchorPosition.x, anchorPosition.y,
				rubberbandPosition.x - anchorPosition.x, rubberbandPosition.y
						- anchorPosition.y, false);
		paintCanvas.update();
		rubberbandPosition = new Point(-1, -1);
		gc.setForeground(paintCanvas.getForeground());
	}

	/*
	 * Show a rubber band selection.
	 */
	private void addRubberBandSelection() {
		rubberbandPosition = tempPosition;
		gc.drawRectangle(anchorPosition.x, anchorPosition.y,
				rubberbandPosition.x - anchorPosition.x, rubberbandPosition.y
						- anchorPosition.y);
	}

	/*
	 * Initialize the workbench operation history for our undo context.
	 */
	private void initializeOperationHistory() {
		// create a unique undo context to represent this view's undo history
		undoContext = new ObjectUndoContext(this);

		// set the undo limit for this context based on the preference
		int limit = UndoPlugin.getDefault().getPreferenceStore().getInt(
				PreferenceConstants.PREF_UNDOLIMIT);
		getOperationHistory().setLimit(undoContext, limit);

		// Install an operation approver for this undo context that prompts
		// according to a user preference.
		operationApprover = new PromptingUserApprover(undoContext);
		getOperationHistory().addOperationApprover(operationApprover);
	}

	/*
	 * Get the operation history from the workbench.
	 */
	private IOperationHistory getOperationHistory() {
		return PlatformUI.getWorkbench().getOperationSupport()
				.getOperationHistory();
	}

}