/*******************************************************************************
 * Copyright (c) 2000, 2010 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.gef.tools;

import org.eclipse.swt.graphics.Cursor;

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PrecisionRectangle;
import org.eclipse.draw2d.geometry.Rectangle;

import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.SharedCursors;
import org.eclipse.gef.SnapToHelper;
import org.eclipse.gef.requests.CreateRequest;
import org.eclipse.gef.requests.CreationFactory;

/**
 * The CreationTool creates new {@link EditPart EditParts} via a
 * {@link CreationFactory}. If the user simply clicks on the viewer, the default
 * sized EditPart will be created at that point. If the user clicks and drags,
 * the created EditPart will be sized based on where the user clicked and
 * dragged.
 */
public class CreationTool extends TargetingTool {

	/**
	 * Property to be used in {@link AbstractTool#setProperties(java.util.Map)}
	 * for {@link #setFactory(CreationFactory)}.
	 */
	public static final Object PROPERTY_CREATION_FACTORY = "factory"; //$NON-NLS-1$

	private CreationFactory factory;
	private SnapToHelper helper;

	/**
	 * Default constructor. Sets the default and disabled cursors.
	 */
	public CreationTool() {
		setDefaultCursor(SharedCursors.CURSOR_TREE_ADD);
		setDisabledCursor(SharedCursors.NO);
	}

	/**
	 * Constructs a new CreationTool with the given factory.
	 * 
	 * @param aFactory
	 *            the creation factory
	 */
	public CreationTool(CreationFactory aFactory) {
		this();
		setFactory(aFactory);
	}

	/**
	 * @see org.eclipse.gef.tools.AbstractTool#applyProperty(java.lang.Object,
	 *      java.lang.Object)
	 */
	protected void applyProperty(Object key, Object value) {
		if (PROPERTY_CREATION_FACTORY.equals(key)) {
			if (value instanceof CreationFactory)
				setFactory((CreationFactory) value);
			return;
		}
		super.applyProperty(key, value);
	}

	/**
	 * @see org.eclipse.gef.tools.AbstractTool#calculateCursor()
	 */
	protected Cursor calculateCursor() {
		/*
		 * Fix for Bug# 66010 The following two lines of code were added for the
		 * case where a tool is activated via the keyboard (that code hasn't
		 * been released yet). However, they were causing a problem as described
		 * in 66010. Since the keyboard activation code is not being released
		 * for 3.0, the following lines are being commented out.
		 */
		// if (isInState(STATE_INITIAL))
		// return getDefaultCursor();
		return super.calculateCursor();
	}

	/**
	 * Creates a {@link CreateRequest} and sets this tool's factory on the
	 * request.
	 * 
	 * @see org.eclipse.gef.tools.TargetingTool#createTargetRequest()
	 */
	protected Request createTargetRequest() {
		CreateRequest request = new CreateRequest();
		request.setFactory(getFactory());
		return request;
	}

	/**
	 * @see org.eclipse.gef.Tool#deactivate()
	 */
	public void deactivate() {
		super.deactivate();
		helper = null;
	}

	/**
	 * @see org.eclipse.gef.tools.AbstractTool#getCommandName()
	 */
	protected String getCommandName() {
		return REQ_CREATE;
	}

	/**
	 * Cast the target request to a CreateRequest and returns it.
	 * 
	 * @return the target request as a CreateRequest
	 * @see TargetingTool#getTargetRequest()
	 */
	protected CreateRequest getCreateRequest() {
		return (CreateRequest) getTargetRequest();
	}

	/**
	 * @see org.eclipse.gef.tools.AbstractTool#getDebugName()
	 */
	protected String getDebugName() {
		return "Creation Tool";//$NON-NLS-1$
	}

	/**
	 * Returns the creation factory used to create the new EditParts.
	 * 
	 * @return the creation factory
	 */
	protected CreationFactory getFactory() {
		return factory;
	}

