/*******************************************************************************
 * 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 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.bpel.ui.editparts;

import java.util.Collections;
import java.util.List;

import org.eclipse.bpel.common.ui.markers.IModelMarkerConstants;
import org.eclipse.bpel.model.Link;
import org.eclipse.bpel.ui.BPELUIPlugin;
import org.eclipse.bpel.ui.IBPELUIConstants;
import org.eclipse.bpel.ui.adapters.ILabeledElement;
import org.eclipse.bpel.ui.adapters.IMarkerHolder;
import org.eclipse.bpel.ui.editparts.borders.ContainerBorder;
import org.eclipse.bpel.ui.editparts.borders.DrawerBorder;
import org.eclipse.bpel.ui.editparts.borders.LeafBorder;
import org.eclipse.bpel.ui.editparts.figures.CollapsableContainerFigure;
import org.eclipse.bpel.ui.editparts.util.BPELDecorationLayout;
import org.eclipse.bpel.ui.figures.CenteredConnectionAnchor;
import org.eclipse.bpel.ui.figures.ILayoutAware;
import org.eclipse.bpel.ui.util.BPELDragEditPartsTracker;
import org.eclipse.bpel.ui.util.BPELUtil;
import org.eclipse.bpel.ui.util.marker.BPELEditPartMarkerDecorator;
import org.eclipse.core.resources.IMarker;
import org.eclipse.draw2d.Border;
import org.eclipse.draw2d.ConnectionAnchor;
import org.eclipse.draw2d.FlowLayout;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.Layer;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.emf.common.notify.Adapter;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gef.DragTracker;
import org.eclipse.gef.Request;
import org.eclipse.swt.graphics.Image;


/**
 * Subclasses of CollapsableEditPart represent BPEL activities which
 * can be graphically represented in an expanded or collapsed manner.
 * 
 * In the collapsed state, this class will render the node. In the
 * expanded state, the subclass will be expected to render the node.
 */
public abstract class CollapsableEditPart extends CompositeActivityEditPart implements ILayoutAware {
	
	// Whether or not the edit part is collapsed
	protected boolean collapsed;
	
	// The primary image for the edit part
	protected Image image;
	
	// The images in the top and bottom drawer, if any
	protected Image topImage, bottomImage;
	
	// The label to display when collapsed. Subclasses may also use it
	// when expanded if desired.
	protected Label collapsedLabel;
	
	// Marker support
	protected IFigure contentFigure;
	protected BPELEditPartMarkerDecorator editPartMarkerDecorator;

	protected Adapter childrenAdapter;

