/******************************************************************************* 
 * Copyright (c) 2011, 2012 Red Hat, Inc. 
 *  All rights reserved. 
 * This program is 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: 
 * Red Hat, Inc. - initial API and implementation 
 *
 * @author Innar Made
 ******************************************************************************/
package org.eclipse.bpmn2.modeler.core.utils;

import org.eclipse.bpmn2.BoundaryEvent;
import org.eclipse.bpmn2.di.BPMNShape;
import org.eclipse.bpmn2.modeler.core.features.GraphitiConstants;
import org.eclipse.dd.dc.Bounds;
import org.eclipse.graphiti.datatypes.IDimension;
import org.eclipse.graphiti.datatypes.ILocation;
import org.eclipse.graphiti.features.context.ICreateContext;
import org.eclipse.graphiti.features.context.IMoveShapeContext;
import org.eclipse.graphiti.mm.PropertyContainer;
import org.eclipse.graphiti.mm.algorithms.GraphicsAlgorithm;
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
import org.eclipse.graphiti.mm.pictograms.Diagram;
import org.eclipse.graphiti.mm.pictograms.PictogramElement;
import org.eclipse.graphiti.mm.pictograms.Shape;
import org.eclipse.graphiti.services.Graphiti;
import org.eclipse.graphiti.services.IPeService;

public class BoundaryEventPositionHelper {

	private static IPeService peService = Graphiti.getPeService();

	public static class PositionOnLine {

		public enum LineType {
			X, Y, XY, UNKNOWN
		}

		public enum LocationType {
			TOP, TOP_LEFT, TOP_RIGHT, BOTTOM, BOTTOM_LEFT, BOTTOM_RIGHT, LEFT, RIGHT, UNKNOWN
		}

		private LineType lineType;
		private LocationType locationType;

		public PositionOnLine(LineType lineType, LocationType locationType) {
			this.lineType = lineType;
			this.locationType = locationType;
		}

		public PositionOnLine(boolean alongLeftX, boolean alongRightX, boolean alongTopY, boolean alongBottomY) {
			boolean alongX = alongLeftX || alongRightX;
			boolean alongY = alongTopY || alongBottomY;

			if (alongX && alongY) {
				lineType = LineType.XY;
			} else if (alongX) {
				lineType = LineType.X;
			} else if (alongY) {
				lineType = LineType.Y;
			} else {
				lineType = LineType.UNKNOWN;
			}

			if (lineType != null) {
				switch (lineType) {
				case XY:
					if (alongLeftX) {
						if (alongTopY) {
							locationType = LocationType.TOP_LEFT;
						} else {
							locationType = LocationType.BOTTOM_LEFT;
						}
					} else if (alongRightX) {
						if (alongTopY) {
							locationType = LocationType.TOP_RIGHT;
						} else {
							locationType = LocationType.BOTTOM_RIGHT;
						}
					}
					break;
				case X:
					if (alongLeftX) {
						locationType = LocationType.LEFT;
					} else {
						locationType = LocationType.RIGHT;
					}
					break;
				case Y:
					if (alongTopY) {
						locationType = LocationType.TOP;
					} else {
						locationType = LocationType.BOTTOM;
					}
					break;
				default:
					locationType = LocationType.UNKNOWN;
					break;
				}
			}

			if (locationType == null) {
				locationType = LocationType.UNKNOWN;
			}
		}

		public LineType getLineType() {
			return lineType;
		}

		public LocationType getLocationType() {
			return locationType;
		}

		public boolean isLegalPosition() {
			return lineType != LineType.UNKNOWN && locationType != LocationType.UNKNOWN;
		}

		public static PositionOnLine fromString(String s) {
			if (s == null) {
				return null;
			}
			String[] arr = s.split(":"); //$NON-NLS-1$
			if (!arr[0].equals(PositionOnLine.class.getSimpleName().toLowerCase())) {
				return null;
			}

			return new PositionOnLine(LineType.valueOf(arr[1]), LocationType.valueOf(arr[2]));
		}

		@Override
		public String toString() {
			String prefix = PositionOnLine.class.getSimpleName().toLowerCase();
			String lineType = this.lineType.toString();
			String locationType = this.locationType.toString();
			String colon = ":"; //$NON-NLS-1$
			return new StringBuilder().append(prefix).append(colon).append(lineType).append(colon).append(locationType)
			        .toString();
		}
	}
	public static boolean canCreateEventAt(ICreateContext context, GraphicsAlgorithm ga, int padding) {
		return canCreateEventAt(context.getX(), context.getY(), ga.getWidth(), ga.getHeight(), padding);
	}

	public static boolean canCreateEventAt(int x, int y, GraphicsAlgorithm ga, int padding) {
		return canCreateEventAt(x, y, ga.getWidth(), ga.getHeight(), padding);
	}

	public static boolean canCreateEventAt(int x, int y, int w, int h, int padding) {
		int x1 = 0;
		int x2 = 0 + padding;
		int x3 = w - padding;
		int x4 = w;

		int y1 = 0;
		int y2 = 0 + padding;
		int y3 = h - padding;
		int y4 = h;

		if ((y >= y1 && y <= y2) || (y >= y3 && y <= y4)) {
			return true;
		}
		if ((x >= x1 && x <= x2) || (x >= x3 && x <= x4)) {
			return true;
		}
		return false;
	}

