/*
 * Copyright (c) 2005, 2006 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 implementation
 *
 */
package org.eclipse.epf.diagramming.part;

import java.util.List;
import org.eclipse.gef.Tool;
import org.eclipse.gef.palette.PaletteContainer;
import org.eclipse.gef.palette.PaletteRoot;
import org.eclipse.gef.palette.ToolEntry;
import org.eclipse.jface.resource.ImageDescriptor;
import java.util.ArrayList;

import org.eclipse.epf.diagram.core.bridge.BridgeHelper;
import org.eclipse.epf.diagramming.providers.UMLElementTypes;

import org.eclipse.gef.palette.PaletteDrawer;

import org.eclipse.gef.palette.PaletteSeparator;

import org.eclipse.gmf.runtime.diagram.ui.tools.UnspecifiedTypeConnectionTool;
import org.eclipse.gmf.runtime.diagram.ui.tools.UnspecifiedTypeCreationTool;

/**
 * @generated
 */
public class UMLPaletteFactory {

	/**
	 * @generated
	 */
	public void fillPalette(PaletteRoot paletteRoot) {
		paletteRoot.add(createFlows1Group());
		paletteRoot.add(createNodes2Group());
	}

	/**
	 * @generated
	 */
	private PaletteContainer createFlows1Group() {
		PaletteContainer paletteContainer = new PaletteDrawer("Flows");
		paletteContainer.setDescription("Creation tool for flows");
		paletteContainer.add(createLink1CreationTool());
		return paletteContainer;
	}

	/**
	 * @generated
	 */
	private PaletteContainer createNodes2Group() {
		PaletteContainer paletteContainer = new PaletteDrawer("Nodes");
		paletteContainer.setDescription("Creation tool group for nodes");
		paletteContainer.add(createActivityPartition1CreationTool());
		paletteContainer.add(createStartNode2CreationTool());
		paletteContainer.add(createForkNode3CreationTool());
		paletteContainer.add(createMergeNode4CreationTool());
		paletteContainer.add(createDecisionNode5CreationTool());
		paletteContainer.add(createEndNode6CreationTool());
		paletteContainer.add(createJoinNode7CreationTool());
		paletteContainer.add(new PaletteSeparator());
		paletteContainer.add(createActivity9CreationTool());
		paletteContainer.add(createPhase10CreationTool());
		paletteContainer.add(createIteration11CreationTool());
		paletteContainer.add(createTaskDescriptor12CreationTool());
		paletteContainer.add(createMilestone13CreationTool());
		return paletteContainer;
	}

	/**
	 * @generated
	 */
	private ToolEntry createActivityPartition1CreationTool() {
		ImageDescriptor smallImage;
		ImageDescriptor largeImage;

		smallImage = EPFDiagramEditorPlugin
				.findImageDescriptor("/org.eclipse.epf.diagramming/icons/full/obj16/ActivityPartition.gif");

		largeImage = smallImage;

		final List elementTypes = new ArrayList();
		elementTypes.add(UMLElementTypes.ActivityPartition_1008);
		elementTypes.add(UMLElementTypes.ActivityPartition_2001);
		ToolEntry result = new NodeToolEntry("Activity Partition",
				"Create new Activity Partition", smallImage, largeImage,
				elementTypes);

		return result;
	}

	/**
	 * @generated
	 */
	private ToolEntry createStartNode2CreationTool() {
		ImageDescriptor smallImage;
		ImageDescriptor largeImage;

		smallImage = EPFDiagramEditorPlugin
				.findImageDescriptor("/org.eclipse.epf.diagramming/icons/full/obj16/InitialNode.gif");

		largeImage = smallImage;

		final List elementTypes = new ArrayList();
		elementTypes.add(UMLElementTypes.InitialNode_1004);
		ToolEntry result = new NodeToolEntry("Start Node",
				"Create new Start Node", smallImage, largeImage, elementTypes);

		return result;
	}

