/*******************************************************************************
 * Copyright (c) 2006 Sybase, Inc. 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:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.pagedesigner.itemcreation;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.SharedCursors;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.tools.TargetingTool;
import org.eclipse.jst.jsf.common.dom.TagIdentifier;
import org.eclipse.jst.jsf.core.internal.tld.TagIdentifierFactory;
import org.eclipse.jst.pagedesigner.commands.CreateItemCommand;
import org.eclipse.jst.pagedesigner.editors.palette.TagToolPaletteEntry;
import org.eclipse.jst.pagedesigner.elementedit.ElementEditFactoryRegistry;
import org.eclipse.jst.pagedesigner.elementedit.IElementEdit;
import org.eclipse.jst.pagedesigner.itemcreation.customizer.IDropCustomizer;
import org.eclipse.swt.graphics.Cursor;

/**
 * This Tool is used to create items. It is to replace the default CreationTool
 * of GEF. We are not using CreationToolEntry for creating item, since the
 * default GEF implementation require creating of the object before drop into
 * the view. We do not want to create the XML element (and possibly its taglib
 * declaration) before the drop is really performed.)
 * 
 * @author mengbo
 */
public class ItemCreationTool extends TargetingTool {
	TagToolPaletteEntry _tagPaletteItem; //can we get rid of this?

	/**
	 * Default constructor. Sets the default and disabled cursors.
	 * @param tagToolPaletteEntryItem 
	 */
	public ItemCreationTool(TagToolPaletteEntry tagToolPaletteEntryItem) {
		setDefaultCursor(SharedCursors.CURSOR_TREE_ADD);
		setDisabledCursor(SharedCursors.NO);

		this._tagPaletteItem = tagToolPaletteEntryItem;  
	}

	/**
	 * @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 ItemCreationRequest}and sets this tool's factory on the
	 * request.
	 * 
	 * @see org.eclipse.gef.tools.TargetingTool#createTargetRequest()
	 */
	protected Request createTargetRequest() {
		ItemCreationRequest request = new ItemCreationRequest();
		request.setTagToolPaletteEntry(_tagPaletteItem);
		return request;
	}

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

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

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

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

	/**
	 * 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)) {
			if (getTargetEditPart() != null) {
				getCreateRequest().setLocation(getLocation());
				lockTargetEditPart(getTargetEditPart());
				// Snap only when size on drop is employed
				// TODO: never read 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)) 
		{
			eraseTargetFeedback();
			unlockTargetEditPart();
			
			// customizer may cancel the drop
			customizeDropAndMaybeExecute(button);
		}
		
		setState(STATE_TERMINAL);
		handleFinished();

		return true;
	}

	/**
	 * @param button
	 */
	protected void customizeDropAndMaybeExecute(final int button)
	{
        Command command = getCurrentCommand();
        
        int status = IStatus.OK;
        if (command instanceof CreateItemCommand)
        {
            status = performCustomization((CreateItemCommand)command);
        }
        
        if (status == IStatus.OK)
        {
            performCreation(button);
        }
	}

	private int performCustomization(CreateItemCommand command)
	{
	    IStatus status = Status.OK_STATUS;
	    TagIdentifier tagId = 
	        TagIdentifierFactory.createJSPTagWrapper
	            (_tagPaletteItem.getURI(), _tagPaletteItem.getTagName());
	    
	    IElementEdit elementEdit = ElementEditFactoryRegistry.getInstance().createElementEdit(tagId);

	    if (elementEdit != null)
	    {
	        IDropCustomizer customizer = elementEdit.getDropCustomizer(tagId);
    	    
    	    if (customizer != null)
    	    {
        	    status = customizer.runCustomizer();
        	    
        	    if (status.getSeverity() == IStatus.OK)
        	    {
        	        command.setCustomizationData(customizer.getDropCustomizationData());
        	    }
    	    }
	    }
	    return status.getSeverity();
	}

	/**
	 * 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) {
		executeCurrentCommand();
		// selectAddedObject();
	}

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

	/**
	 * 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() {
		ItemCreationRequest req = getCreateRequest();
		req.setLocation(getLocation());
		// if (isInState(STATE_DRAG_IN_PROGRESS)) {
		// Point loq = getStartLocation();
		// req.setLocation(bounds.getLocation());
		// req.getExtendedData().clear();
		// if (!getCurrentInput().isAltKeyDown() && helper != null) {
		// PrecisionRectangle baseRect = new PrecisionRectangle(bounds);
		// PrecisionRectangle result = baseRect.getPreciseCopy();
		// helper.snapRectangle(req, PositionConstants.NSEW,
		// baseRect, result);
		// req.setLocation(result.getLocation());
		// req.setSize(result.getSize());
		// }
		// } else {
		// req.setLocation(getLocation());
		// }
	}

}