	public class CollapsableDecorationLayout extends BPELDecorationLayout {
		private int borderImageWidth;
		public CollapsableDecorationLayout(int borderImageWidth) {
			this.borderImageWidth = borderImageWidth;
		}
		@Override
		protected Point calculateLocation(int locationHint, IFigure container, Dimension childDimension) {
			Rectangle area = container.getClientArea();
			switch (locationHint) {
				case PositionConstants.CENTER:
					// Center
					return new Point(area.x + area.width / 2 - childDimension.width / 2, area.y + area.height / 2 - childDimension.height / 2);
				case PositionConstants.TOP:
					// Top Center
					return new Point(area.x + area.width / 2 - childDimension.width / 2, area.y + borderImageWidth / 2);
				case PositionConstants.BOTTOM:
					// Bottom Center
					return new Point(area.x + area.width / 2 - childDimension.width / 2, area.y + area.height - childDimension.height);
				case PositionConstants.LEFT: {
					// Center Left
					int x = area.x + DrawerBorder.DRAWER_WIDTH;
					int y = area.y + (area.height / 2) - (childDimension.width / 2);
					if (!isCollapsed()) {
						y += DrawerBorder.DRAWER_HALF_HEIGHT / 2;
					}
					return new Point(x, y);
				}
				case PositionConstants.RIGHT: {
					// Center Right
					int x = area.x + area.width - childDimension.width - DrawerBorder.DRAWER_WIDTH;
					int y = area.y + (area.height / 2) - (childDimension.width / 2);
					if (!isCollapsed()) {
						y += DrawerBorder.DRAWER_HALF_HEIGHT / 2;
					}
					return new Point(x, y);
				}
				case PositionConstants.TOP | PositionConstants.LEFT: {
					// Top Left
					int x = area.x + DrawerBorder.DRAWER_WIDTH;
					int y = area.y + (borderImageWidth / 2);
					if (!isCollapsed()) {
						y += (collapsedLabel.getSize().height / 2) - (IBPELUIConstants.ARC_WIDTH / 2);
					}
					return new Point(x, y);
				}
				case PositionConstants.TOP | PositionConstants.RIGHT: {
					// Top Right
					int x = area.x + area.width - childDimension.width - DrawerBorder.DRAWER_WIDTH;
					int y = area.y + (borderImageWidth / 2);
					if (!isCollapsed()) {
						y += (collapsedLabel.getSize().height / 2) - (IBPELUIConstants.ARC_WIDTH / 2);
					} else {
						x -= 1; // 1 is a magic number
					}
					return new Point(x, y);
				}
				case PositionConstants.BOTTOM | PositionConstants.LEFT: {
					// Bottom Left
					int x = area.x + DrawerBorder.DRAWER_WIDTH;
					int y = area.y + area.height - IBPELUIConstants.ARC_WIDTH;
					if (!isCollapsed()) {
						y -= DrawerBorder.DRAWER_HALF_HEIGHT / 2;
					} else {
						y -= DrawerBorder.DRAWER_HALF_HEIGHT;
					}
					return new Point(x, y);
				}
				case PositionConstants.BOTTOM | PositionConstants.RIGHT: {
					// Bottom Right
					int x = area.x + area.width - childDimension.width - DrawerBorder.DRAWER_WIDTH;
					int y = area.y + area.height - IBPELUIConstants.ARC_WIDTH;
					if (!isCollapsed()) {
						y -= DrawerBorder.DRAWER_HALF_HEIGHT / 2;
					} else {
						y -= DrawerBorder.DRAWER_HALF_HEIGHT;
						x -= 1; // 1 is a magic number
					}
					return new Point(x, y);
				}
				default:
					return new Point(area.x, area.y);
			}
		}
	}

	public CollapsableEditPart() {
		this(false);
	}
	public CollapsableEditPart(boolean collapsed) {
		this.collapsed = collapsed;
	}
	protected void initializeLabels() {
		this.collapsedLabel = new Label(getLabel());
		
		// Get Image from registry
		this.image = getImg();
	}
	
	private boolean isGenericContainerBorder() {
		Border border = this.getContentPane().getBorder();
		return (border != null && border instanceof ContainerBorder);
	}
		
	@Override
	protected DrawerBorder getDrawerBorder() {
		Border border = getContentPane().getBorder();
		if (border instanceof DrawerBorder) return (DrawerBorder)border;
		return null;
	}
	
	@Override
	public Label getLabelFigure() {
		if (isGenericContainerBorder()) {
			ContainerBorder border = (ContainerBorder)(this.getContentPane().getBorder());
			return border.getLabel();
		}
		return collapsedLabel;
	}

	@Override
	protected IFigure createFigure() {		
		initializeLabels();
		editPartMarkerDecorator = new BPELEditPartMarkerDecorator(
			(EObject)getModel(),
			new CollapsableDecorationLayout(image.getBounds().width)
		);
		editPartMarkerDecorator.addMarkerMotionListener(getMarkerMotionListener());
		
		IFigure figure = getNewContentPane(editPartMarkerDecorator.getDecorationLayer());
		this.contentFigure = figure;
		
		figure.setForegroundColor(BPELUIPlugin.INSTANCE.getColorRegistry().get(IBPELUIConstants.COLOR_BLACK));		
		if (isCollapsed()) {
			addCollapsedContents(figure);
		} else {
			configureExpandedFigure(figure);
		}
		
		return editPartMarkerDecorator.createFigure(figure);
	}
	
