/*******************************************************************************
 * 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.Collections;
import java.util.List;

import org.eclipse.bpel.common.ui.markers.IModelMarkerConstants;
import org.eclipse.bpel.model.Activity;
import org.eclipse.bpel.model.Link;
import org.eclipse.bpel.model.Source;
import org.eclipse.bpel.model.Sources;
import org.eclipse.bpel.model.Target;
import org.eclipse.bpel.model.Targets;
import org.eclipse.bpel.ui.BPELUIPlugin;
import org.eclipse.bpel.ui.GraphicalBPELRootEditPart;
import org.eclipse.bpel.ui.IBPELUIConstants;
import org.eclipse.bpel.ui.IHoverHelper;
import org.eclipse.bpel.ui.adapters.IMarkerHolder;
import org.eclipse.bpel.ui.editparts.borders.DrawerBorder;
import org.eclipse.bpel.ui.editparts.policies.BPELGraphicalEditPolicy;
import org.eclipse.bpel.ui.extensions.BPELUIRegistry;
import org.eclipse.bpel.ui.figures.CenteredConnectionAnchor;
import org.eclipse.bpel.ui.util.BPELUtil;
import org.eclipse.bpel.ui.util.ModelHelper;
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.MouseEvent;
import org.eclipse.draw2d.MouseMotionListener;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.ConnectionEditPart;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.NodeEditPart;
import org.eclipse.gef.Request;


/**
 * ActivityEditPart is the graphical GEF edit part representing a BPEL Activity.
 * It implements NodeEditPart because activities can be the source and the target of
 * connections in the graph. These connections include flow links as well as implicit
 * control flow connections, often determined by the node's parent.
 */
public abstract class ActivityEditPart extends BPELEditPart implements NodeEditPart {

	private MouseMotionListener mouseMotionListener;
	
	/**
	 * Brand new shiny ActivityEditPart.
	 */
	public ActivityEditPart() {
		super();
	}

	@Override
	protected void addAllAdapters() {
		super.addAllAdapters();
		
		Sources sources = getActivity().getSources();
		
		
		if (sources != null) {
			adapter.addToObject(sources);
			for(Source source : sources.getChildren()) {
				adapter.addToObject(source);
			}
//			
//			for (Iterator it = sources.getChildren().iterator(); it.hasNext(); ) {
//				Source source = (Source)it.next();
//				// also include the link, if there is one (since we indirectly
//				// control the activation of the LinkEditPart)
//				if (source.getLink() != null) adapter.addToObject(source.getLink());
//
//				// Okay--the real problem here, is that the Activity might be
//				// referred to by a Source object, but the Activity is not going
//				// to find out about the creation of a new Sources that references
//				// it.  Therefore, our model listeners don't know what to do!
//				
//				// TODO: temporarily hacked around in FlowEditPart.FlowContentAdapter.
//				
//				// TODO: also include any parent flows, and the Links object of
//				// any parent flows that have one.  !
//				// TODO: in future, use a global listener to handle refreshing the
//				// correct source editpart.
//			}			
		}

		Targets targets = getActivity().getTargets();
		if (targets != null) {
			adapter.addToObject(targets);
			for( Target target : targets.getChildren()) {
				adapter.addToObject(target);
			}						
		}
	}
	
