/*******************************************************************************
 * Copyright (c) 2007, 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:
 * 	   Wind River Systems - Pawel Piech - Initial Implementation - Drag/Drop to Expressions View (Bug 184057), Integration with non-standard debug models (Bug 209883)
 *     IBM Corporation - further implementation and documentation
 *     Wind River Systems - integration with non-standard debug models
 *******************************************************************************/
package org.eclipse.debug.internal.ui.views.expression;

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

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.IExpressionManager;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IDebugElement;
import org.eclipse.debug.core.model.IExpression;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.debug.core.model.IWatchExpression;
import org.eclipse.debug.internal.core.ExpressionManager;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.internal.ui.viewers.model.provisional.TreeModelViewer;
import org.eclipse.debug.internal.ui.views.variables.IndexedVariablePartition;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapter;
import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapter2;
import org.eclipse.debug.ui.actions.IWatchExpressionFactoryAdapterExtension;
import org.eclipse.jface.util.LocalSelectionTransfer;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ViewerDropAdapter;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.TransferData;

/**
 * Drop Adapter allowing expressions, variables and text to be dropped in the Expression View.
 * When IVariables or text is dropped new watch expressions are created at the drop location.
 * When IExpressions are dropped, they are moved to the drop location
 * 
 * @see org.eclipse.debug.internal.ui.views.variables.VariablesDragAdapter
 * @see ExpressionManager
 * @since 3.4
 */
public class ExpressionDropAdapter extends ViewerDropAdapter {

	private TransferData fCurrentTransferType = null;
	private boolean fInsertBefore;
	private int fDropType;
	
	private static final int DROP_TYPE_DEFAULT = 0;
	private static final int DROP_TYPE_VARIABLE = 1;
	private static final int DROP_TYPE_EXPRESSION = 2;
    private static final int DROP_TYPE_WATCH_ADAPTABLE_ELEMENT = 3;

