/*******************************************************************************
 * <copyright>
 *
 * Copyright (c) 2013, 2013 SAP AG.
 * 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:
 *    SAP AG - initial API, implementation and documentation
 *
 * </copyright>
 *
 *******************************************************************************/
package org.eclipse.fmc;

import static org.eclipse.fmc.blockdiagram.editor.diagram.BlockDiagramFeatureProvider.CREATE_FEATURE_AGENT;
import static org.eclipse.fmc.blockdiagram.editor.diagram.BlockDiagramFeatureProvider.CREATE_FEATURE_AGENT_L;
import static org.eclipse.fmc.blockdiagram.editor.diagram.BlockDiagramFeatureProvider.CREATE_FEATURE_AGENT_U;
import static org.eclipse.fmc.blockdiagram.editor.diagram.BlockDiagramFeatureProvider.CREATE_FEATURE_AREA_BORDER;
import static org.eclipse.fmc.blockdiagram.editor.diagram.BlockDiagramFeatureProvider.CREATE_FEATURE_BRACE;
import static org.eclipse.fmc.blockdiagram.editor.diagram.BlockDiagramFeatureProvider.CREATE_FEATURE_COMMON_FEATURE_AREA;
import static org.eclipse.fmc.blockdiagram.editor.diagram.BlockDiagramFeatureProvider.CREATE_FEATURE_DOTS;
import static org.eclipse.fmc.blockdiagram.editor.diagram.BlockDiagramFeatureProvider.CREATE_FEATURE_HUMAN_AGENT;
import static org.eclipse.fmc.blockdiagram.editor.diagram.BlockDiagramFeatureProvider.CREATE_FEATURE_STORAGE;
import static org.eclipse.fmc.blockdiagram.editor.diagram.BlockDiagramFeatureProvider.CREATE_FEATURE_STORAGE_L;
import static org.eclipse.fmc.blockdiagram.editor.diagram.BlockDiagramFeatureProvider.CREATE_FEATURE_STORAGE_U;
import static org.eclipse.fmc.blockdiagram.editor.diagram.BlockDiagramFeatureProvider.CREATE_FEATURE_STRUCTURE_VARIANCE;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.awt.Point;

import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.graphiti.features.IMoveShapeFeature;
import org.eclipse.graphiti.features.IRemoveFeature;
import org.eclipse.graphiti.features.IResizeShapeFeature;
import org.eclipse.graphiti.features.context.impl.MoveShapeContext;
import org.eclipse.graphiti.features.context.impl.RemoveContext;
import org.eclipse.graphiti.features.context.impl.ResizeShapeContext;
import org.eclipse.graphiti.mm.algorithms.AbstractText;
import org.eclipse.graphiti.mm.algorithms.styles.Orientation;
import org.eclipse.graphiti.mm.pictograms.ContainerShape;
import org.eclipse.graphiti.mm.pictograms.Shape;
import org.junit.Test;

public class ShapeTest extends FMCTestCase {

	private static final int WIDTH = 200;
	private static final int HEIGHT = 120;

	private Shape testCreate(int createFeature) {
		return testCreate(createFeature, new Point(0, 0));
	}

	protected Shape testCreate(int createFeature, final Point offset) {
		final int width = 200;
		final int height = 120;
		final int x = 2;
		final int y = 5;
		Shape shape = createShape(createFeature, width, height, x, y);
		assertSize(shape, width + offset.x, height + offset.y);
		assertPosition(shape, x, y);
		return shape;
	}

	private void testResize(final Shape shape) {
		testResize(shape, new Point(0, 0), Orientation.ALIGNMENT_BOTTOM);
	}

	private void testResize(final Shape shape, final Point offset,
			final Orientation hAlignment) {
		getEditingDomain().getCommandStack().execute(
				new RecordingCommand(getEditingDomain()) {
					@Override
					protected void doExecute() {
						int width = 122;
						int height = 111;
						AbstractText text = findText((ContainerShape) shape);
						Orientation horizontalBefore = null;
						Orientation horizontalAfter = null;
						if (text != null) {
							text.setHorizontalAlignment(hAlignment);
							horizontalBefore = text.getHorizontalAlignment();
							horizontalAfter = text.getVerticalAlignment();
						}
						ResizeShapeContext ctx = new ResizeShapeContext(shape);
						ctx.setSize(width, height);
						IResizeShapeFeature resizeShapeFeature = getFeatureProvider()
								.getResizeShapeFeature(ctx);
						assertTrue(resizeShapeFeature.canResizeShape(ctx));
						assertTrue(resizeShapeFeature.canExecute(ctx));
						resizeShapeFeature.execute(ctx);
						assertEquals(width + offset.x, shape
								.getGraphicsAlgorithm().getWidth());
						assertEquals(height + offset.y, shape
								.getGraphicsAlgorithm().getHeight());
						if (text != null) {
							text = findText((ContainerShape) shape);
							assertEquals(horizontalBefore,
									text.getHorizontalAlignment());
							assertEquals(horizontalAfter,
									text.getVerticalAlignment());
						}
					}
				});
	}