	public static boolean canMoveTo(IMoveShapeContext context, Diagram diagram) {
		int x = context.getX() + context.getDeltaX();
		int y = context.getY() + context.getDeltaY();

		if (!(context.getTargetContainer() instanceof Diagram)) {
			ILocation loc = peService.getLocationRelativeToDiagram(context.getTargetContainer());
			x += loc.getX();
			y += loc.getY();
		}

		BoundaryEvent event = BusinessObjectUtil.getFirstElementOfType(context.getShape(), BoundaryEvent.class);
		GraphicsAlgorithm eventGa = context.getShape().getGraphicsAlgorithm();
		PictogramElement firstBaseElement = BusinessObjectUtil.getFirstBaseElementFromDiagram(diagram, event.getAttachedToRef());
		if (firstBaseElement == null || !(firstBaseElement instanceof ContainerShape))
			return false;
		
		ContainerShape activityContainer = (ContainerShape)firstBaseElement;
		GraphicsAlgorithm activityGa = activityContainer.getGraphicsAlgorithm();
		ILocation activityLoc = peService.getLocationRelativeToDiagram(activityContainer);

//		if (!activityContainer.equals(context.getTargetContainer())) {
//			return false;
//		}

		PositionOnLine pos = getPositionOnLine(x, y, eventGa.getWidth(), eventGa.getHeight(), activityLoc.getX(),
		        activityLoc.getY(), activityGa.getWidth(), activityGa.getHeight());
		return pos.isLegalPosition();
	}
	
	public static ILocation getLocation(IMoveShapeContext context, Diagram diagram) {
		ILocation eventLoc = peService.getLocationRelativeToDiagram(context.getShape());
		Shape eventShape = context.getShape();
		BoundaryEvent event = BusinessObjectUtil.getFirstElementOfType(eventShape, BoundaryEvent.class);
		PictogramElement pe = BusinessObjectUtil.getFirstBaseElementFromDiagram(diagram, event.getAttachedToRef());
		if (pe instanceof ContainerShape) {
			ContainerShape activityShape = (ContainerShape) pe;
			ILocation activityLoc = peService.getLocationRelativeToDiagram(activityShape);
			IDimension eventSize = GraphicsUtil.calculateSize(eventShape);
			IDimension activitySize = GraphicsUtil.calculateSize(activityShape);
			eventLoc.setX(activityLoc.getX() + eventSize.getWidth());
			eventLoc.setY(activityLoc.getY() + activitySize.getHeight() - eventSize.getHeight()/2);
		}

		return eventLoc;
	}
	

	public static PositionOnLine getPositionOnLineUsingBPMNShape(Shape eventShape, Shape activityShape) {
		BPMNShape event = BusinessObjectUtil.getFirstElementOfType(eventShape, BPMNShape.class);
		Bounds eventBounds = event.getBounds();
		BPMNShape activity = BusinessObjectUtil.getFirstElementOfType(activityShape, BPMNShape.class);
		Bounds activityBounds = activity.getBounds();

		return getPositionOnLine((int) eventBounds.getX(), (int) eventBounds.getY(), (int) eventBounds.getWidth(),
		        (int) eventBounds.getHeight(), (int) activityBounds.getX(), (int) activityBounds.getY(),
		        (int) activityBounds.getWidth(), (int) activityBounds.getHeight());
	}

	public static PositionOnLine getPositionOnLineUsingAbsoluteCoordinates(Shape eventShape, Shape activityShape) {
		GraphicsAlgorithm eventGa = eventShape.getGraphicsAlgorithm();
		ILocation eventLoc = peService.getLocationRelativeToDiagram(eventShape);
		GraphicsAlgorithm activityGa = activityShape.getGraphicsAlgorithm();
		ILocation activityLoc = peService.getLocationRelativeToDiagram(activityShape);

		return getPositionOnLine(eventLoc.getX(), eventLoc.getY(), eventGa.getWidth(), eventGa.getHeight(),
		        activityLoc.getX(), activityLoc.getY(), activityGa.getWidth(), activityGa.getHeight());
	}

	public static PositionOnLine getPositionOnLine(int eventX, int eventY, int eventW, int eventH, int activityX,
	        int activityY, int activityW, int activityH) {

		int x = eventX + eventW / 2;
		int y = eventY + eventH / 2;

		int x1 = activityX;
		int x2 = x1 + 10;
		int x3 = x1 + activityW - 10;
		int x4 = x1 + activityW + 10;

		int y1 = activityY;
		int y2 = y1 + 10;
		int y3 = y1 + activityH - 10;
		int y4 = y1 + activityH + 10;

		boolean alongLeftX = x >= x1 && x <= x2;
		boolean alongRightX = x >= x3 && x <= x4;
		boolean alongTopY = y >= y1 && y <= y2;
		boolean alongBottomY = y >= y3 && y <= y4;

		PositionOnLine pos = new PositionOnLine(alongLeftX, alongRightX, alongTopY, alongBottomY);

		return pos;
	}

	public static void assignPositionOnLineProperty(PropertyContainer propertyContainer, PositionOnLine pos) {
		FeatureSupport.setPropertyValue(propertyContainer, GraphitiConstants.BOUNDARY_EVENT_RELATIVE_POS, pos.toString());
	}

	public static PositionOnLine getPositionOnLineProperty(PropertyContainer propertyContainer) {
		String value = FeatureSupport.getPropertyValue(propertyContainer, GraphitiConstants.BOUNDARY_EVENT_RELATIVE_POS);
		return PositionOnLine.fromString(value);
	}
}