/*****************************************************************************
 * Copyright (c) 2011 CEA LIST.
 *
 * 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:
 *
 *		CEA LIST - Initial API and implementation
 *
 *****************************************************************************/
package org.eclipse.papyrus.sysml.diagram.common.edit.part;

import java.util.Collections;
import java.util.List;

import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.LayoutListener;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.Request;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.editpolicies.LayoutEditPolicy;
import org.eclipse.gef.editpolicies.NonResizableEditPolicy;
import org.eclipse.gef.handles.MoveHandle;
import org.eclipse.gef.requests.CreateRequest;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IBorderItemEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;
import org.eclipse.gmf.runtime.diagram.ui.figures.IBorderItemLocator;
import org.eclipse.gmf.runtime.notation.NotationPackage;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.papyrus.gmf.diagram.common.edit.policy.ExternalLabelPrimaryDragRoleEditPolicy;
import org.eclipse.papyrus.infra.gmfdiag.common.editpart.IPapyrusEditPart;
import org.eclipse.papyrus.sysml.diagram.common.Activator;
import org.eclipse.papyrus.sysml.diagram.common.figure.FlowPortFigure;
import org.eclipse.papyrus.sysml.diagram.common.utils.SysMLGraphicalTypes;
import org.eclipse.papyrus.sysml.portandflows.FlowPort;
import org.eclipse.papyrus.sysml.portandflows.PortandflowsPackage;
import org.eclipse.papyrus.uml.diagram.common.edit.part.AbstractElementBorderEditPart;
import org.eclipse.papyrus.uml.diagram.common.edit.part.AbstractElementLabelEditPart;
import org.eclipse.papyrus.uml.diagram.common.editpolicies.AppliedStereotypeIconlDisplayEditPolicy;
import org.eclipse.papyrus.uml.diagram.common.editpolicies.AppliedStereotypeLabelDisplayEditPolicy;
import org.eclipse.papyrus.uml.diagram.common.editpolicies.ShowHideLabelEditPolicy;
import org.eclipse.papyrus.uml.diagram.common.figure.node.IPapyrusUMLElementFigure;
import org.eclipse.papyrus.uml.diagram.common.locator.ExternalLabelPositionLocator;
import org.eclipse.swt.graphics.Image;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.util.UMLUtil;

/**
 * This class implements an edit part for FlowPort represented as border items.
 */
public class FlowPortAffixedNodeEditPart extends AbstractElementBorderEditPart {

	private LayoutListener.Stub layoutInitializationListener;

	public FlowPortAffixedNodeEditPart(View view) {
		super(view);
	}

	@Override
	protected void createDefaultEditPolicies() {
		super.createDefaultEditPolicies();
		installEditPolicy(AppliedStereotypeLabelDisplayEditPolicy.STEREOTYPE_LABEL_POLICY, new AppliedStereotypeIconlDisplayEditPolicy() {

			/**
			 * <pre>
			 * {@inheritDoc}
			 *
			 * This modifies the edit policy in order to call refreshVisuals() whenever the stereotype image to show is null.
			 * (required to show the FlowPort default image correctly).
			 * </pre>
			 */
			@Override
			protected void refreshStereotypeDisplay() {
				if (getHost() instanceof IPapyrusEditPart) {
					IFigure figure = ((IPapyrusEditPart) getHost()).getPrimaryShape();

					if ((figure instanceof IPapyrusUMLElementFigure) && (stereotypeIconToDisplay() != null)) {
						((IPapyrusUMLElementFigure) figure).setStereotypeDisplay(null, stereotypeIconToDisplay());
					} else {
						refreshVisuals();
					}
				}
			}

		});

		installEditPolicy(ShowHideLabelEditPolicy.SHOW_HIDE_LABEL_ROLE, new ShowHideLabelEditPolicy());
	}

	@Override
	protected LayoutEditPolicy createLayoutEditPolicy() {
		org.eclipse.gmf.runtime.diagram.ui.editpolicies.LayoutEditPolicy lep = new org.eclipse.gmf.runtime.diagram.ui.editpolicies.LayoutEditPolicy() {

			@Override
			protected EditPolicy createChildEditPolicy(EditPart child) {
				if (child instanceof IBorderItemEditPart) { // External labels
					return new ExternalLabelPrimaryDragRoleEditPolicy() {

						@Override
						@SuppressWarnings("rawtypes")
						protected List createSelectionHandles() {
							MoveHandle mh = new MoveHandle((GraphicalEditPart) getHost());
							mh.setBorder(null);
							return Collections.singletonList(mh);
						}
					};
				}

				EditPolicy result = child.getEditPolicy(EditPolicy.PRIMARY_DRAG_ROLE);
				if (result == null) {
					result = new NonResizableEditPolicy();
				}
				return result;
			}

			@Override
			protected Command getMoveChildrenCommand(Request request) {
				return null;
			}

			@Override
			protected Command getCreateCommand(CreateRequest request) {
				return null;
			}
		};
		return lep;
	}

	@Override
	protected void addBorderItem(IFigure borderItemContainer, IBorderItemEditPart borderItemEditPart) {
		IBorderItemLocator locator = new ExternalLabelPositionLocator(getMainFigure());
		borderItemContainer.add(borderItemEditPart.getFigure(), locator);
		return;
	}

	@Override
	public EditPart getPrimaryChildEditPart() {
		return getChildBySemanticHint(SysMLGraphicalTypes.AFFIXEDLABEL_SYSML_FLOWPORT_LABEL_ID);
	}