	/**
	 * @generated
	 */
	private ToolEntry createForkNode3CreationTool() {
		ImageDescriptor smallImage;
		ImageDescriptor largeImage;

		smallImage = EPFDiagramEditorPlugin
				.findImageDescriptor("/org.eclipse.epf.diagramming/icons/full/obj16/ForkNode.gif");

		largeImage = smallImage;

		final List elementTypes = new ArrayList();
		elementTypes.add(UMLElementTypes.ForkNode_1003);
		ToolEntry result = new NodeToolEntry("Fork Node",
				"Create new Fork Node", smallImage, largeImage, elementTypes);

		return result;
	}

	/**
	 * @generated
	 */
	private ToolEntry createMergeNode4CreationTool() {
		ImageDescriptor smallImage;
		ImageDescriptor largeImage;

		smallImage = EPFDiagramEditorPlugin
				.findImageDescriptor("/org.eclipse.epf.diagramming/icons/full/obj16/MergeNode.gif");

		largeImage = smallImage;

		final List elementTypes = new ArrayList();
		elementTypes.add(UMLElementTypes.MergeNode_1002);
		ToolEntry result = new NodeToolEntry("Merge Node",
				"Create new Merge Node", smallImage, largeImage, elementTypes);

		return result;
	}

	/**
	 * @generated
	 */
	private ToolEntry createDecisionNode5CreationTool() {
		ImageDescriptor smallImage;
		ImageDescriptor largeImage;

		smallImage = EPFDiagramEditorPlugin
				.findImageDescriptor("/org.eclipse.epf.diagramming/icons/full/obj16/DecisionNode.gif");

		largeImage = smallImage;

		final List elementTypes = new ArrayList();
		elementTypes.add(UMLElementTypes.DecisionNode_1005);
		ToolEntry result = new NodeToolEntry("Decision Node",
				"Create new Decision Node", smallImage, largeImage,
				elementTypes);

		return result;
	}

	/**
	 * @generated
	 */
	private ToolEntry createEndNode6CreationTool() {
		ImageDescriptor smallImage;
		ImageDescriptor largeImage;

		smallImage = EPFDiagramEditorPlugin
				.findImageDescriptor("/org.eclipse.epf.diagramming/icons/full/obj16/ActivityFinalNode.gif");

		largeImage = smallImage;

		final List elementTypes = new ArrayList();
		elementTypes.add(UMLElementTypes.ActivityFinalNode_1001);
		ToolEntry result = new NodeToolEntry("End Node", "Create new End Node",
				smallImage, largeImage, elementTypes);

		return result;
	}

	/**
	 * @generated
	 */
	private ToolEntry createJoinNode7CreationTool() {
		ImageDescriptor smallImage;
		ImageDescriptor largeImage;

		smallImage = EPFDiagramEditorPlugin
				.findImageDescriptor("/org.eclipse.epf.diagramming/icons/full/obj16/JoinNode.gif");

		largeImage = smallImage;

		final List elementTypes = new ArrayList();
		elementTypes.add(UMLElementTypes.JoinNode_1006);
		ToolEntry result = new NodeToolEntry("Join Node",
				"Create new Join Node", smallImage, largeImage, elementTypes);

		return result;
	}

	/**
	 * @generated
	 */
	private ToolEntry createActivity9CreationTool() {
		ImageDescriptor smallImage;
		ImageDescriptor largeImage;

		smallImage = EPFDiagramEditorPlugin
				.findImageDescriptor("/org.eclipse.epf.diagramming/icons/full/obj16/Activity.gif");

		largeImage = smallImage;

		final List elementTypes = new ArrayList();
		elementTypes.add(UMLElementTypes.StructuredActivityNode_1007);
		ToolEntry result = new NodeToolEntry("Activity", "Create new Activity",
				smallImage, largeImage, elementTypes);

		return result;
	}

	/**
	 * @generated
	 */
	private ToolEntry createPhase10CreationTool() {
		ImageDescriptor smallImage;
		ImageDescriptor largeImage;

		smallImage = EPFDiagramEditorPlugin
				.findImageDescriptor("/org.eclipse.epf.diagramming/icons/full/obj16/Phase.gif");

		largeImage = smallImage;

		final List elementTypes = new ArrayList();
		elementTypes.add(UMLElementTypes.StructuredActivityNode_1010);
		ToolEntry result = new NodeToolEntry("Phase", "Create new Phase",
				smallImage, largeImage, elementTypes);

		return result;
	}