	private void testMove(final Shape shape) {
		testMove(shape, new Point(0, 0));
	}

	private void testMove(final Shape shape, final Point offset) {
		getEditingDomain().getCommandStack().execute(
				new RecordingCommand(getEditingDomain()) {
					@Override
					protected void doExecute() {
						final int width = WIDTH;
						final int height = HEIGHT;
						MoveShapeContext ctx = new MoveShapeContext(shape);
						ctx.setLocation(20, 20);
						ctx.setSourceContainer(shape.getContainer());
						ctx.setTargetContainer(shape.getContainer());
						IMoveShapeFeature moveShapeFeature = getFeatureProvider()
								.getMoveShapeFeature(ctx);
						assertTrue(moveShapeFeature.canExecute(ctx));
						assertTrue(moveShapeFeature.canMoveShape(ctx));
						assertTrue(moveShapeFeature.isAvailable(ctx));
						moveShapeFeature.execute(ctx);
						assertSize(shape, width + offset.x, height + offset.y);
						assertPosition(shape, 20, 20);
						// TODO Test moving into another shape
					}
				});
	}

	private void testDelete(final Shape shape) {
		getEditingDomain().getCommandStack().execute(
				new RecordingCommand(getEditingDomain()) {
					@Override
					protected void doExecute() {
						RemoveContext ctx = new RemoveContext(shape);
						IRemoveFeature deleteFeature = getFeatureProvider()
								.getRemoveFeature(ctx);
						assertTrue("Remove feature cannot be executed",
								deleteFeature.canRemove(ctx));
						assertTrue(deleteFeature.canExecute(ctx));
						deleteFeature.execute(ctx);
						assertEquals(0, getDiagram().getChildren().size());
					}
				});
	}

	@Test
	public void testAgent() {
		Shape shape = testCreate(CREATE_FEATURE_AGENT);
		testMove(shape);
		testResize(shape);
		testDelete(shape);
	}

	@Test
	public void testAgentL() {
		Shape shape = testCreate(CREATE_FEATURE_AGENT_L);
		testMove(shape);
		testResize(shape);
		testDelete(shape);
	}

	@Test
	public void testAgentU() {
		Shape shape = testCreate(CREATE_FEATURE_AGENT_U);
		testMove(shape);
		testResize(shape);
		testDelete(shape);
	}

	@Test
	public void testStorage() {
		Shape shape = testCreate(CREATE_FEATURE_STORAGE);
		testMove(shape);
		testResize(shape);
		testDelete(shape);
	}

	@Test
	public void testStorageL() {
		Shape shape = testCreate(CREATE_FEATURE_STORAGE_L);
		testMove(shape);
		testResize(shape);
		testDelete(shape);
	}

	@Test
	public void testStorageU() {
		Shape shape = testCreate(CREATE_FEATURE_STORAGE_U);
		testMove(shape);
		testResize(shape);
		testDelete(shape);
	}

	@Test
	public void testHumanAgent() {
		Shape shape = testCreate(CREATE_FEATURE_HUMAN_AGENT);
		testMove(shape);
		testResize(shape);
		testDelete(shape);
	}

	@Test
	public void testStructureVariance() {
		Shape shape = testCreate(CREATE_FEATURE_STRUCTURE_VARIANCE);
		testMove(shape);
		testResize(shape);
		testDelete(shape);
	}

	/*
	 * public void testChannel(){ Shape shape =
	 * testCreate(CREATE_FEATURE_CHANNEL); testMove(shape); testResize(shape);
	 * testDelete(shape); }
	 */
	@Test
	public void testCommonFeatureArea() {
		Shape shape = testCreate(CREATE_FEATURE_COMMON_FEATURE_AREA);
		testMove(shape);
		testResize(shape);
		testDelete(shape);
	}

	@Test
	public void testBrace() {
		Shape shape = testCreate(CREATE_FEATURE_BRACE, new Point(0, -75));
		testMove(shape, new Point(0, -75));
		testResize(shape, new Point(0, -84), Orientation.ALIGNMENT_RIGHT);
		testDelete(shape);
	}

	@Test
	public void testAreaBorder() {
		Shape shape = testCreate(CREATE_FEATURE_AREA_BORDER, new Point(0, -92));
		testMove(shape, new Point(0, -92));
		testResize(shape, new Point(0, -83), Orientation.ALIGNMENT_RIGHT);
		testDelete(shape);
	}

	@Test
	public void testDots() {
		Shape shape = testCreate(CREATE_FEATURE_DOTS);
		testMove(shape);
		testResize(shape);
		testDelete(shape);
	}

	private AbstractText findText(ContainerShape shape) {
		for (Shape child : shape.getChildren()) {
			if (child.getGraphicsAlgorithm() instanceof AbstractText) {
				return (AbstractText) child.getGraphicsAlgorithm();
			}
		}
		AbstractText found = null;
		for (Shape child : shape.getChildren()) {
			if (child instanceof ContainerShape)
				found = findText((ContainerShape) child);
			if (found != null)
				return found;
		}
		return found;
	}
}