	@Override
	protected void addSemanticListeners() {

		if (resolveSemanticElement() != null) {

			FlowPort flowPort = UMLUtil.getStereotypeApplication((Element) resolveSemanticElement(), FlowPort.class);
			if (flowPort != null) {
				addListenerFilter("FlowPort", this, flowPort); //$NON-NLS-1$
			}
		}

		super.addSemanticListeners();
	}

	@Override
	protected void removeSemanticListeners() {
		removeListenerFilter("FlowPort"); //$NON-NLS-1$
		super.removeSemanticListeners();
	}

	/**
	 * <pre>
	 * Calls the figure refresh when a change event is detected on
	 * UMLPackage.eINSTANCE.getProperty_Aggregation().
	 *
	 * {@inheritDoc}
	 * </pre>
	 */
	@Override
	protected void handleNotificationEvent(Notification event) {

		// When the flow port position changes, its position on parent side may change and requires a visual refresh.
		Object feature = event.getFeature();
		if (NotationPackage.eINSTANCE.getSize_Width().equals(feature) || NotationPackage.eINSTANCE.getSize_Height().equals(feature) || NotationPackage.eINSTANCE.getLocation_X().equals(feature) || NotationPackage.eINSTANCE.getLocation_Y().equals(feature)) {
			refreshVisuals();
		}

		// A visual refresh may also be needed when the following properties are changing : isAtomic (depend on the type), direction, isConjugated.
		if (resolveSemanticElement() != null) {
			Element element = (Element) resolveSemanticElement();
			FlowPort flowPort = UMLUtil.getStereotypeApplication(element, FlowPort.class);

			if ((flowPort != null) && (flowPort.equals(event.getNotifier()))) {
				if (PortandflowsPackage.eINSTANCE.getFlowPort_Direction().equals(event.getFeature())
						// || PortandflowsPackage.eINSTANCE.getFlowPort_IsAtomic().equals(event.getFeature())
						|| PortandflowsPackage.eINSTANCE.getFlowPort_IsConjugated().equals(event.getFeature())) {
					refreshVisuals();
				}
			}

			// IsAtomic change is triggered by a type change
			if (resolveSemanticElement().equals(event.getNotifier())) {
				if (UMLPackage.eINSTANCE.getTypedElement_Type().equals(event.getFeature())) {
					refreshVisuals();
				}
			}
		}

		super.handleNotificationEvent(event);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected IFigure createNodeShape() {
		return primaryShape = new FlowPortFigure();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public FlowPortFigure getPrimaryShape() {
		return (FlowPortFigure) primaryShape;
	}

	/**
	 * <pre>
	 * Refresh the figure with the flow port image.
	 *
	 * {@inheritDoc}
	 * </pre>
	 */
	@Override
	protected void refreshVisuals() {
		super.refreshVisuals();

		int side = getBorderItemLocator().getCurrentSideOfParent();
		if (side == 0) {
			getBorderItemLocator().getCurrentSideOfParent();
		}

		Element element = (Element) resolveSemanticElement();
		FlowPort flowPort = UMLUtil.getStereotypeApplication(element, FlowPort.class);

		Image image = Activator.getInstance().getFlowPortImage(flowPort, side);
		getPrimaryShape().setImage(image);
	}

	/**
	 * <pre>
	 * A post layout listener is added during activate and remove the first time the layout occurs.
	 * This is required in order to be able to find the side of this border item on its parent when opening the model.
	 * Without this, the locator is unable to guess the parent side because the parent constraint is not set yet.
	 *
	 * Once the initialization is done, the listener become useless and can be removed.
	 *
	 * {@inheritDoc}
	 * </pre>
	 */
	@Override
	public void activate() {

		layoutInitializationListener = new LayoutListener.Stub() {

			@Override
			public void postLayout(IFigure container) {
				refreshVisuals();
				// getBorderedFigure().getBorderItemContainer().removeLayoutListener(layoutInitializationListener);
				layoutInitializationListener = null;
			}
		};
		getBorderedFigure().getBorderItemContainer().addLayoutListener(layoutInitializationListener);

		super.activate();
	}

	/**
	 * {@inheritDoc}
	 */

	@Override
	protected void addChildVisual(EditPart childEditPart, int index) {
		if (addFixedChild(childEditPart)) {
			return;
		}
		super.addChildVisual(childEditPart, -1);
	}


	/**
	 * {@inheritDoc}
	 */

	@Override
	protected void removeChildVisual(EditPart childEditPart) {
		if (removeFixedChild(childEditPart)) {
			return;
		}
		super.removeChildVisual(childEditPart);
	}


	/**
	 * {@inheritDoc}
	 */
	protected boolean addFixedChild(EditPart childEditPart) {
		if (childEditPart instanceof FlowPortAffixedLabelNameEditPart) {
			((FlowPortAffixedLabelNameEditPart) childEditPart).setLabel(getPrimaryShape().getNameLabel());
			IFigure borderItemContainer = getContentPaneFor((IGraphicalEditPart) childEditPart);
			addBorderItem(borderItemContainer, (IBorderItemEditPart) childEditPart);
			return true;
		}
		return false;
	}

	/**
	 * {@inheritDoc}
	 */
	protected boolean removeFixedChild(EditPart childEditPart) {
		if (childEditPart instanceof FlowPortAffixedLabelNameEditPart) {
			return true;
		}
		return false;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void removeChild(EditPart child) {
		if (child instanceof AbstractElementLabelEditPart) {
			return;
		}
		super.removeChild(child);
	}

}