	/**
	 * @generated
	 */
	private ToolEntry createIteration11CreationTool() {
		ImageDescriptor smallImage;
		ImageDescriptor largeImage;

		smallImage = EPFDiagramEditorPlugin
				.findImageDescriptor("/org.eclipse.epf.diagramming/icons/full/obj16/Iteration.gif");

		largeImage = smallImage;

		final List elementTypes = new ArrayList();
		elementTypes.add(UMLElementTypes.StructuredActivityNode_1011);
		ToolEntry result = new NodeToolEntry("Iteration",
				"Create new Iteration", smallImage, largeImage, elementTypes);

		return result;
	}

	/**
	 * @generated
	 */
	private ToolEntry createTaskDescriptor12CreationTool() {
		ImageDescriptor smallImage;
		ImageDescriptor largeImage;

		smallImage = EPFDiagramEditorPlugin
				.findImageDescriptor("/org.eclipse.epf.diagramming/icons/full/obj16/TaskDescriptor.gif");

		largeImage = smallImage;

		final List elementTypes = new ArrayList();
		elementTypes.add(UMLElementTypes.ActivityParameterNode_1009);
		ToolEntry result = new NodeToolEntry("Task Descriptor",
				"Create new Task Descriptor", smallImage, largeImage,
				elementTypes);

		return result;
	}

	/**
	 * @generated
	 */
	private ToolEntry createMilestone13CreationTool() {
		ImageDescriptor smallImage;
		ImageDescriptor largeImage;

		smallImage = EPFDiagramEditorPlugin
				.findImageDescriptor("/org.eclipse.epf.diagramming/icons/full/obj16/Milestone.gif");

		largeImage = smallImage;

		final List elementTypes = new ArrayList();
		elementTypes.add(UMLElementTypes.ActivityParameterNode_1012);
		ToolEntry result = new NodeToolEntry("Milestone",
				"Create new Milestone", smallImage, largeImage, elementTypes);

		return result;
	}

	/**
	 * @generated
	 */
	private ToolEntry createLink1CreationTool() {
		ImageDescriptor smallImage;
		ImageDescriptor largeImage;

		smallImage = EPFDiagramEditorPlugin
				.findImageDescriptor("/org.eclipse.epf.diagramming/icons/full/obj16/ControlFlow.gif");

		largeImage = smallImage;

		final List relationshipTypes = new ArrayList();
		relationshipTypes.add(UMLElementTypes.ControlFlow_3001);
		ToolEntry result = new LinkToolEntry("Link", "Create new Link",
				smallImage, largeImage, relationshipTypes);

		return result;
	}

	/**
	 * @generated
	 */
	private static class NodeToolEntry extends ToolEntry {

		/**
		 * @generated
		 */
		private final List elementTypes;

		/**
		 * @generated
		 */
		private NodeToolEntry(String title, String description,
				ImageDescriptor smallIcon, ImageDescriptor largeIcon,
				List elementTypes) {
			super(title, description, smallIcon, largeIcon);
			this.elementTypes = elementTypes;
		}

		/**
		 * @modified
		 */
		public Tool createTool() {
			Tool tool = new UnspecifiedTypeCreationTool(elementTypes);
			tool.setProperties(getToolProperties());
			BridgeHelper.elementTypes.add(elementTypes
					.get(elementTypes.size() - 1));
			return tool;
		}
	}

	/**
	 * @generated
	 */
	private static class LinkToolEntry extends ToolEntry {

		/**
		 * @generated
		 */
		private final List relationshipTypes;

		/**
		 * @generated
		 */
		private LinkToolEntry(String title, String description,
				ImageDescriptor smallIcon, ImageDescriptor largeIcon,
				List relationshipTypes) {
			super(title, description, smallIcon, largeIcon);
			this.relationshipTypes = relationshipTypes;
		}

		/**
		 * @generated
		 */
		public Tool createTool() {
			Tool tool = new UnspecifiedTypeConnectionTool(relationshipTypes);
			tool.setProperties(getToolProperties());
			return tool;
		}
	}
}
