/**
 * File:    ReferenceEdgeEditPart.java
 * Created: 27.02.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.view;

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PolygonDecoration;
import org.eclipse.draw2d.PolylineConnection;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.editpolicies.ConnectionEndpointEditPolicy;
import org.eclipse.jwt.meta.model.application.Application;
import org.eclipse.jwt.meta.model.core.ReferenceableElement;
import org.eclipse.jwt.meta.model.data.Data;
import org.eclipse.jwt.meta.model.organisations.Role;
import org.eclipse.jwt.meta.model.processes.Action;
import org.eclipse.jwt.we.model.view.EdgeDirection;
import org.eclipse.jwt.we.model.view.Reference;
import org.eclipse.jwt.we.model.view.ReferenceEdge;
import org.eclipse.jwt.we.model.view.ViewPackage;
import org.eclipse.jwt.we.parts.core.EdgeModelElementEditPart;
import org.eclipse.jwt.we.parts.processes.ActionEditPart;


/**
 * EditPart for an {@link ReferenceEdge}.
 * 
 * A {@link ReferenceEdge} is created indirectly by adding an {@link ReferenceableElement}
 * to an {@link Action} so that either: - the {@link Action} is executed by
 * Reference.getReference() ({@link Application}) - the {@link Action} is performed by
 * Reference.getReference() ({@link Role}) - the {@link Action} has
 * Reference.getReference() as Input and/or Output ({@link Data})
 * 
 * If the {@link Reference} is input data it is an "in" edge, if it is output data it is
 * an "out" edge, if it is both it is an "inout" edge. Otherwise it is an default edge.
 * 
 * {@link ActionEditPart} actually creates and/or removes the corresponding
 * {@link ReferenceEdge}s in ActionEditPart#notifyChanged()
 * 
 * 
 * @version $Id: ReferenceEdgeEditPart.java,v 1.3 2009-11-26 12:41:50 chsaad Exp $
 * @author Markus Bauer (markusbauer@users.sourceforge.net), Programming distributed
 *         Systems Lab, University of Augsburg, Germany, www.ds-lab.org
 * @since 0.6.0
 */
public class ReferenceEdgeEditPart
		extends EdgeModelElementEditPart
{

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


	/**
	 * @return The {@link ReferenceEdge} model.
	 */
	public ReferenceEdge getReferenceEdge()
	{
		return (ReferenceEdge) getModel();
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jwt.we.parts.core.EdgeModelElementEditPart#createEditPolicies()
	 */
	@Override
	protected void createEditPolicies()
	{
		super.createEditPolicies();

		installEditPolicy(EditPolicy.CONNECTION_ENDPOINTS_ROLE,
				new ConnectionEndpointEditPolicy());
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jwt.we.parts.core.EdgeModelElementEditPart#createFigure()
	 */
	@Override
	protected IFigure createFigure()
	{
		PolylineConnection connection = (PolylineConnection) super.createFigure();

		setDecorations(connection);

		return connection;
	}


	/**
	 * Set source and target decorations according to direction of the edge.
	 * 
	 * @param connection
	 *            The figure.
	 */
	protected void setDecorations(PolylineConnection connection)
	{
		EdgeDirection direction = ((ReferenceEdge) getModel()).getDirection();

		if (direction == EdgeDirection.IN
				|| direction == EdgeDirection.INOUT)
		{
			connection.setSourceDecoration(new PolygonDecoration());
		}
		else
		{
			connection.setSourceDecoration(null);
		}

		if (direction == EdgeDirection.OUT
				|| direction == EdgeDirection.INOUT)
		{
			connection.setTargetDecoration(new PolygonDecoration());
		}
		else
		{
			connection.setTargetDecoration(null);
		}
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.jwt.we.parts.core.EdgeModelElementEditPart#notifyChanged(org.eclipse
	 * .emf.common.notify.Notification)
	 */
	@Override
	public void notifyChanged(Notification notification)
	{
		super.notifyChanged(notification);

		int featureId = notification.getFeatureID(ReferenceEdge.class);

		switch (notification.getEventType())
		{
			case Notification.SET:
			case Notification.UNSET:
				switch (featureId)
				{
					case ViewPackage.REFERENCE_EDGE__DIRECTION:
						setDecorations((PolylineConnection) getFigure());
						break;
				}
				break;
		}
	}

}