	protected IFigure getNewContentPane(Layer layer) {
		CollapsableContainerFigure fig =  new CollapsableContainerFigure(getModel(), image, getLabel());
		fig.addMouseMotionListener(getMouseMotionListener());
		fig.setEditPart(this);
		return fig;
	}
	
	protected CollapsableContainerFigure getContentFigure() {
		return (CollapsableContainerFigure)this.contentFigure;
	}
	
	// subclasses can override this to change edit policies, etc.
	protected void notifyCollapsed(boolean collapsed) { }
	
	public void setCollapsed(boolean collapsed) {
		if (!isCollapsable()) return;

		if (isCollapsed() == collapsed) return;
		this.collapsed = collapsed;
		if (isGenericContainerBorder())
			getContentFigure().setCollapsed(collapsed);
		
		notifyCollapsed(collapsed);
		
		IFigure figure = getContentPane();
		if (isCollapsed()) {
			// First refresh children, which removes all model children's 
			// figures
			refreshChildren();
			
			
			// changed by Grid.Qian
			// when use figure.remove() to remove the children element
			// we will change the list of figure.getChildren()
			// so we will get the a error.
			int size = figure.getChildren().size();
			for(int i = 0; i < size; i++){
				figure.remove((IFigure)figure.getChildren().get(0));
			}
			
			/*// Manually remove the rest of the children
			for (Object o : figure.getChildren()) {
				figure.remove((IFigure)o);
			}*/
			
			
			// Now restore the collapsed children, border and layout
			addCollapsedContents(figure);
		} else {
			
			// changed by Grid.Qian
			// when use figure.remove() to remove the children element
			// we will change the list of figure.getChildren()
			// so we will get the a error.
			int size = figure.getChildren().size();
			for(int i = 0; i < size; i++){
				figure.remove((IFigure)figure.getChildren().get(0));
			}
			
			/*// Manually remove the children
			for (Object o : figure.getChildren()) {
				figure.remove((IFigure)o);
			}*/
			
			// Now restore the expanded children, border and layout
			configureExpandedFigure(figure);
			refreshChildren();
		}
		
		refreshSourceConnections();
		refreshTargetConnections();
		
		// Switching collapsed states may have changed the border, which is
		// responsible for drawing the drawer markers. Refresh these markers
		// now.
		refreshDrawerImages();
		// Force a repaint, as the drawer images may have changed.
		getFigure().repaint();
	}
	
	public boolean isCollapsed() {
		if (isGenericContainerBorder())
			return getContentFigure().isCollapsed();
		return collapsed;
	}
	
	protected boolean isCollapsable() {
		return true;
	}

	@Override
	protected void unregisterVisuals() {
		this.image = null;
		this.editPartMarkerDecorator = null;
		this.topImage = null;
		this.bottomImage = null;
		super.unregisterVisuals();
	}

	protected void addCollapsedContents(IFigure figure) {
		figure.setLayoutManager(new FlowLayout());
		
		if (!isGenericContainerBorder()) {
			LeafBorder lBorder = new LeafBorder(figure);
			// FIX: We have to set the editpart!
			lBorder.setEditPart(this);
			figure.setBorder(lBorder);
			figure.addMouseMotionListener(getMouseMotionListener());
			figure.add(collapsedLabel);
		}
	}
	@Override
	protected List getModelChildren() {
		if (isCollapsed()) return Collections.EMPTY_LIST;

		return getExpandedChildren();
	}
	
	protected boolean isPointInCollapseIcon(Point point) {
		if (isGenericContainerBorder()) {
			return getContentFigure().isPointInCollapseImage(point.x, point.y);
		}
		return true;
	}
	
