/******************************************************************************
 * 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 
 * 11 Ρεπ 2006   	MPeleshchyshyn  	Created 
 **/

package org.eclipse.stp.bpmn.tools;

import java.lang.reflect.Field;

import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.Request;
import org.eclipse.gef.palette.ToolEntry;
import org.eclipse.gef.tools.AbstractTool;
import org.eclipse.gef.tools.SelectionTool;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.ITextAwareEditPart;
import org.eclipse.gmf.runtime.diagram.ui.requests.RequestConstants;

/**
 * Extends the default selection tool and overrides it to behave in this manner:
 * <ul>
 * <li>on drag always always make a selection request unless the curosr is
 * over the bpmn pool's label or the sub-process label or the sub-process
 * is collapsed.
 * In order to be a little less bpmn only related, we do this based
 * on the nature of the editpart.<li>
 * <li>double-click will issue a direct-edit request
 * on either the ITextAwareEditPart or the PrimaryChild of the focused
 * editpart if that primary child is an ITextAwareEditPart.</li>
 * </ul>
 * 
 * @author hmalphettes
 * @author <a href="http://www.intalio.com">&copy; Intalio, Inc.</a>
 */
public class SelectionToolEx extends SelectionTool {

    //helper
    private static Field toolClassField;

    private static void init() {
        if (toolClassField != null) {
            return;
        }
        try {
            toolClassField = ToolEntry.class.getDeclaredField("toolClass");
            toolClassField.setAccessible(true);
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    }

    public static void setToolClass(ToolEntry toolEntry, Class toolClass) {
        init();
        try {
            toolClassField.set(toolEntry, toolClass);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //--helper
//direct edit on double-click
    /**
     * Issues direct-edit request if the edit-part looks like it should receive
     * such request
     * @see AbstractTool#handleButtonDown(int)
     */
    @Override
    protected boolean handleDoubleClick(int button) {
        if (isHoverActive()) {
            handleHoverStop();
            setHoverActive(false);
        }
        EditPartViewer viewer = getCurrentViewer();
        if (viewer instanceof GraphicalViewer &&
                 (isInState(STATE_DRAG) || isInState(STATE_INITIAL))) {
            EditPart selectedEditPart =
                ((GraphicalViewer)viewer).getFocusEditPart();
            if (!(selectedEditPart instanceof ITextAwareEditPart)
                    && selectedEditPart instanceof IGraphicalEditPart) {
                    IGraphicalEditPart nodePart =
                        (IGraphicalEditPart) selectedEditPart;
                    EditPart primEditPart = nodePart.getPrimaryChildEditPart();
                    if (primEditPart != null &&
                            primEditPart instanceof ITextAwareEditPart) {
                        ITextAwareEditPart textPart =
                            (ITextAwareEditPart) primEditPart;
                        selectedEditPart = textPart;
                        
                        //at this point we could decide to edit only if the label
                        //is in fact null or empty.
                        
                        //if (textPart.getEditLabel() != null
                        //|| && textPart.getEditLabel().getLength() > 0) {
                        //return false;
                        
                        
                        //if above is not commented, double-clicking anywhere
                        //on the task even outside of its label
                        //will put the label in edit mode
                        
                    }
            }
            if (selectedEditPart instanceof ITextAwareEditPart) {
                Request request = new Request(RequestConstants.REQ_DIRECT_EDIT);
                selectedEditPart.performRequest(request);
                return true;
            }
        }

        return false;
    }
//-- end of the direct-edit requests on double-click.

}
