/******************************************************************************
 * Copyright (c) 2006, Intalio Inc.
 * 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:
 *     Intalio Inc. - initial API and implementation
 *******************************************************************************/

package org.eclipse.stp.bpmn.diagram.providers;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;

import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.stp.bpmn.ActivityType;
import org.eclipse.stp.bpmn.BpmnPackage;
import org.eclipse.stp.bpmn.commands.ElementTypeEx;
import org.eclipse.stp.bpmn.commands.IElementTypeEx;

/**
 * 
 * Helper collections.
 * 
 * @author hmalphettes
 * @author <a href="http://www.intalio.com">&copy; Intalio, Inc.</a>
 */
public class BPMNElementTypesActivities {

    private static Collection<IElementTypeEx> TypesForSubProcessBorder;
    private static Collection<IElementTypeEx> TypesForPoolAndSubProcessBody;
    
    private static Collection<IElementTypeEx> TypesForSequenceEdgeSource;
    private static Collection<IElementTypeEx> TypesForSequenceEdgeTarget;
    private static Collection<IElementTypeEx> TypesForMessagingEdgeSource;
    private static Collection<IElementTypeEx> TypesForMessagingEdgeTarget;

    public static Collection<IElementTypeEx> getElementTypesForSubProcessBorder() {

        if (TypesForSubProcessBorder == null) {
            TypesForSubProcessBorder = Collections
                    .unmodifiableCollection(Arrays
                            .asList(new IElementTypeEx[] {
                                    ElementTypeEx
                                            .wrap(
                                                    BpmnElementTypes.Activity_2003,
                                                    ActivityType.EVENT_INTERMEDIATE_COMPENSATION_LITERAL
                                                            .getLiteral()),
                                    ElementTypeEx
                                            .wrap(
                                                    BpmnElementTypes.Activity_2003,
                                                    ActivityType.EVENT_INTERMEDIATE_ERROR_LITERAL
                                                            .getLiteral()),
                                    ElementTypeEx
                                            .wrap(
                                                    BpmnElementTypes.Activity_2003,
                                                    ActivityType.EVENT_INTERMEDIATE_TIMER_LITERAL
                                                            .getLiteral()) }

                            ));
        }

        return TypesForSubProcessBorder;
    }

    /**
     * TODO: put them in the order you want to see them
     * 
     * @return
     */
    public static Collection<IElementTypeEx> getElementTypesForPoolAndSubProcessBody() {
        if (TypesForPoolAndSubProcessBody == null) {
            TypesForPoolAndSubProcessBody = new ArrayList<IElementTypeEx>();
            for (Object at : ActivityType.VALUES) {
                String literal = ((ActivityType) at).getLiteral();
                IElementType elementType;
                if ("SubProcess".equals(literal)) {
                    elementType = BpmnElementTypes.SubProcess_2002;
                } else {
                    elementType = BpmnElementTypes.Activity_2001;
                }
                TypesForPoolAndSubProcessBody.add(ElementTypeEx.wrap(
                        elementType, literal));
            }
            TypesForPoolAndSubProcessBody.add(ElementTypeEx.wrap(
                    BpmnElementTypes.Activity_2001,
                    BpmnPackage.Literals.ACTIVITY__LOOPING.getName()));
            TypesForPoolAndSubProcessBody.add(ElementTypeEx.wrap(
                    BpmnElementTypes.SubProcess_2002,
                    BpmnPackage.Literals.ACTIVITY__LOOPING.getName()));
        }
        return TypesForPoolAndSubProcessBody;
    }

