/******************************************************************************
 * Copyright (c) 2002, 2008 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.gmf.runtime.diagram.ui.tools;

import java.util.Iterator;
import java.util.List;

import org.eclipse.draw2d.FigureCanvas;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.Viewport;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
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.commands.CompoundCommand;
import org.eclipse.gef.requests.ChangeBoundsRequest;
import org.eclipse.gef.tools.DragEditPartsTracker;
import org.eclipse.gef.tools.ToolUtilities;
import org.eclipse.gmf.runtime.diagram.ui.editparts.GroupEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.internal.ruler.SnapToHelperUtil;
import org.eclipse.gmf.runtime.diagram.ui.requests.DuplicateRequest;
import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants;
import org.eclipse.gmf.runtime.draw2d.ui.mapmode.MapModeUtil;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.widgets.Control;

/**
 * A dervied DragEditPartsTRacker that sends REQ_DRAG instead of REQ_ORPHAN
 * and REQ_DROP instead of REQ_ADD
 * 
 * @author melaasar
 */
public class DragEditPartsTrackerEx extends DragEditPartsTracker {

    /**
	 * @param sourceEditPart
	 */
	public DragEditPartsTrackerEx(EditPart sourceEditPart) {
		super(sourceEditPart);
	}

	/**
	 * @see org.eclipse.gef.tools.AbstractTool#getCommand()
	 */
	protected Command getCommand() {
		if (!isMove()) {
			CompoundCommand command = new CompoundCommand();
			addSourceCommands(false, command); 
			if (getTargetEditPart()!=null){
				command.add(getTargetEditPart().getCommand(getTargetRequest()));
				if (command.canExecute())
					return command;
			} 
			
			
		}
		CompoundCommand command = new CompoundCommand();
		addSourceCommands(true, command);
		return command;
	}

	/**
	 * Collects the move/drag commands from the operation set
	 * @param isMove
	 * @param command
	 */
	protected void addSourceCommands(boolean isMove, CompoundCommand command) {
        Request request = getTargetRequest();

        if (isCloneActive()) {

            // do not use operation set in this case as connections will get
            // filtered out
            List editparts = ToolUtilities
                .getSelectionWithoutDependants(getCurrentViewer());

            DuplicateRequest duplicateRequest = new DuplicateRequest();
            duplicateRequest.setEditParts(editparts);
            duplicateRequest.setExtendedData(request.getExtendedData());
            if (request instanceof ChangeBoundsRequest) {
                Point delta = ((ChangeBoundsRequest) request).getMoveDelta();
                MapModeUtil.getMapMode(
                    ((IGraphicalEditPart) getTargetEditPart()).getFigure())
                    .DPtoLP(delta);

                duplicateRequest.setOffset(delta);
            }
            command.add(getTargetEditPart().getCommand(duplicateRequest));
        } else {
            request.setType(isMove ? REQ_MOVE
                : RequestConstants.REQ_DRAG);
            Iterator iter = getOperationSet().iterator();
            while (iter.hasNext()) {
                EditPart editPart = (EditPart) iter.next();
                command.add(editPart.getCommand(request));
            }
        }

        request.setType(RequestConstants.REQ_DROP);
    }

	/**
	 * @see org.eclipse.gef.tools.AbstractTool#getCommandName()
	 */
	protected String getCommandName() {
		if (!isMove())
			return RequestConstants.REQ_DROP;
		return super.getCommandName();
	}

