/******************************************************************************* 
 * 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();
		ContainerShape activityContainer = (ContainerShape) BusinessObjectUtil.getFirstBaseElementFromDiagram(diagram,
		        event.getAttachedToRef());
		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) {
		peService.setPropertyValue(propertyContainer, GraphitiConstants.BOUNDARY_EVENT_RELATIVE_POS, pos.toString());
	}

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