/**
 * File:    ActivityNodeEditPart.java
 * Created: 09.12.2005
 *
 *
/*******************************************************************************
 * 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.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.gef.EditPolicy;
import org.eclipse.jwt.meta.model.processes.ActivityNode;
import org.eclipse.jwt.meta.model.processes.ProcessesPackage;
import org.eclipse.jwt.meta.model.processes.impl.ActivityEdgeImpl;
import org.eclipse.jwt.we.misc.logging.Logger;
import org.eclipse.jwt.we.misc.views.Views;
import org.eclipse.jwt.we.parts.core.GraphicalElementEditPartHelper;
import org.eclipse.jwt.we.parts.core.NamedElementEditPart;
import org.eclipse.jwt.we.parts.processes.policies.ActivityNodeGraphicalNodeEditPolicy;

/**
 * EditPart for {@link ActivityNode}.
 * 
 * @version $Id: ActivityNodeEditPart.java,v 1.11 2009/11/26 12:41:36 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 ActivityNodeEditPart extends NamedElementEditPart
{

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

	/**
	 * Stores the maximum number of ingoing edges.
	 */
	private int maximumInEdges = Integer.MAX_VALUE;

	/**
	 * Stores the maximum number of outgoing edges.
	 */
	private int maximumOutEdges = Integer.MAX_VALUE;

	/**
	 * Helper for functions from the GraphicalElement.
	 */
	private final GraphicalElementEditPartHelper graphicalElementEditPartHelper = new GraphicalElementEditPartHelper(
			this);


	/**
	 * Default constructor.
	 */
	public ActivityNodeEditPart()
	{
	}


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


	/**
	 * @return Returns the maximumInEdges.
	 */
	protected int getMaximumInActivityEdges()
	{
		return maximumInEdges;
	}


	/**
	 * @param maximumInEdges
	 *            The maximumInEdges to set.
	 */
	public void setMaximumInActivityEdges(int maximumInEdges)
	{
		this.maximumInEdges = maximumInEdges;

		EditPolicy graphicalEditPolicy = getEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE);
		if (graphicalEditPolicy != null
				&& graphicalEditPolicy instanceof ActivityNodeGraphicalNodeEditPolicy)
		{
			((ActivityNodeGraphicalNodeEditPolicy) graphicalEditPolicy)
					.setMaximumInActivityEdges(maximumInEdges);
		}
	}


	/**
	 * @return Returns the maximumOutEdges.
	 */
	public int getMaximumOutActivityEdges()
	{
		return maximumOutEdges;
	}


	/**
	 * @param maximumOutEdges
	 *            The maximumOutEdges to set.
	 */
	public void setMaximumOutActivityEdges(int maximumOutEdges)
	{
		this.maximumOutEdges = maximumOutEdges;

		EditPolicy graphicalEditPolicy = getEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE);
		if (graphicalEditPolicy != null
				&& graphicalEditPolicy instanceof ActivityNodeGraphicalNodeEditPolicy)
		{
			((ActivityNodeGraphicalNodeEditPolicy) graphicalEditPolicy)
					.setMaximumOutActivityEdges(maximumOutEdges);
		}
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.gef.editparts.AbstractEditPart#createEditPolicies()
	 */
	@Override
	protected void createEditPolicies()
	{
		super.createEditPolicies();

		// allow the creation of connections and
		// and the reconnection of connections
		installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE,
				new ActivityNodeGraphicalNodeEditPolicy(getMaximumInActivityEdges(),
						getMaximumOutActivityEdges()));
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.emf.common.notify.Adapter#notifyChanged(org.eclipse.emf.common
	 * .notify .Notification)
	 */
	@Override
	public void notifyChanged(Notification notification)
	{
		// call super notify
		super.notifyChanged(notification);

		// call graphicalelement notify
		graphicalElementEditPartHelper.notifyChanged(notification);

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

		switch (notification.getEventType())
		{
			case Notification.ADD:
			case Notification.ADD_MANY:
			case Notification.REMOVE:
			case Notification.REMOVE_MANY:
				switch (featureId)
				{
					case ProcessesPackage.ACTIVITY_NODE__IN:
						refreshTargetConnections();
						break;

					case ProcessesPackage.ACTIVITY_NODE__OUT:
						refreshSourceConnections();
						break;
				}
		}
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.gef.editparts.AbstractEditPart#refreshVisuals()
	 */
	@Override
	protected void refreshVisuals()
	{
		super.refreshVisuals();

		graphicalElementEditPartHelper.refreshVisuals();
	}


	/**
	 * These methods return the outgoing edges of this node (non-Javadoc)
	 * 
	 * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#getModelSourceConnections()
	 */
	@Override
	protected List getModelSourceConnections()
	{
		List objectlist = ((ActivityNode) getModel()).getOut();
		List returnlist = new ArrayList();
		Views myviews = Views.getInstance();
		for (Object obj : objectlist)
		{
			ActivityEdgeImpl aei = (ActivityEdgeImpl) obj;
			ActivityNode targetActivityNode = aei.basicGetTarget();
			if (targetActivityNode == null)
			{
				// edges being built and not yet fully linked : when a
				// transition edge has already its source and its target is
				// being set
				returnlist.add(obj);
				continue;
			}
			EClass basicclass = aei.basicGetTarget().eClass();
			if (myviews.displayObject(basicclass))
			{
				returnlist.add(obj);
			}
		}

		return returnlist;
	}


	/**
	 * These methods return the ingoing edges of this node (non-Javadoc)
	 * 
	 * @see org.eclipse.gef.editparts.AbstractGraphicalEditPart#getModelTargetConnections()
	 */
	@Override
	protected List getModelTargetConnections()
	{
		List objectlist = ((ActivityNode) getModel()).getIn();
		List returnlist = new ArrayList();
		Views myviews = Views.getInstance();
		for (Object obj : objectlist)
		{
			ActivityEdgeImpl aei = (ActivityEdgeImpl) obj;
			ActivityNode sourceActivityNode = aei.basicGetSource();
			if (sourceActivityNode == null)
			{
				// edges being built and not yet fully linked : when a
				// transition edge has already its source and its target is
				// being set
				returnlist.add(obj);
				continue;
			}
			EClass basicclass = aei.basicGetSource().eClass();
			if (myviews.displayObject(basicclass))
			{
				returnlist.add(obj);
			}
		}

		return returnlist;
	}


	/**
	 * Creates the ConnectionAnchor for this EditPart.
	 * 
	 * Subclasses should overwrite this method, if they need a different anchor.
	 * 
	 * @return The connection anchor
	 */
	@Override
	protected ConnectionAnchor createConnectionAnchor()
	{
		return new ChopboxAnchor(getFigure());
	}
}