	/**
	 * The creation tool only works by clicking mouse button 1 (the left mouse
	 * button in a right-handed world). If any other button is pressed, the tool
	 * goes into an invalid state. Otherwise, it goes into the drag state,
	 * updates the request's location and calls
	 * {@link TargetingTool#lockTargetEditPart(EditPart)} with the edit part
	 * that was just clicked on.
	 * 
	 * @see org.eclipse.gef.tools.AbstractTool#handleButtonDown(int)
	 */
	protected boolean handleButtonDown(int button) {
		if (button != 1) {
			setState(STATE_INVALID);
			handleInvalidInput();
			return true;
		}
		if (stateTransition(STATE_INITIAL, STATE_DRAG)) {
			getCreateRequest().setLocation(getLocation());
			lockTargetEditPart(getTargetEditPart());
			// Snap only when size on drop is employed
			if (getTargetEditPart() != null)
				helper = (SnapToHelper) getTargetEditPart().getAdapter(
						SnapToHelper.class);
		}
		return true;
	}

	/**
	 * If the tool is currently in a drag or drag-in-progress state, it goes
	 * into the terminal state, performs some cleanup (erasing feedback,
	 * unlocking target edit part), and then calls {@link #performCreation(int)}
	 * .
	 * 
	 * @see org.eclipse.gef.tools.AbstractTool#handleButtonUp(int)
	 */
	protected boolean handleButtonUp(int button) {
		if (stateTransition(STATE_DRAG | STATE_DRAG_IN_PROGRESS, STATE_TERMINAL)) {
		  // HACK for DND in RAP
			handleMove();
			eraseTargetFeedback();
			unlockTargetEditPart();
			performCreation(button);
		}

		setState(STATE_TERMINAL);
		handleFinished();

		return true;
	}

	/**
	 * Updates the request, sets the current command, and asks to show feedback.
	 * 
	 * @see org.eclipse.gef.tools.AbstractTool#handleDragInProgress()
	 */
	protected boolean handleDragInProgress() {
		if (isInState(STATE_DRAG_IN_PROGRESS)) {
			updateTargetRequest();
			setCurrentCommand(getCommand());
			showTargetFeedback();
		}
		return true;
	}

	/**
	 * @see org.eclipse.gef.tools.AbstractTool#handleDragStarted()
	 */
	protected boolean handleDragStarted() {
		return stateTransition(STATE_DRAG, STATE_DRAG_IN_PROGRESS);
	}

	/**
	 * If the user is in the middle of creating a new edit part, the tool erases
	 * feedback and goes into the invalid state when focus is lost.
	 * 
	 * @see org.eclipse.gef.tools.AbstractTool#handleFocusLost()
	 */
	protected boolean handleFocusLost() {
		if (isInState(STATE_DRAG | STATE_DRAG_IN_PROGRESS)) {
			eraseTargetFeedback();
			setState(STATE_INVALID);
			handleFinished();
			return true;
		}
		return false;
	}

	/**
	 * @see org.eclipse.gef.tools.TargetingTool#handleHover()
	 */
	protected boolean handleHover() {
		if (isInState(STATE_INITIAL))
			updateAutoexposeHelper();
		return true;
	}

	/**
	 * Updates the request and mouse target, gets the current command and asks
	 * to show feedback.
	 * 
	 * @see org.eclipse.gef.tools.AbstractTool#handleMove()
	 */
	protected boolean handleMove() {
		updateTargetRequest();
		updateTargetUnderMouse();
		setCurrentCommand(getCommand());
		showTargetFeedback();
		return true;
	}

	/**
	 * Executes the current command and selects the newly created object. The
	 * button that was released to cause this creation is passed in, but since
	 * {@link #handleButtonDown(int)} goes into the invalid state if the button
	 * pressed is not button 1, this will always be button 1.
	 * 
	 * @param button
	 *            the button that was pressed
	 */
	protected void performCreation(int button) {
		EditPartViewer viewer = getCurrentViewer();
		executeCurrentCommand();
		selectAddedObject(viewer);
	}

