/*******************************************************************************
 * Copyright (c) 2005, 2012 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.bpel.ui.editparts;

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

import org.eclipse.bpel.model.Activity;
import org.eclipse.bpel.model.Sequence;
import org.eclipse.bpel.ui.BPELUIPlugin;
import org.eclipse.bpel.ui.IHoverHelper;
import org.eclipse.bpel.ui.IHoverHelperSupport;
import org.eclipse.bpel.ui.adapters.AdapterNotification;
import org.eclipse.bpel.ui.adapters.IContainer;
import org.eclipse.bpel.ui.editparts.policies.BPELComponentEditPolicy;
import org.eclipse.bpel.ui.editparts.policies.BPELDirectEditPolicy;
import org.eclipse.bpel.ui.editparts.policies.BPELOrderedLayoutEditPolicy;
import org.eclipse.bpel.ui.extensions.BPELUIRegistry;
import org.eclipse.bpel.ui.figures.CenteredConnectionAnchor;
import org.eclipse.bpel.ui.util.BPELCellEditorLocator;
import org.eclipse.bpel.ui.util.BPELDirectEditManager;
import org.eclipse.bpel.ui.util.BPELDragEditPartsTracker;
import org.eclipse.bpel.ui.util.BPELUtil;
import org.eclipse.bpel.ui.util.ModelHelper;
import org.eclipse.bpel.ui.util.MultiObjectAdapter;
import org.eclipse.bpel.ui.util.marker.BPELEditPartMarkerDecorator;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.draw2d.ConnectionAnchor;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.AccessibleAnchorProvider;
import org.eclipse.gef.AccessibleEditPart;
import org.eclipse.gef.DragTracker;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.Request;
import org.eclipse.gef.RequestConstants;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.editparts.AbstractGraphicalEditPart;
import org.eclipse.gef.tools.DirectEditManager;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.jface.viewers.TextCellEditor;


/**
 * The superclass of all BPEL edit parts. Provides a listener on the model
 * which calls the handleModelChanged() method.
 */
@SuppressWarnings("nls")
public abstract class BPELEditPart extends AbstractGraphicalEditPart implements IHoverHelperSupport {

	/**
	 *  The amount of spacing to place between child items. Subclasses
	 */
	public static final int SPACING = 14;
	
	static protected String EMPTY_STRING = "";
	
	protected AccessibleEditPart acc;

	protected MultiObjectAdapter adapter;
	
	protected BPELEditPartMarkerDecorator.MarkerMotionListener markerMotionListener;
	
	// The direct edit manager handles the in-place editing of node names on the graphical canvas.
	private DirectEditManager manager;

	// Mouse motion hover help support
	protected int mouseLocation = 0; // 0 == no marker, 1 == top drawer, 2 == bottom drawer, 3 == marker on main figure
	
	/**
	 * Create a new BPELEditPart.
	 * 
	 * Construct the model adapter.
	 */
	public BPELEditPart() {
		adapter = new MultiObjectAdapter() {
			
			@Override
			public void notify(Notification n) {
				int eventGroup = n.getEventType() / 100;
				if (eventGroup == AdapterNotification.NOTIFICATION_MARKERS_CHANGED_GROUP ) {					
					refreshVisuals();
					return ;
				}
				
				
				// TODO: check if we care about this notification
				if (isActive()) {
					handleModelChanged();
				}
				refreshAdapters();
			}
		};
	}
	
	/**
	 * Default implementation based on IContainer.  Should be sufficient except in
	 * special cases (such as ProcessEditPart?). 
	 */
	@Override
	protected List getModelChildren() {
		IContainer container = BPELUtil.adapt(getModel(), IContainer.class);
		if (container != null) {
			return container.getChildren(getModel());
		}
		return super.getModelChildren();
	}

	protected void addAllAdapters() {
		EObject modelObject = (EObject)getModel();  
		adapter.addToObject(modelObject);
		
		// if the object has an extension, add adapter to that too
		EObject extension = ModelHelper.getExtension(modelObject);
		if (extension != null) adapter.addToObject(extension);
		// if the object contains an implicit sequence, add adapter to that also
		try {
			Activity activity = ModelHelper.getActivity(modelObject);
			if (activity instanceof Sequence) {
				// TODO: perhaps we should check and make sure it's an implicit sequence!
				// for now, don't worry about it.
				adapter.addToObject(activity);
			}
		} catch (IllegalArgumentException e) {
			// it's not a single-activity container.  ignore.
		}
		// ..but we probably don't need an adapter on the implicit sequence...
	}
	
