/******************************************************************************
 * Copyright (c) 2006, Intalio Inc.
 * 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:
 *     Intalio Inc. - initial API and implementation
 *******************************************************************************/

/** 
 * Date          	Author             Changes 
 * 12 Oct 2006   	ASerhiychuk         Created 
 **/

package org.eclipse.stp.bpmn.tools;

import java.util.List;

import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gmf.runtime.diagram.ui.editparts.GraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.tools.DragEditPartsTrackerEx;
import org.eclipse.stp.bpmn.diagram.edit.parts.PoolPoolCompartmentEditPart;
import org.eclipse.stp.bpmn.diagram.edit.parts.SubProcessSubProcessBodyCompartmentEditPart;

/**
 * @author Anton Serhiychuk
 * @author <a href="http://www.intalio.com">&copy; Intalio, Inc.</a>
 */
public class TaskDragEditPartsTrackerEx extends DragEditPartsTrackerEx {
    public TaskDragEditPartsTrackerEx(EditPart sourceEditPart) {
        super(sourceEditPart);
    }

    @Override
    protected void performDrag() {
        boolean reparentEnabled = isReparentEnabled();
        if (!reparentEnabled) {
            EditPart source = getSourceEditPart();
            EditPart parent = source.getParent();

            Rectangle parentBounds = ((GraphicalEditPart) parent).getFigure()
                    .getBounds();

            // get selected objects
            List selectedObjects = getCurrentViewer().getSelectedEditParts();

            // calculate selected objects bounds
            Rectangle selectionBounds = ((GraphicalEditPart) source)
                    .getFigure().getBounds().getCopy();

            for (Object item : selectedObjects) {
                if (item instanceof GraphicalEditPart) {
                    Rectangle itemBounds = ((GraphicalEditPart) item)
                            .getFigure().getBounds().getCopy();
                    selectionBounds.union(itemBounds);
                }
            }

            assert parent instanceof SubProcessSubProcessBodyCompartmentEditPart
                    || parent instanceof PoolPoolCompartmentEditPart;
            // command to change container figure bounds
            Command containerBoundsCommand = TaskDragHelper
                    .getNewContainerBoundsCommand((GraphicalEditPart) source,
                            selectedObjects, selectionBounds,
                            (GraphicalEditPart) parent.getParent(),
                            parentBounds, getDragMoveDelta());
            CompoundCommand currentCommand = (CompoundCommand) getCurrentCommand();

            // command to change container figure bounds
            currentCommand.add(containerBoundsCommand);
            super.performDrag();
            parent.refresh();
        } else {
            super.performDrag();
        }
    }

    /**
     * Determines wheter reparent is enabled. Returns <code>true</code> in
     * case if CTRL is pressed and source edit part has Pool Compartment parent
     * and has no connections to other edit parts.
     * 
     * @return <code>true</code> in case if CTRL is pressed and source edit
     *         part has Pool Compartment parent, <code>false</code> otherwise.
     */
    private boolean isReparentEnabled() {
        IGraphicalEditPart source = (IGraphicalEditPart) getSourceEditPart();
        return getCurrentInput().isControlKeyDown()
                && source.getParent() instanceof PoolPoolCompartmentEditPart
                && source.getSourceConnections().size() == 0
                && source.getTargetConnections().size() == 0;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.eclipse.gmf.runtime.diagram.ui.tools.DragEditPartsTrackerEx#isMove()
     */
    @Override
    protected boolean isMove() {
        boolean isMove;
        if (isReparentEnabled()) {
            isMove = super.isMove();
        } else {
            isMove = true;
        }
        return isMove;
    }

    /*
     * (non-Javadoc) Overriden to change clone mode in case if CTRL is pressed
     * and source edit part is over another pool.
     * 
     * @see org.eclipse.gef.tools.DragEditPartsTracker#setTargetEditPart(org.eclipse.gef.EditPart)
     */
    @Override
    protected void setTargetEditPart(EditPart editpart) {
        if (isReparentEnabled()) {
            setCloneActive(!(editpart instanceof PoolPoolCompartmentEditPart)
                    || editpart == getSourceEditPart().getParent());
        }
        super.setTargetEditPart(editpart);
    }
}