	/*
	 * Add the newly created object to the viewer's selected objects.
	 */
	private void selectAddedObject(EditPartViewer viewer) {
		final Object model = getCreateRequest().getNewObject();
		if (model == null || viewer == null)
			return;
		Object editpart = viewer.getEditPartRegistry().get(model);
		if (editpart instanceof EditPart) {
			// Force the new object to get positioned in the viewer.
			viewer.flush();
			viewer.select((EditPart) editpart);
		}
	}

	/**
	 * Sets the creation factory used to create the new edit parts.
	 * 
	 * @param factory
	 *            the factory
	 */
	public void setFactory(CreationFactory factory) {
		this.factory = factory;
	}

	/**
	 * Sets the location (and size if the user is performing size-on-drop) of
	 * the request.
	 * 
	 * @see org.eclipse.gef.tools.TargetingTool#updateTargetRequest()
	 */
	protected void updateTargetRequest() {
		CreateRequest createRequest = getCreateRequest();
		if (isInState(STATE_DRAG_IN_PROGRESS)) {
			Point loq = getStartLocation();
			Rectangle bounds = new Rectangle(loq, loq);
			bounds.union(loq.getTranslated(getDragMoveDelta()));
			createRequest.setSize(bounds.getSize());
			createRequest.setLocation(bounds.getLocation());
			createRequest.getExtendedData().clear();
			createRequest.setSnapToEnabled(!getCurrentInput().isModKeyDown(
					MODIFIER_NO_SNAPPING));
			if (helper != null && createRequest.isSnapToEnabled()) {
				PrecisionRectangle baseRect = new PrecisionRectangle(bounds);
				PrecisionRectangle result = baseRect.getPreciseCopy();
				helper.snapRectangle(createRequest, PositionConstants.NSEW,
						baseRect, result);
				createRequest.setLocation(result.getLocation());
				createRequest.setSize(result.getSize());
			}
			enforceConstraintsForSizeOnDropCreate(createRequest);
		} else {
			createRequest.setSize(null);
			createRequest.setLocation(getLocation());
			createRequest.setSnapToEnabled(false);
		}
	}

	/**
	 * Ensures size constraints (by default minimum and maximum) are respected
	 * by the given request. May be overwritten by clients to enforce additional
	 * constraints.
	 * 
	 * @since 3.7
	 */
	protected void enforceConstraintsForSizeOnDropCreate(CreateRequest request) {
		CreateRequest createRequest = (CreateRequest) getTargetRequest();
		if (createRequest.getSize() != null) {
			// ensure create request respects minimum and maximum size
			// constraints
			PrecisionRectangle constraint = new PrecisionRectangle(
					createRequest.getLocation(), createRequest.getSize());
			((GraphicalEditPart) getTargetEditPart()).getContentPane()
					.translateToRelative(constraint);
			constraint.setSize(Dimension.max(constraint.getSize(),
					getMinimumSizeFor(createRequest)));
			constraint.setSize(Dimension.min(constraint.getSize(),
					getMaximumSizeFor(createRequest)));
			((GraphicalEditPart) getTargetEditPart()).getContentPane()
					.translateToRelative(constraint);
			createRequest.setSize(constraint.getSize());
		}
	}

	/**
	 * Determines the <em>maximum</em> size for CreateRequest's size on drop. It
	 * is called from {@link #enforceConstraintsForSizeOnDropCreate(CreateRequest)}
	 * during creation. By default, a large <code>Dimension</code> is returned.
	 * 
	 * @param request
	 *            the request.
	 * @return the minimum size
	 * @since 3.7
	 */
	protected Dimension getMaximumSizeFor(CreateRequest request) {
		return IFigure.MAX_DIMENSION;
		}

	/**
	 * Determines the <em>minimum</em> size for CreateRequest's size on drop. It
	 * is called from {@link #enforceConstraintsForSizeOnDropCreate(CreateRequest)}
	 * during creation. By default, a small <code>Dimension</code> is returned.
	 * 
	 * @param request
	 *            the request.
	 * @return the minimum size
	 * @since 3.7
	 */
	protected Dimension getMinimumSizeFor(CreateRequest request) {
		return IFigure.MIN_DIMENSION;
	}

}