	protected void removeAllAdapters() {
		adapter.removeFromAll();
	}
	
	protected void refreshAdapters() {
		removeAllAdapters();
		addAllAdapters();
	}
	
	/**
	 * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#activate()
	 */
	@Override
	public void activate() {
		if (isActive()) {
			return;
		}
		super.activate();
		addAllAdapters();
	}

	/**
	 * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#deactivate()
	 */
	@Override
	public void deactivate() {
		if (!isActive()) {
			return;		
		}
		removeAllAdapters();
		super.deactivate();
		clearConnections();					
	}

	
	@Override
	protected void createEditPolicies() {
		// The COMPONENT_ROLE policy determines how an edit part is deleted.
		installEditPolicy(EditPolicy.COMPONENT_ROLE, new BPELComponentEditPolicy());

		// The DIRECT_EDIT_ROLE policy determines how in-place editing takes place.
		installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, new BPELDirectEditPolicy());
	}
	
	
	/**
	 * The model has changed. Perform any actions necessary to ensure that the
	 * edit part, model and graphical representation are in sync.
	 * 
	 * Subclasses may override but should call super.
	 */
	protected void handleModelChanged() {
		// If property name is children, refresh children.
		// If property name is size or location, refresh visuals.
		// TODO: refresh connections in there somewhere too!
		refreshChildren();
		refreshVisuals();
		
		refresh();
	}
	
	/**
	 * Get an anchor at the given location for this edit part.
	 * 
	 * This must be called after the figure for this edit part has been created.
	 * @param location 
	 * @return 
	 */
	public ConnectionAnchor getConnectionAnchor(int location) {
		return new CenteredConnectionAnchor(getFigure(), location, 0);
	}

	/**
	 * Return whether or not the edit part can execute the given request.
	 * The answer is determined by asking each edit policy and returning
	 * true if any policy can execute the request.
	 * @param request 
	 * @return 
	 */
	public boolean canExecuteRequest(Request request) {
		EditPolicyIterator i = getEditPolicyIterator();
		while (i.hasNext()) {
			Command cm= i.next().getCommand(request);
			if (cm != null)
				if (cm.canExecute())
					return true;
		}
		return false;
	}

	/**
	 * Override to handle direct edit requests
	 */
	@Override
	public void performRequest(Request request) {
		if (request.getType() == RequestConstants.REQ_DIRECT_EDIT) {
			performDirectEdit();
		} else {
			super.performRequest(request);
		}
	}

	/**
	 * Return whether the receiver can perform direct edit.
	 */
	public boolean canPerformDirectEdit() {
		return getLabelFigure() != null;
	}
	
	/**
	 * Invoke direct edit on the receiver
	 */
	public void performDirectEdit() {
		if (getLabelFigure() != null) {
			// make sure we can execute it through
			Command cmd = BPELDirectEditPolicy.getFinalizeCommand(this.getModel(), "blahblah"); //$NON-NLS-1$
			if (cmd == null || !cmd.canExecute())
				return;
			
			if (manager == null) {
				manager = new BPELDirectEditManager(this, TextCellEditor.class,
						new BPELCellEditorLocator(getLabelFigure()), getLabelValidator());
			}
			manager.show();
		}
	}
	
	/**
	 * Return the label that should be used for direct edit.
	 * 
	 * The default implementation returns null.
	 * 
	 * Subclasses should override to return the appropriate label.
	 */
	public Label getLabelFigure() {
		return null;
	}

	/**
	 * Return the text to display in the label for the edit part.
	 * 
	 * The default implementation returns null.
	 * 
	 * Subclasses should override to return the appropriate text.
	 */
	public String getLabelContent() {
		return null;
	}
	
	/**
	 * Set the text to display in the label for the edit part.
	 * 
	 * The default implementation does nothing.
	 * 
	 * Subclasses should override to set the label to the given string.
	 */
	public void setLabelContent(String str) {
	}
	
	/**
	 * TODO: visibility increased (from protected) so I could move the edit
	 * policies to a separate package.  In future, we should change it back.
	 */
	
	@Override
	public void refreshVisuals() {
		super.refreshVisuals();
		refreshHoverHelp();
	}
	
	@Override
	protected void refreshChildren() {		
		super.refreshChildren();
		
		// Not the most logical place to refresh connections, but it
		// needs to be refreshed after the children are refreshed		
		//TODO: May make more sense to put connections into adapter
		// so connections are not refreshed unnecessarily
		refreshConnections();
	}

	protected void refreshConnections(){
		EditPolicy policy = getEditPolicy(EditPolicy.LAYOUT_ROLE);
		if (policy instanceof BPELOrderedLayoutEditPolicy){
			((BPELOrderedLayoutEditPolicy)policy).refreshConnections();
		}
	}
	
	protected void clearConnections(){
		EditPolicy policy = getEditPolicy(EditPolicy.LAYOUT_ROLE);
		if (policy instanceof BPELOrderedLayoutEditPolicy){
			((BPELOrderedLayoutEditPolicy)policy).clearConnections();
		}
	}
	
	@Override
	public Object getAdapter(Class key) {
		if (key.isInstance(getModel())) {
			return getModel();
		}
		
		if (key == AccessibleAnchorProvider.class) {
			return new DefaultAccessibleAnchorProvider() {
				private List<Point> getDefaultLocations() {
					List<Point> list = new ArrayList<Point>();
					Rectangle r = getFigure().getBounds();
					
					// when calculating the target in connection tools, it was targettig
					// the object behind the figure we were interested in, so adding an addition
					// fudge factor to -2 helps make sure we hit the right target
					Point p = r.getTopRight().translate(-r.width / 2, r.height / 3);
					getFigure().translateToAbsolute(p);
					list.add(p);
					return list;
				}
				/**
				 * @see AccessibleAnchorProvider#getSourceAnchorLocations()
				 */
				@Override
				public List<Point> getSourceAnchorLocations() {
					return getDefaultLocations();
				}
				/**
				 * @see AccessibleAnchorProvider#getTargetAnchorLocations()
				 */
				@Override
				public List<Point> getTargetAnchorLocations() {
					return getDefaultLocations();
				}
			};
		}
		return super.getAdapter(key);
	}
	
	public void regenerateVisuals() {
	}
	
	// increase visibility!
	@Override
	public void refreshSourceConnections() { super.refreshSourceConnections(); }
	@Override
	public void refreshTargetConnections() { super.refreshTargetConnections(); }
	
	public void refreshHoverHelp() {
		// Refresh the tooltip if we can find a helper.
		try {
			IHoverHelper helper = BPELUIRegistry.getInstance().getHoverHelper();
			if (helper != null) {
				IFigure tooltip = helper.getHoverFigure((EObject)getModel());
				getFigure().setToolTip(tooltip);
			}
		} catch (CoreException e) {
			getFigure().setToolTip(null);
			BPELUIPlugin.log(e);
		}		
	}
	
	@Override
	protected IFigure createFigure() {
		return null;
	}

	@Override
	protected AccessibleEditPart getAccessibleEditPart() {
		if (acc == null) acc = createAccessible();
		return acc;
	}
	
	protected AccessibleEditPart createAccessible() {
		return BPELUtil.getAccessibleEditPart(this);
	}

	protected BPELEditPartMarkerDecorator.MarkerMotionListener getMarkerMotionListener() {
		return markerMotionListener = new BPELEditPartMarkerDecorator.MarkerMotionListener() {
			public void markerEntered(IMarker marker) {
				// refresh the hover help for this marker.
				mouseLocation = 3;
				refreshHoverHelp();
			}
		};	
	}
	
	@Override
	public DragTracker getDragTracker(Request request) {
		return new BPELDragEditPartsTracker(this);
	}
	
	/**
	 * Returns the label validator for this part or <code>null</code> if not applicable. The
	 * default behavior is to return <code>null</code>. Subclasses may override this method.
	 */
	protected IInputValidator getLabelValidator() {
		return null;
	}
}