	/**
	 * Install the BPELGraphicalEditPolicy as GRAPHICAL_NODE_ROLE. This policy allows
	 * the graphical creation of flow links between activities.
	 */
	@Override
	protected void createEditPolicies() {
		super.createEditPolicies();
		installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, new BPELGraphicalEditPolicy());
	}

	/**
	 * The model is the source of the following connections:
	 * - Any flow links that the model is the source of
	 * - Any other connections that the model's parent determines the model is the source of
	 */	
	@Override
	protected List<Link> getModelSourceConnections() {
		Sources sources = getActivity().getSources();
		if (sources == null) {
			return Collections.emptyList();
		}
		List<Link> result = new ArrayList<Link>();
		for(Source source : sources.getChildren()) {
			if (source.getLink() != null) {
				result.add(source.getLink());
			}
		}
		return result;
	}

	/**
	 * The model is the target of the following connections:
	 * - Any flow links that the model is the target of
	 * - Any other connections that the model's parent determines the model is the target of
	 */
	@Override
	protected List<Link> getModelTargetConnections() {
		Targets targets = getActivity().getTargets();
		if (targets == null) {
			return Collections.emptyList();
		}
		List<Link> result = new ArrayList<Link>();
		for(Target target : targets.getChildren()) {
			if (target.getLink() != null) {
				result.add(target.getLink());
			}				
		}
		return result;
	}
	
	/**
	 * Returns the connection anchor of a source connection which
	 * is at the given point.
	 * 
	 * @return  ConnectionAnchor.
	 */
	public ConnectionAnchor getSourceConnectionAnchor(Request request) {
		// TODO: Translate point to figure, call other method
		return getSourceConnectionAnchor((ConnectionEditPart)null);
	}
	
	/**
	 * Returns the connection anchor of a target connection which
	 * is at the given point.
	 *
	 * @return  ConnectionAnchor.
	 */
	public ConnectionAnchor getTargetConnectionAnchor(Request request) {
		// TODO: Translate point to figure, call other method
		return getTargetConnectionAnchor((ConnectionEditPart)null);
	}
	
	/**
	 * Because ActivityEditPart implements NodeEditPart, there may be connections
	 * to or from this node that are affected by model changes. Refresh the
	 * connections now.
	 * 
	 * If the model change involves the addition of an ActivityExtension, add an adapter
	 * to that extension.
	 */
	@Override
	protected void handleModelChanged() {
		super.handleModelChanged();
		refreshSourceConnections();
		refreshTargetConnections();
	}
	
	/**
	 * Convenience method to get the model as a BPEL Activity
	 * @return the model as a BPEL activity
	 */
	public Activity getActivity() {
		return (Activity) getModel();
	}
	
	/** 
	 * Override so we can set the constraint for every XY placed object
	 */
	
	@Override
	public void refreshVisuals() {
		Rectangle r = null;
		
		if (this.getParent() instanceof FlowEditPart) {
			EditPart root = getRoot();
			if (root instanceof GraphicalBPELRootEditPart) {
				Point p = ModelHelper.getLocation(getActivity());
				if (p.x == Integer.MIN_VALUE) {
					// HACK: We don't know its position, pretend it's at 0, 0.  This should only
					// be necessary during brief edge-case situations (like during startup before
					// we've done auto-layout on flows without metadata)..
					p = new Point(0, 0);
				}
				Dimension s = new Dimension(-1, -1);
				r = new Rectangle(p, s);
			}
		}

		if (r != null) {
			((GraphicalEditPart) getParent()).setLayoutConstraint(this, getFigure(), r);
		}
		super.refreshVisuals();
	}

	public ConnectionAnchor getTargetConnectionAnchorForTargetChild(ConnectionEditPart connEditPart) {
		return null;
	}
	
	protected void refreshDrawerHoverHelp() {
		
		IHoverHelper helper = null;
		
		try {
			helper = BPELUIRegistry.getInstance().getHoverHelper();
			if (helper == null) {
				return ;
			}
		}  catch (CoreException ce) {
			getFigure().setToolTip(null);
			BPELUIPlugin.log(ce);
			return ;
		}
		
	
		// Get the marker and pass it to the hover helper
		ArrayList<IMarker> listOfMarkers = new ArrayList<IMarker>();
		
		IMarkerHolder holder = BPELUtil.adapt(getActivity(), IMarkerHolder.class);
		
		for (IMarker m : holder.getMarkers(getActivity()) ) {
			
			// if we can't see it, then we will not look at it
			if (m.getAttribute(IModelMarkerConstants.DECORATION_MARKER_VISIBLE_ATTR, true) == false) {
				continue;
			}
			
			String where = m.getAttribute(IModelMarkerConstants.DECORATION_GRAPHICAL_MARKER_ANCHOR_POINT_ATTR,EMPTY_STRING); 
			
			if (mouseLocation == 1) {
				// Top drawer
				if (where.equals( IBPELUIConstants.MARKER_ANCHORPOINT_DRAWER_TOP )) {
					listOfMarkers.add(m);
				}
								
			} else {
				// bottom drawer
				if (where.equals( IBPELUIConstants.MARKER_ANCHORPOINT_DRAWER_BOTTOM )) {
					listOfMarkers.add(m);
				}
			}			
		}
		
		if (listOfMarkers.size() == 0) {
			return;
		}
		String text = null;
		
		if (listOfMarkers.size() == 1) {
			text = helper.getHoverHelp( listOfMarkers.get(0) );
		} else {
			StringBuilder sb = new StringBuilder();
			sb.append("There are ").append(listOfMarkers.size()).append(" issues here:\n");
			for(IMarker m : listOfMarkers) {
				String t = helper.getHoverHelp (m) ;
				sb.append("o ").append(t).append("\n");
			}
			text = sb.toString();
		}
				
		if (text == null || text.length() < 1) {
			getFigure().setToolTip(null);
		} else {
			getFigure().setToolTip(new Label(text));
		}
	}
	
	
	
	protected MouseMotionListener getMouseMotionListener() {
		if (mouseMotionListener == null) {
			this.mouseMotionListener = new MouseMotionListener() {
				public void mouseDragged(MouseEvent me) {
				}
				public void mouseEntered(MouseEvent me) {
				}
				public void mouseExited(MouseEvent me) {
				}
				public void mouseHover(MouseEvent me) {
				}
				public void mouseMoved(MouseEvent me) {
					DrawerBorder border = getDrawerBorder();
					if (border == null) return;
					int inTop = border.isPointInTopDrawer(me.x, me.y) ? 1 : 0;
					int inBottom = border.isPointInBottomDrawer(me.x, me.y) ? 2 : 0;
					// If mouse stayed in the same place it was in last time, do nothing
					int newLocation = inTop | inBottom;
					if (newLocation == mouseLocation) return;
					mouseLocation = newLocation;
					refreshHoverHelp();
				}
			};
		}
		return mouseMotionListener;
	}
	protected abstract DrawerBorder getDrawerBorder();
	
	/**
	 * Override the refreshHoverHelp method from BPELEditPart. This method
	 * will refresh either the regular hover help, or the drawer hover help
	 * if that is what is currently being displayed.
	 */
	
	@Override
	public void refreshHoverHelp() {
		switch (mouseLocation) {
			case 1:
				refreshDrawerHoverHelp();
				return;
			case 2:
				refreshDrawerHoverHelp();
				return;
		}
		super.refreshHoverHelp();
	}
	
	public IFigure getMainActivityFigure() {
		return getFigure();
	}
	
	public ConnectionAnchor getSourceConnectionAnchor(ConnectionEditPart connEditPart) {
		// Provide default anchor for Links.
		if (connEditPart == null || connEditPart instanceof LinkEditPart) {
			if(ModelHelper.isHorizontalLayout(getModel())){
				return new CenteredConnectionAnchor(getMainActivityFigure(), CenteredConnectionAnchor.RIGHT_INNER, 0);
			}else
				return new CenteredConnectionAnchor(getMainActivityFigure(), CenteredConnectionAnchor.BOTTOM, 0);
		}
		return null;
	}
	public ConnectionAnchor getTargetConnectionAnchor(ConnectionEditPart connEditPart) {
		// Provide default anchor for Links.
		if (connEditPart == null || connEditPart instanceof LinkEditPart) {
			if(ModelHelper.isHorizontalLayout(getModel())){
				return new CenteredConnectionAnchor(getMainActivityFigure(), CenteredConnectionAnchor.LEFT_INNER, 0);
			}else
				return new CenteredConnectionAnchor(getMainActivityFigure(), CenteredConnectionAnchor.TOP, 0);
		}
		return null;
	}
	
}