    /**
     * Constructor takes the viewer this drop adapter applies to.
     * @param viewer the viewer to add drop to
     */
    protected ExpressionDropAdapter(TreeModelViewer viewer) {
        super(viewer);
        setFeedbackEnabled(true);
        setSelectionFeedbackEnabled(false);
        setScrollExpandEnabled(false);
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.viewers.ViewerDropAdapter#dragEnter(org.eclipse.swt.dnd.DropTargetEvent)
     */
    public void dragEnter(DropTargetEvent event) {
    	fDropType = DROP_TYPE_DEFAULT;
        event.detail = DND.DROP_NONE;
        
    	for (int i = 0; i < event.dataTypes.length; i++) {
            if (LocalSelectionTransfer.getTransfer().isSupportedType(event.dataTypes[i])) {
                if (isExpressionDrop()){
                    event.currentDataType = event.dataTypes[i];
                    event.detail = DND.DROP_MOVE;
                    fDropType = DROP_TYPE_EXPRESSION;
                    break;
                } else if (isVariableDrop()){
                    event.currentDataType = event.dataTypes[i];
                    event.detail = DND.DROP_COPY;
                    fDropType = DROP_TYPE_VARIABLE;
                    break;
                } else if (isWatchAdaptableElementDrop()){
                    event.currentDataType = event.dataTypes[i];
                    event.detail = DND.DROP_COPY;
                    fDropType = DROP_TYPE_WATCH_ADAPTABLE_ELEMENT;
                    break;
                }
            } else if (TextTransfer.getInstance().isSupportedType(event.dataTypes[i])) {
                event.currentDataType = event.dataTypes[i];
                event.detail = DND.DROP_COPY;
                fDropType = DROP_TYPE_DEFAULT;
                break;
            }
        }

        super.dragEnter(event);
    }
    
    /**
     * @return whether the selection transfer contains only IExpressions
     */
    private boolean isExpressionDrop() {
	    IStructuredSelection selection = (IStructuredSelection) LocalSelectionTransfer.getTransfer().getSelection();
	    Iterator iterator = selection.iterator();
	    while (iterator.hasNext()) {
	    	Object element = iterator.next();
	        if (getTargetExpression(element) == null){
	        	return false;
	        }
	    }
	    return true;
	}

	/**
	 * @return whether the selection transfer contains only IVariables
	 */
	private boolean isVariableDrop() {
	    IStructuredSelection selection = (IStructuredSelection) LocalSelectionTransfer.getTransfer().getSelection();
	    Iterator iterator = selection.iterator();
	    while (iterator.hasNext()) {
	    	Object element = iterator.next();
	        if (!(element instanceof IVariable)){
	        	return false;
	        }
	    }
	    return true;
	}

   /**
     * @return whether the selection transfer contains only objects adaptable 
     * to IWatchExpressionFactoryAdapter2
     */
    private boolean isWatchAdaptableElementDrop() {
        IStructuredSelection selection = (IStructuredSelection) LocalSelectionTransfer.getTransfer().getSelection();
        Iterator iterator = selection.iterator();
        while (iterator.hasNext()) {
            Object element = iterator.next();
            if (!(element instanceof IAdaptable && 
                ((IAdaptable)element).getAdapter(IWatchExpressionFactoryAdapter2.class) != null))
            {
                return false;
            }
        }
        return true;
    }

	/* (non-Javadoc)
	 * @see org.eclipse.jface.viewers.ViewerDropAdapter#dragOver(org.eclipse.swt.dnd.DropTargetEvent)
	 */
	public void dragOver(DropTargetEvent event) {
    	super.dragOver(event);
        // Allow scrolling (but not expansion)
    	event.feedback |= DND.FEEDBACK_SCROLL;
    }

    /* (non-Javadoc)
     * @see org.eclipse.jface.viewers.ViewerDropAdapter#validateDrop(java.lang.Object, int, org.eclipse.swt.dnd.TransferData)
     */
    public boolean validateDrop(Object target, int operation, TransferData transferType) {
        if (LocalSelectionTransfer.getTransfer().isSupportedType(transferType)) {
        	if (fDropType == DROP_TYPE_EXPRESSION){
        		return validateExpressionDrop(target);
        	} else if (fDropType == DROP_TYPE_VARIABLE){
        		return validateVariableDrop(target);
            } else if (fDropType == DROP_TYPE_WATCH_ADAPTABLE_ELEMENT){
                return validateWatchAdaptableDrop(target);
            }
        } else if (TextTransfer.getInstance().isSupportedType(transferType)) {
            return validateTextDrop(target);
        }
        return false;
    }

	/**
	 * Validates if an IExpression drop is valid by checking if the target
	 * is an IExpression.
	 * @param target target of the drop
	 * @return whether the drop is valid
	 */
	private boolean validateExpressionDrop(Object target){
		return target instanceof IExpression || 
		       ((target instanceof IAdaptable) && ((IAdaptable)target).getAdapter(IExpression.class) != null);
	}

	private IExpression getTargetExpression(Object target) {
	    if (target instanceof IExpression) {
	        return (IExpression)target;
	    } else if (target instanceof IAdaptable) {
	        return (IExpression)((IAdaptable)target).getAdapter(IExpression.class);
	    }
	    return null;
	}
	
	/**
	 * Validates if the drop is valid by validating the local selection transfer 
	 * to ensure that a watch expression can be created for each contained IVariable.
	 * @param target target of the drop
	 * @return whether the drop is valid
	 */
	private boolean validateVariableDrop(Object target) {
		// Target must be null or an IExpression, you cannot add a new watch expression inside another
		if (target != null && getTargetExpression(target) == null) {
		    return false;
		}
		
	    IStructuredSelection selection = (IStructuredSelection) LocalSelectionTransfer.getTransfer().getSelection();
	    int enabled = 0;
	    int size = -1;
	    if (selection != null) {
	        size = selection.size();
	        IExpressionManager manager = DebugPlugin.getDefault().getExpressionManager();
	        Iterator iterator = selection.iterator();
	        while (iterator.hasNext()) {
	            Object element = iterator.next();
	            if (element instanceof IVariable){
	                IVariable variable = (IVariable) element;
	                if (variable instanceof IndexedVariablePartition) {
	                    break;
	                } else if (manager.hasWatchExpressionDelegate(variable.getModelIdentifier()) && isFactoryEnabled(variable)) {
	                    enabled++;
	                } else {
	                    break;
	                }
	            }
	        }
	    }
	    return enabled == size;
	}

	/**
     * Validates if the drop is valid by validating the local selection transfer 
     * to ensure that a watch expression can be created for each contained element.
     * @param target target of the drop
     * @return whether the drop is valid
     */
    private boolean validateWatchAdaptableDrop(Object target) {
        // Target must be null or an IExpression, you cannot add a new watch expression inside another
        if (target != null && getTargetExpression(target) == null) {
            return false;
        }
        
        IStructuredSelection selection = (IStructuredSelection) LocalSelectionTransfer.getTransfer().getSelection();
        int enabled = 0;
        int size = -1;
        if (selection != null) {
            size = selection.size();
            Iterator iterator = selection.iterator();
            while (iterator.hasNext()) {
                Object element = iterator.next();
                if (isFactory2Enabled(element)) {
                    enabled++;
                } else {
                    break;
                }
            }
        }
        return enabled == size;
    }

	/**
	 * Validates if the drop is valid by validating the drop location.
	 * Only valid if the target is <code>null</code> or an <code>IExpression</code>.
	 * You cannot add a new watch expression inside another.
	 * @param target target of the drop
	 * @return whether the drop is valid
	 */
	private boolean validateTextDrop(Object target){
        return target == null || getTargetExpression(target) != null;
	}

	/**
	 * Returns whether the factory adapter for the given variable is currently enabled.
	 * 
	 * @param variable the variable to ask for the adapter
	 * @return whether the factory is enabled
	 */
	private boolean isFactoryEnabled(IVariable variable) {
	    IWatchExpressionFactoryAdapter factory = getFactory(variable);
	    if (factory instanceof IWatchExpressionFactoryAdapterExtension) {
	        IWatchExpressionFactoryAdapterExtension ext = (IWatchExpressionFactoryAdapterExtension) factory;
	        return ext.canCreateWatchExpression(variable);
	    }
	    return true;
	}

   /**
     * Returns whether the factory adapter for the given element is currently enabled.
     * 
     * @param element the element to ask for the adapter
     * @return whether the factory is enabled
     */
    private boolean isFactory2Enabled(Object element) {
        IWatchExpressionFactoryAdapter2 factory = getFactory2(element);
        if (factory != null) {
            return factory.canCreateWatchExpression(element);
        }
        return false;
    }

	/* (non-Javadoc)
	 * @see org.eclipse.jface.viewers.ViewerDropAdapter#drop(org.eclipse.swt.dnd.DropTargetEvent)
	 */
	public void drop(DropTargetEvent event) {
	    fCurrentTransferType = event.currentDataType;
	    // Unless insert after is explicitly set, insert before
	    fInsertBefore = getCurrentLocation() != LOCATION_AFTER;
	    super.drop(event);
	}

	/* (non-Javadoc)
     * @see org.eclipse.jface.viewers.ViewerDropAdapter#performDrop(java.lang.Object)
     */
    public boolean performDrop(Object data) {
        if (LocalSelectionTransfer.getTransfer().isSupportedType(fCurrentTransferType)) {
            IStructuredSelection selection = (IStructuredSelection) LocalSelectionTransfer.getTransfer().getSelection();
            if (fDropType == DROP_TYPE_EXPRESSION){
            	return performExpressionDrop(selection);
            } else if (fDropType == DROP_TYPE_VARIABLE || fDropType == DROP_TYPE_WATCH_ADAPTABLE_ELEMENT){
            	return performVariableOrWatchAdaptableDrop(selection);
            }
        } else if (TextTransfer.getInstance().isSupportedType(fCurrentTransferType)) {
            if (data != null) {
            	return performTextDrop((String)data);
            }
        }
        return false;
    }

    /**
     * Performs the drop when the selection is a collection of IExpressions.
     * Moves the given expressions from their original locations to the
     * location of the current target.
     * @param selection the dragged selection
     * @return whether the drop could be completed
     */
    private boolean performExpressionDrop(IStructuredSelection selection) {
        IExpression targetExpression = getTargetExpression(getCurrentTarget());
		if (targetExpression != null){
			IExpression[] expressions = new IExpression[selection.size()];
			Object[] selectionElements = selection.toArray();
			for (int i = 0; i < selectionElements.length; i++) {
			    expressions[i] = getTargetExpression(selectionElements[i]);
			}
	    	
	    	IExpressionManager manager = DebugPlugin.getDefault().getExpressionManager();
	    	if (manager instanceof ExpressionManager){
	    		((ExpressionManager)manager).moveExpressions(expressions, targetExpression, fInsertBefore);
	    	}
	    	return true;
		}
		return false;
		
	}

	/**
     * If the dragged data is a structured selection, get any IVariables in it 
     * and create expressions for each of them.  Insert the created expressions
     * at the currently selected target or add them to the end of the collection
     * if no target is selected.
     * 
     * @param selection Structured selection containing IVariables
     * @return whether the drop was successful
     */
    private boolean performVariableOrWatchAdaptableDrop(IStructuredSelection selection) {
        List expressions = new ArrayList(selection.size());
    	for (Iterator itr = selection.iterator(); itr.hasNext(); ) {
            Object element = itr.next();
        	String expressionText = createExpressionString(element);
        	if (expressionText != null){
            	IExpression expression = createExpression(expressionText);
            	if (expression != null){
            		expressions.add(expression);
            	} else {
            		DebugUIPlugin.log(new Status(IStatus.ERROR,DebugUIPlugin.getUniqueIdentifier(),"Drop failed.  Watch expression could not be created for the text " + expressionText)); //$NON-NLS-1$
            		return false;
            	}
        	} else {
        		return false;
        	}
        }
    	if (expressions.size() == selection.size()){
    		IExpressionManager manager = DebugPlugin.getDefault().getExpressionManager();
	    	if (manager instanceof ExpressionManager){
	            IExpression targetExpression = getTargetExpression(getCurrentTarget());
	            if (targetExpression != null){
	    			((ExpressionManager)manager).insertExpressions((IExpression[])expressions.toArray(new IExpression[expressions.size()]), targetExpression, fInsertBefore);
	    		} else {
	    			((ExpressionManager)manager).addExpressions((IExpression[])expressions.toArray(new IExpression[expressions.size()]));
	    		}
	    		return true;
	    	}
    	}
    	return false;
    }


    /**
     * Performs the drop when text was dragged.  Creates a new watch expression from
     * the text.  Inserts the expression at the currently selected target or adds it
     * to the end of the collection if no target is selected.
     * 
     * @param text string to use to create the expression
     * @return whether the drop was successful
     */
    private boolean performTextDrop(String text){
    	IExpression expression = createExpression(text);
    	if (expression != null){
    		IExpressionManager manager = DebugPlugin.getDefault().getExpressionManager();
	    	if (manager instanceof ExpressionManager){
	            IExpression targetExpression = getTargetExpression(getCurrentTarget());
	            if (targetExpression != null){
	    			((ExpressionManager)manager).insertExpressions(new IExpression[]{expression}, targetExpression, fInsertBefore);
	    		} else {
	    			((ExpressionManager)manager).addExpression(expression);
	    		}
	    		return true;
	    	}
    	}
    	DebugUIPlugin.log(new Status(IStatus.ERROR,DebugUIPlugin.getUniqueIdentifier(),"Drop failed.  Watch expression could not be created for the text " + text)); //$NON-NLS-1$
    	return false;
    }
    
    /**
     * Creates a new watch expression from an IVariable using the watch expression factory
     * adapter for that variable.
     * 
     * @param variable the variable to use to create the watch expression
     * @return the string to be used to create expression, return <code>null</code> 
     * if no expression is to be created
     */
    private String createExpressionString(Object element) {
        try {
            if (element instanceof IVariable) {
                IVariable variable = (IVariable)element;
                IWatchExpressionFactoryAdapter factory = getFactory(variable);
                String exp = variable.getName();
                if (factory != null) {
                	//if a factory exists, use it to create expression, 
                	//otherwise just use variable name
                    exp = factory.createWatchExpression(variable);
                }
                return exp;
            } else {
                IWatchExpressionFactoryAdapter2 factory2 = getFactory2(element);
                if (factory2 != null) {
                    return factory2.createWatchExpression(element);
                } 
            }
        } catch (CoreException e) {
            DebugUIPlugin.log(e.getStatus());
        }
        return null;
    }

    /**
     * Creates a new watch expression from a string using the default expression manager.
     * 
     * @param exp the string to use to create the expression
     */
    private IExpression createExpression(String exp) {
        IWatchExpression expression = DebugPlugin.getDefault().getExpressionManager().newWatchExpression(exp);
        IAdaptable object = DebugUITools.getDebugContext();
        IDebugElement context = null;
        if (object instanceof IDebugElement) {
            context = (IDebugElement) object;
        } else if (object instanceof ILaunch) {
            context = ((ILaunch) object).getDebugTarget();
        }
        expression.setExpressionContext(context);
        return expression;
    }
    
   
    /**
     * Returns the factory adapter for the given variable or <code>null</code> if none.
     * 
     * @param variable
     * @return factory or <code>null</code>
     */
    private IWatchExpressionFactoryAdapter getFactory(IVariable variable) {
        return (IWatchExpressionFactoryAdapter) variable.getAdapter(IWatchExpressionFactoryAdapter.class);      
    }

    /**
     * Returns the factory adapter for the given element or <code>null</code> if none.
     * 
     * @param element
     * @return factory or <code>null</code>
     */
    private IWatchExpressionFactoryAdapter2 getFactory2(Object element) {
        if (element instanceof IAdaptable) {
            return (IWatchExpressionFactoryAdapter2)((IAdaptable)element).getAdapter(IWatchExpressionFactoryAdapter2.class);
        }
        return null;
    }

}