	/**
	 * If the source is not in the operation set, it is not a move
	 * @see org.eclipse.gef.tool s.DragEditPartsTracker#isMove()
	 */
	protected boolean isMove() {		
		for (int i = 0 ; i < getOperationSet().size(); i++){
			if (getOperationSet().get(i).equals(getSourceEditPart())){
				return super.isMove();
			}
			//additional case for GroupEditPart, check the children
			//this is for snap to geometry			
			if (getOperationSet().get(i) instanceof GroupEditPart){
				GroupEditPart currPart = (GroupEditPart)getOperationSet().get(i);
				for (int j = 0 ; j < currPart.getChildren().size() ; j++){
					if (currPart.getChildren().get(j).equals(getSourceEditPart())){
						return super.isMove();
					}
				}
			}
		}
		return false;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.gef.tools.AbstractTool#executeCurrentCommand()
	 */
	protected void executeCurrentCommand() {
		super.executeCurrentCommand();
		if (isActive()) {
			if (getOperationSet().size() > 0) {
				if (getOperationSet().get(0) instanceof IGraphicalEditPart) {
					IGraphicalEditPart editpart = (IGraphicalEditPart) getOperationSet()
						.get(0);
					if ((editpart.getFigure() == null)
						|| (editpart.getFigure().getParent() == null)
						|| (editpart.getFigure().getParent().getLayoutManager() == null))
						return;
					editpart.getFigure().getParent().getLayoutManager().layout(
						editpart.getFigure().getParent());
					reveal(editpart);
				}
			}
		}
	}
	
	/**
	 * @param editpart
	 */
	protected void reveal(EditPart editpart){
		editpart.getViewer().reveal(editpart);
	}
   
    protected boolean handleDragInProgress() {
        boolean returnValue = super.handleDragInProgress();
        if (isInState(STATE_DRAG_IN_PROGRESS)
            || isInState(STATE_ACCESSIBLE_DRAG_IN_PROGRESS)) {
            
            // Expose the diagram as the user scrolls in the area handled by the
            // autoexpose helper.
            updateAutoexposeHelper();
        }
        return returnValue;
    }

    protected Cursor calculateCursor() {
        if (isInState(STATE_DRAG_IN_PROGRESS)
            || isInState(STATE_ACCESSIBLE_DRAG_IN_PROGRESS)) {

            // Give some feedback so the user knows the area where autoscrolling
            // will occur.
            if (getAutoexposeHelper() != null) {
                return SharedCursors.HAND;
            } else {

                // Give some feedback so the user knows that they can't drag
                // outside the viewport.
                Control control = getCurrentViewer().getControl();
                if (control instanceof FigureCanvas) {
                    Viewport viewport = ((FigureCanvas) control).getViewport();
                    Rectangle rect = Rectangle.SINGLETON;
                    viewport.getClientArea(rect);
                    viewport.translateToParent(rect);
                    viewport.translateToAbsolute(rect);

                    if (!rect.contains(getLocation())) {
                        return getDisabledCursor();
                    }
                }
            }
        }
        return super.calculateCursor();
    }
    
    protected boolean handleButtonDown(int button) {

        // If the group is selected, and the user clicks on a shape, defer the
        // selection of the shape until the mouse button is released instead of
        // selecting on mouse down because if the user does a drag they will
        // move the entire group and not the shape.
        if (button == 1
            && getSourceEditPart().getParent() instanceof GroupEditPart
            && getSourceEditPart().getParent().getSelected() != EditPart.SELECTED_NONE) {

            stateTransition(STATE_INITIAL, STATE_DRAG);
            return true;
        }

        return super.handleButtonDown(button);
    }

    protected boolean handleDoubleClick(int button) {
        // If the user double-clicks a shape in a group and the shape is not
        // selected, select the shape.
        if (getSourceEditPart().getParent() instanceof GroupEditPart
            && getSourceEditPart().getSelected() == EditPart.SELECTED_NONE) {
            performSelection();
            return true;
        } else {
            return super.handleDoubleClick(button);
        }
    }

    protected void performSelection() {
        super.performSelection();

        // If the new selection is a child of a group, we want to deselect the group.
        if (getSourceEditPart().getParent() instanceof GroupEditPart
            && getSourceEditPart().getParent().getSelected() != EditPart.SELECTED_NONE) {
            getCurrentViewer().deselect(getSourceEditPart().getParent());
        }
    }
    
    /**
     * Overridden to add extended data to the request to restrict snapping to
     * specific directions based on the move delta.
     */
    protected void snapPoint(ChangeBoundsRequest request) {
        Point moveDelta = request.getMoveDelta();
        if (getState() == STATE_ACCESSIBLE_DRAG_IN_PROGRESS) {
            int restrictedDirection = 0;

            if (moveDelta.x > 0) {
                restrictedDirection = restrictedDirection
                    | PositionConstants.EAST;
            } else if (moveDelta.x < 0) {
                restrictedDirection = restrictedDirection
                    | PositionConstants.WEST;
            }

            if (moveDelta.y > 0) {
                restrictedDirection = restrictedDirection
                    | PositionConstants.SOUTH;
            } else if (moveDelta.y < 0) {
                restrictedDirection = restrictedDirection
                    | PositionConstants.NORTH;
            }

            request.getExtendedData().put(SnapToHelperUtil.RESTRICTED_DIRECTIONS,
                restrictedDirection);
        }

        super.snapPoint(request);
    }
    
    protected boolean handleKeyDown(KeyEvent e) {
        if (acceptArrowKey(e)) {
            if (isInState(STATE_INITIAL)) {
                IGraphicalEditPart ep = (IGraphicalEditPart) getSourceEditPart();
                if (ep != null) {
                    Point location = ep.getFigure().getBounds().getCenter();
                    ep.getFigure().translateToAbsolute(location);
                    placeMouseInViewer(location);       
                    getCurrentInput().setMouseLocation(location.x, location.y);
                }
            }
        }
        return super.handleKeyDown(e);
    }

}