	@Override
	public DragTracker getDragTracker(Request request) {
		return new BPELDragEditPartsTracker(this) {
			@Override
			protected boolean handleDoubleClick(int button) {
				if (!isGenericContainerBorder()) 
					setCollapsed(!isCollapsed());
				return true;
			}
			
			@Override
			protected boolean handleButtonDown(int button) {
				if (isGenericContainerBorder()) {
					if (isPointInCollapseIcon(getLocation())) {
						setCollapsed(!isCollapsed());
						return true;
					}
				}
				return super.handleButtonDown(button);
			}
		};	
	}
	
	/**
	 * @see org.eclipse.gef.editparts.AbstractEditPart#refreshVisuals()
	 */
	@Override
	public void refreshVisuals() {
		super.refreshVisuals();
		// The name has changed, change the corresponding label
		if (!isGenericContainerBorder()) {
			collapsedLabel.setText(getLabel());
		} else {
			getContentFigure().setName(getLabel());
			getContentFigure().revalidate();
		}
		// Refresh any decorations on this edit part
		editPartMarkerDecorator.refresh();
		refreshDrawerImages();
		// Force a repaint, as the drawer images may have changed.
		getFigure().repaint();
	}
	/**
	 * Return the image that was created for the receiver. This image corresponds
	 * to the image descriptor which the subclass provided in getImageDescriptor().
	 * 
	 * This image may be used by subclasses for the lifetime of this edit part.
	 * TODO: Get rid of this. Subclasses should handle the lifecycle.
	 */	
	protected Image getImage() {
		return image;
	}
	/**
	 * Return an image which should be displayed in this node while
	 * collapsed. Subclasses may override.
	 */
	protected Image getImg() {
		ILabeledElement element = BPELUtil.adapt(getActivity(), ILabeledElement.class);
		if (element != null) {
			return element.getSmallImage(getActivity());
		}
		return null;
	}
	
	/**
	 * Return a string which should be displayed in this node while collapsed.
	 */
	protected String getLabel() {
		ILabeledElement element = BPELUtil.adapt(getActivity(), ILabeledElement.class);
		if (element != null) {
			return element.getLabel(getActivity());
		}
		return null;
	}
	
	/**
	 * Return a list of the model children that should be displayed while
	 * the node is in expanded mode. Subclasses may override.
	 */
	protected List getExpandedChildren() {
		return super.getModelChildren();
	}
	/**
	 * Configure the given figure for expanded mode. Subclasses should do work
	 * in here to set border and layout information for expanded mode.
	 */
	protected abstract void configureExpandedFigure(IFigure figure);
	
	/**
	 * A CollapsableEditPart has extra responsibilities for source and target connections,
	 * because it must show flow links for any activities which are inside it but not
	 * visible (in the case that the CollapsableEditPart is collapsed).
	 */	
	@Override
	protected List<Link> getModelSourceConnections() {
		final List<Link> result = super.getModelSourceConnections();
//		if (isCollapsed()) {
//			BPELUtil.visitModelDepthFirst(getActivity(), new IModelVisitor() {
//				public boolean visit(Object modelObject) {
//					if (modelObject instanceof Activity) {
//						List sources = ((Activity)modelObject).getSources();
//						Iterator it = sources.iterator();
//						while (it.hasNext()) {
//							Source source = (Source)it.next();
//							Target target = source.getLink().getTarget();
//							Activity targetActivity = target.getActivity();
//							// If the target is not contained in this model object, add the 
//							// connection.
//							if (!containsModel(targetActivity)) {
//								result.add(source.getLink());
//							}
//						}
//					}
//					return true;
//				}
//			});
//		}
		return result;
	}