    /**
     * TODO: put them in the order you want to see them
     * 
     * @return
     */
    public static Collection<IElementTypeEx> getElementTypesForSequenceEdgeSource() {
        if (TypesForSequenceEdgeSource == null) {
            TypesForSequenceEdgeSource = new ArrayList<IElementTypeEx>();
            for (Object at : ActivityType.VALUES) {
                ActivityType attype = (ActivityType)at;
                String literal = attype.getLiteral();
                if (literal.startsWith("EventEnd")) {
                    continue;
                }
                IElementType elementType;
                if ("SubProcess".equals(literal)) {
                    elementType = BpmnElementTypes.SubProcess_2002;
                } else {
                    elementType = BpmnElementTypes.Activity_2001;
                }
                TypesForSequenceEdgeSource.add(ElementTypeEx.wrap(
                        elementType, literal));
            }
            TypesForSequenceEdgeSource.add(ElementTypeEx.wrap(
                    BpmnElementTypes.Activity_2001,
                    BpmnPackage.Literals.ACTIVITY__LOOPING.getName()));
            TypesForSequenceEdgeSource.add(ElementTypeEx.wrap(
                    BpmnElementTypes.SubProcess_2002,
                    BpmnPackage.Literals.ACTIVITY__LOOPING.getName()));
        }
        return TypesForSequenceEdgeSource;
    }
    /**
     * TODO: put them in the order you want to see them
     * 
     * @return
     */
    public static Collection<IElementTypeEx> getElementTypesForSequenceEdgeTarget() {
        if (TypesForSequenceEdgeTarget == null) {
            TypesForSequenceEdgeTarget = new ArrayList<IElementTypeEx>();
            for (Object at : ActivityType.VALUES) {
                ActivityType attype = (ActivityType)at;
                String literal = attype.getLiteral();
                if (literal.startsWith("EventStart")) {
                    continue;
                }
                IElementType elementType;
                if ("SubProcess".equals(literal)) {
                    elementType = BpmnElementTypes.SubProcess_2002;
                } else {
                    elementType = BpmnElementTypes.Activity_2001;
                }
                TypesForSequenceEdgeTarget.add(ElementTypeEx.wrap(
                        elementType, literal));
            }
            TypesForSequenceEdgeTarget.add(ElementTypeEx.wrap(
                    BpmnElementTypes.Activity_2001,
                    BpmnPackage.Literals.ACTIVITY__LOOPING.getName()));
            TypesForSequenceEdgeTarget.add(ElementTypeEx.wrap(
                    BpmnElementTypes.SubProcess_2002,
                    BpmnPackage.Literals.ACTIVITY__LOOPING.getName()));
        }
        return TypesForSequenceEdgeTarget;
    }

    /**
     * TODO: put them in the order you want to see them
     * 
     * @return
     */
    public static Collection<IElementTypeEx> getElementTypesForMessagingEdgeTarget() {
        if (TypesForMessagingEdgeTarget == null) {
            TypesForMessagingEdgeTarget = new ArrayList<IElementTypeEx>();
            for (Object at : ActivityType.VALUES) {
                ActivityType attype = (ActivityType)at;
                String literal = attype.getLiteral();
                if (literal.startsWith("Gateway")) {
                    continue;
                }
                switch (attype.getValue()) {
                case ActivityType.EVENT_END_EMPTY:
                case ActivityType.EVENT_START_EMPTY:
                case ActivityType.EVENT_INTERMEDIATE_EMPTY:
                case ActivityType.EVENT_END_TERMINATE:
                case ActivityType.SUB_PROCESS:
                    continue;
                }
                TypesForMessagingEdgeTarget.add(ElementTypeEx.wrap(
                        BpmnElementTypes.Activity_2001, literal));
            }
            TypesForMessagingEdgeTarget.add(ElementTypeEx.wrap(
                    BpmnElementTypes.Activity_2001,
                    BpmnPackage.Literals.ACTIVITY__LOOPING.getName()));
        }
        return TypesForMessagingEdgeTarget;
    }

    /**
     * TODO: put them in the order you want to see them
     * 
     * @return
     */
    public static Collection<IElementTypeEx> getElementTypesForMessagingEdgeSource() {
        if (TypesForMessagingEdgeSource == null) {
            TypesForMessagingEdgeSource = new ArrayList<IElementTypeEx>();
            for (Object at : ActivityType.VALUES) {
                ActivityType attype = (ActivityType)at;
                String literal = attype.getLiteral();
                if (literal.startsWith("Gateway")) {
                    continue;
                }
                switch (attype.getValue()) {
                case ActivityType.EVENT_END_EMPTY:
                case ActivityType.EVENT_START_EMPTY:
                case ActivityType.EVENT_INTERMEDIATE_EMPTY:
                case ActivityType.EVENT_END_TERMINATE:
                case ActivityType.SUB_PROCESS:
                    continue;
                }
                TypesForMessagingEdgeSource.add(ElementTypeEx.wrap(
                        BpmnElementTypes.Activity_2001, literal));
            }
            TypesForMessagingEdgeSource.add(ElementTypeEx.wrap(
                    BpmnElementTypes.Activity_2001,
                    BpmnPackage.Literals.ACTIVITY__LOOPING.getName()));
        }
        return TypesForMessagingEdgeSource;
    }

    
}
