/**
 * File:    ActionEditPart.java
 * Created: 19.01.2006
 *
 *
/*******************************************************************************
 * Copyright (c) 2005-2011
 * University of Augsburg, Germany <www.ds-lab.org>
 *
 * 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:
 *    Markus Bauer, Programming distributed Systems Lab, University of Augsburg 
 *    	- initial API and implementation
 *******************************************************************************/

package org.eclipse.jwt.we.parts.processes;

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

import org.eclipse.draw2d.ChopboxAnchor;
import org.eclipse.draw2d.ConnectionAnchor;
import org.eclipse.draw2d.IFigure;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.ConnectionEditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.Request;
import org.eclipse.jwt.meta.model.processes.Action;
import org.eclipse.jwt.meta.model.processes.ActivityEdge;
import org.eclipse.jwt.meta.model.processes.Scope;
import org.eclipse.jwt.we.figures.processes.DiamondAnchor;
import org.eclipse.jwt.we.misc.logging.Logger;
import org.eclipse.jwt.we.misc.util.EMFHelper;
import org.eclipse.jwt.we.misc.views.Views;
import org.eclipse.jwt.we.model.view.Diagram;
import org.eclipse.jwt.we.model.view.ReferenceEdge;
import org.eclipse.jwt.we.model.view.ViewPackage;
import org.eclipse.jwt.we.parts.processes.policies.ActionGraphicalNodeEditPolicy;
import org.eclipse.jwt.we.parts.view.ReferenceEdgeEditPart;

/**
 * EditPart for an {@link Action}. It also creates/removes the
 * {@link ReferenceEdge}s if the corresponding feature is set
 * 
 * @version $Id: ActionEditPart.java,v 1.13 2009-12-21 10:30:47 chsaad Exp $
 * @author Markus Bauer (markusbauer@users.sourceforge.net), Programming
 *         distributed Systems Lab, University of Augsburg, Germany,
 *         www.ds-lab.org
 * @since 0.5.0
 */
public class ActionEditPart extends ExecutableNodeEditPart
{

	/**
	 * A Logger.
	 */
	@SuppressWarnings("unused")
	private static final Logger logger = Logger.getLogger(ActionEditPart.class);

	/**
	 * Maximum number of ingoing edges from action nodes.
	 */
	private static final int MAXIMUM_IN_EDGES = 1;

	/**
	 * Maximum number of outgoing edges from action nodes.
	 */
	private static final int MAXIMUM_OUT_EDGES = 1;


	/**
	 * Default Constructor, empty.
	 */
	public ActionEditPart()
	{
		setMaximumInActivityEdges(MAXIMUM_IN_EDGES);
		setMaximumOutActivityEdges(MAXIMUM_OUT_EDGES);
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jwt.we.parts.EditPartAdapterSupport#getModelClass()
	 */
	@Override
	public Class getModelClass()
	{
		return Action.class;
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @seeorg.eclipse.jwt.we.parts.processes.ActivityNodeEditPart#
	 * getModelSourceConnections()
	 */
	@Override
	protected List getModelSourceConnections()
	{
		List conns = new BasicEList(super.getModelSourceConnections());
		List referenceedges = EMFHelper.getReferenceEdgesForAction(getWEEditor(),
				(Action) getModel());
		List newreferencelist = new ArrayList();

		for (Object obj : referenceedges)
		{
			ReferenceEdge refedge = (ReferenceEdge) obj;
			if (refedge.getReference() != null
					&& refedge.getReference().getReference() != null
					&& Views.getInstance().displayObject(
							refedge.getReference().getReference().eClass()))
			{
				newreferencelist.add(obj);
			}
		}

		conns.addAll(newreferencelist);
		return conns;
	}


	@Override
	public ConnectionAnchor getSourceConnectionAnchor(ConnectionEditPart connection)
	{
		if (connection instanceof ActivityEdgeEditPart)
		{
			return createActivityEdgeConnectionAnchor();
		}
		if (connection instanceof ReferenceEdgeEditPart)
		{
			return createReferenceEdgeConnectionAnchor();
		}

		return super.getSourceConnectionAnchor(connection);
	}


	@Override
	public ConnectionAnchor getSourceConnectionAnchor(Request request)
	{
		// return super.getSourceConnectionAnchor(request);
		return createReferenceEdgeConnectionAnchor();
	}


	/**
	 * @return The scope in which the model is contained.
	 */
	protected Scope getScope()
	{
		return (Scope) ((EObject) getModel()).eContainer();
	}


	/**
	 * @return The action model.
	 */
	protected Action getAction()
	{
		return (Action) getModel();
	}


	@Override
	protected void createEditPolicies()
	{
		super.createEditPolicies();

		installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE,
				new ActionGraphicalNodeEditPolicy(getMaximumInActivityEdges(),
						getMaximumOutActivityEdges()));
	}


	@Override
	protected IFigure createFigure()
	{
		setDoDirectEdit(true);

		return super.createFigure();
	}


	@Override
	protected ConnectionAnchor createConnectionAnchor()
	{
		return createActivityEdgeConnectionAnchor();
	}


	/**
	 * Creates a {@link ConnectionAnchor} for an {@link ActivityEdge}.
	 * 
	 * @return The anchor.
	 */
	protected ConnectionAnchor createActivityEdgeConnectionAnchor()
	{
		return new DiamondAnchor(getFigure());
	}


	/**
	 * Creates a {@link ConnectionAnchor} for an {@link ReferenceEdge}.
	 * 
	 * @return The anchor.
	 */
	protected ConnectionAnchor createReferenceEdgeConnectionAnchor()
	{
		// TODO should be a roundedRectangle anchor
		return new ChopboxAnchor(getFigure());
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.jwt.we.parts.processes.ActivityNodeEditPart#notifyChanged
	 * (org.eclipse .emf.common.notify.Notification)
	 */
	@Override
	public void notifyChanged(Notification notification)
	{
		super.notifyChanged(notification);
		int featureId = notification.getFeatureID(Diagram.class);

		switch (featureId)
		{
			// REFERENCEEDGES
			case ViewPackage.DIAGRAM__REFERENCE_EDGES:
				refreshSourceConnections();
				break;
		}
	}

}