	/**
	 * A CollapsableEditPart has extra responsibilities for source and target connections,
	 * because it must show flow links for any activities which are inside it but not
	 * visible (in the case that the CollapsableEditPart is collapsed).
	 */
	@Override
	protected List<Link> getModelTargetConnections() {
		final List<Link> result = super.getModelTargetConnections();
//		if (isCollapsed()) {
//			BPELUtil.visitModelDepthFirst(getActivity(), new IModelVisitor() {
//				public boolean visit(Object modelObject) {
//					if (modelObject instanceof Activity) {
//						List targets = ((Activity)modelObject).getTargets();
//						Iterator it = targets.iterator();
//						while (it.hasNext()) {
//							Target target = (Target)it.next();
//							Source source = target.getLink().getSource();
//							Activity sourceActivity = source.getActivity();
//							// If the source is not contained in this model object, add the 
//							// connection.
//							if (!containsModel(sourceActivity)) {
//								result.add(target.getLink());
//							}
//						}
//					}
//					return true;
//				}
//			});
//		}
		return result;
	}
	
	@Override
	public IFigure getContentPane() {
		return contentFigure;
	}

	public Label getCollapsedLabel() {
		return collapsedLabel;
	}

	protected void refreshDrawerImages() {
		DrawerBorder border = (DrawerBorder)getContentPane().getBorder();
		
		if (topImage != null) {
			topImage.dispose();
			topImage = null;
		}
		if (bottomImage != null) {
			bottomImage.dispose();
			bottomImage = null;
		}
		IMarkerHolder holder = BPELUtil.adapt(getActivity(), IMarkerHolder.class);
		
		int topMarkerPriority = Integer.MIN_VALUE;
		int bottomMarkerPriority = Integer.MIN_VALUE;
		IMarker topMarker = null;
		IMarker bottomMarker = null;
		
		for (IMarker marker : holder.getMarkers(getActivity())) {
			
			if (marker.getAttribute(IModelMarkerConstants.DECORATION_MARKER_VISIBLE_ATTR, true) == false) {
				continue;
			}
			
			String value = marker.getAttribute(IModelMarkerConstants.DECORATION_GRAPHICAL_MARKER_ANCHOR_POINT_ATTR,EMPTY_STRING);  
			
			if (value.equals(IBPELUIConstants.MARKER_ANCHORPOINT_DRAWER_TOP)) {
				int priority = marker.getAttribute(IModelMarkerConstants.DECORATION_MARKER_PRIORITY_ATTR, 0);
				if (priority > topMarkerPriority) {
					topMarkerPriority = priority;
					topImage = BPELUtil.getImage(marker);
					topMarker = marker;
				}
			} else if (value.equals(IBPELUIConstants.MARKER_ANCHORPOINT_DRAWER_BOTTOM)) {
				int priority = marker.getAttribute(IModelMarkerConstants.DECORATION_MARKER_PRIORITY_ATTR, 0);
				if (priority > bottomMarkerPriority) {
					bottomMarkerPriority = priority;
					bottomImage = BPELUtil.getImage(marker);
					bottomMarker = marker;
				}
			}
		}
		
		border.setTopImage(topImage);
		border.setBottomImage(bottomImage);
		border.setTopMarker(topMarker);
		border.setBottomMarker(bottomMarker);
	}
	
	/**
	 * Get an anchor at the given location for this edit part.
	 * 
	 * This must be called after the figure for this edit part has been created.
	 */
	@Override
	public ConnectionAnchor getConnectionAnchor(int location) {
		switch(location){
		case CenteredConnectionAnchor.TOP_INNER:
			return new CenteredConnectionAnchor(getFigure(), location, 30);
		case CenteredConnectionAnchor.LEFT:
			return new CenteredConnectionAnchor(getFigure(), CenteredConnectionAnchor.LEFT_INNER, 0);
		case CenteredConnectionAnchor.RIGHT:
			return new CenteredConnectionAnchor(getFigure(), CenteredConnectionAnchor.RIGHT_INNER, 0);
		default:
				return super.getConnectionAnchor(location);
		}
	}
}
