/*****************************************************************************
 * Copyright (c) 2017 CEA LIST 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:
 *   Nicolas FAUVERGUE (CEA LIST) nicolas.fauvergue@cea.fr - Initial API and implementation
 *****************************************************************************/

import org.eclipse.papyrus.interoperability.common.blackboxes.ecore.EcoreHelper;
import org.eclipse.papyrus.interoperability.sysml14.sysml.blackboxes.notation.NotationBlackboxHelper;
import org.eclipse.papyrus.interoperability.sysml14.sysml.SysMLDiagramsUtils;
import org.eclipse.papyrus.interoperability.sysml14.sysml.SysMLDiagramsConstants;
import org.eclipse.papyrus.interoperability.sysml14.sysml.SysMLUtils;

modeltype notation "strict" uses 'http://www.eclipse.org/gmf/runtime/1.0.2/notation';
modeltype UML "strict" uses 'http://www.eclipse.org/uml2/5.0.0/UML';
modeltype ecore "strict" uses 'http://www.eclipse.org/emf/2002/Ecore';
modeltype viewpoint "strict" uses 'http://www.eclipse.org/papyrus/infra/viewpoints/configuration';
modeltype SysML11 "strict" uses 'http://www.eclipse.org/papyrus/0.7.0/SysML';
modeltype SysML14 "strict" uses 'http://www.eclipse.org/papyrus/sysml/1.4/SysML';
modeltype nattable "strict" uses 'http://www.eclipse.org/papyrus/nattable/model';


transformation SysMLParametricDiagram(in blockDefinitionViewpoint : viewpoint, in internalBlockViewpoint : viewpoint, in parametricViewpoint : viewpoint, in requirementViewpoint : viewpoint, in umlFile : UML, in inS14Profile : SysML14, in requirementNatTableS11 : nattable, in allocationNatTableS11 : nattable, in requirementNatTableS14 : nattable, in allocationNatTableS14 : nattable, in requirementTableViewPoint : viewpoint, in allocationTableViewPoint : viewpoint, inout notationFile : notation);

// Define needed constants
property diagramName:String = "Parametric";
property diagramConfigurationName:String = "SysML 1.4 Parametric";

property model:UML::Model = umlFile.rootObjects()[uml::Model]->any(true);
property rootDiagram:notation::Diagram;

property childrenToRemove:OrderedSet(notation::View);

mapping notation::Diagram::fromSysML11ParametricDiagram() : notation::Diagram when {self.type=diagramName} {
	init{
		var existingChildren:OrderedSet(notation::Node) := self.children;
		var existingEdges:OrderedSet(notation::Edge) := self.edges;
		result := self;
		rootDiagram := result;
		result.edges := object OrderedSet(notation::Edge){};
		result.edges := existingEdges->map fromSysML11Edge();
		result.children := object OrderedSet(notation::Node){};
		result.children := existingChildren->map fromSysML11Shape(result);
	}
	type := "CompositeStructure";
	
	// Create the annotation for versionning
	var model:UML::Model := umlFile.rootObjects()[uml::Model]->any(true);
	result.eAnnotations += model.createEAnnotationForVersioning();
	
	// Modify or create the compatibility version
	setOrCreateCompatibilityVersion(result);
	
	// Add the viewpoint configuration to the papyrus view style
	addPapyrusViewStyleConfiguration(result, model, getParametricPapyrusDiagramConfiguration());
	
	// Remove the needed children
	childrenToRemove->forEach(childToRemove){
		var parent:ecore::EObject := childToRemove.oclAsType(ecore::EObject).eContainer();
		if (parent.oclIsKindOf(notation::View)) {
			var parentView:notation::View := parent.oclAsType(notation::View);
			removeFromOwnerView(parentView, childToRemove);
		};
	};
}

// Get the requirement papyrus diagram configuration from the viewpoint file
helper getParametricPapyrusDiagramConfiguration() : viewpoint::PapyrusDiagram {
	return parametricViewpoint.objects()->selectByType(viewpoint::PapyrusDiagram)->any(curr | curr.name = diagramConfigurationName);
}

// Nodes ans shapes management
mapping notation::Node::fromSysML11Shape(parent:notation::View) : notation::Node disjuncts
	notation::BasicCompartment::fromSysML11BasicCompartment,
	notation::DecorationNode::fromSysML11DecorationNode,
	notation::Shape::fromSysML11StereotypeComment,
	notation::Shape::fromSysML11AffixedPropertyAsAffixedPort,
	notation::Shape::fromSysML11BlockAsClass,
	notation::Shape::fromSysML11ConstraintPropertyAsContraintProperty,
	notation::Shape::fromSysML11PropertyAsProperty,
	notation::Shape::fromSysML11DefaultShape
{}

mapping notation::Shape::fromSysML11AffixedPropertyAsAffixedPort(parent:notation::View) : notation::Shape when {self.oclIsTypeOf(notation::Shape) and self.type = PROPERTY_AS_AFFIXED_SYSML11} {
	init {
		result := self;
	}
	
	// Remove the existing children
	var existingChildren:OrderedSet(notation::Node) := self.children;
	children := object OrderedSet(notation::Node){};
	
	var isNameLabelDecorationNodeExist:Boolean := false;
	var isStereotypeLabelDecorationNodeExist:Boolean := false;
	
	// Loop on existing children to map with the new correct type
	existingChildren->forEach(existingChild){
		if (existingChild.type = AFFIXED_PORT_LABEL_DECORATIONNODE_SYSML11) {
			existingChild.type := PORT_NAME_LABEL_DECORATIONNODE_SYSML14;
			setPapyrusCSSForceValueVisible(existingChild, TRUE);
			isNameLabelDecorationNodeExist := true;
			children += existingChild;
		} elif (existingChild.type = APPLIEDSTEREOTYPE_AFFIXED_LABEL_DECORATIONODE_SYSML11) {
			existingChild.type := PORT_STEREOTYPE_LABEL_DECORATIONNODE_SYSML14;
			setPapyrusCSSForceValueVisible(existingChild, TRUE);			
			isStereotypeLabelDecorationNodeExist := true;
			children += existingChild;
		} elif (existingChild.type = COMPARTMENT_SHAPE_DISPLAY) {
			children += existingChild;
		};
	};
	
	// If the shape is not in the diagram, this is a Child node
	type := PORT_SHAPE_SYSML14;
	
	if(not isNameLabelDecorationNodeExist){
		var nameLabel:notation::DecorationNode := createDefaultFloatingNameLabelDecorationNode(PORT_NAME_LABEL_DECORATIONNODE_SYSML14);
		nameLabel.layoutConstraint.oclAsType(notation::Location).x := 25;
		nameLabel.layoutConstraint.oclAsType(notation::Location).y := 3;
		children += nameLabel;
	};
	if(not isNameLabelDecorationNodeExist){
		var stereotypeLabel:notation::DecorationNode := createDefaultFloatingNameLabelDecorationNode(PORT_STEREOTYPE_LABEL_DECORATIONNODE_SYSML14);
		stereotypeLabel.layoutConstraint.oclAsType(notation::Location).x := 25;
		stereotypeLabel.layoutConstraint.oclAsType(notation::Location).y := -10;
		children += stereotypeLabel;
	};
}

mapping notation::Shape::fromSysML11AffixedPortAsParameterBorderItem(parent:notation::View) : notation::Shape when {self.oclIsTypeOf(notation::Shape) and self.type = PROPERTY_AS_AFFIXED_SYSML11} {
	init {
		result := self;
	}
	
	// Remove the existing children
	var existingChildren:OrderedSet(notation::Node) := self.children;
	children := object OrderedSet(notation::Node){};
	
	// If the shape is not in the diagram, this is a Child node
	type := PARAMETER_BORDERITEM_SHAPE_SYSML14;
	
	var parameterLabel:notation::Shape := object notation::Shape{
		type := PARAMETER_LABEL_SHAPE_SYSML14;
		fontName := "Segoe UI";
	};
	parameterLabel.layoutConstraint := object notation::Bounds{};
	parameterLabel.eAnnotations += object ecore::EAnnotation{
		source := PAPYRUS_CSS_FORCE_VALUE;
		details += object ecore::EStringToStringMapEntry{
			key := "lineColor";
			value := TRUE;
		};
		details += object ecore::EStringToStringMapEntry{
			key := "fontHeight";
			value := TRUE;
		};
		details += object ecore::EStringToStringMapEntry{
			key := "bold";
			value := TRUE;
		};
		details += object ecore::EStringToStringMapEntry{
			key := "italic";
			value := TRUE;
		};
		details += object ecore::EStringToStringMapEntry{
			key := "fontColor";
			value := TRUE;
		};
		details += object ecore::EStringToStringMapEntry{
			key := "fillColor";
			value := TRUE;
		};
	};
	children += parameterLabel;
}

mapping notation::Shape::fromSysML11BlockAsClass(parent:notation::View) : notation::Shape when {self.oclIsTypeOf(notation::Shape) and self.type = BLOCK_AS_COMPOSITE_SYSML11} {
	init {
		result := self;
	}
	
	// Remove the existing children
	var existingChildren:OrderedSet(notation::Node) := self.children;
	children := object OrderedSet(notation::Node){};
	
	var isCN:Boolean := not parent.oclIsTypeOf(notation::Diagram);
	
	var isClassNameDecorationNodeExist:Boolean := false;
	var isStructureCompartmentExist:Boolean := false;
	
	// Loop on existing children to map with the new correct type
	existingChildren->forEach(existingChild){
		if (existingChild.type = LABEL_BLOCK_COMPARTMENT_SYSML11) {
			if (isCN) {
				existingChild.type := CLASS_NAME_LABEL_DECORATIONNODE_CN_SYSML14;
			} else {
				existingChild.type := CLASS_NAME_LABEL_DECORATIONNODE_SYSML14;
			};
			setPapyrusCSSForceValueVisible(existingChild, TRUE);
			isClassNameDecorationNodeExist := true;
			children += existingChild;
		} elif (existingChild.type = COMPARTMENT_STRUCTURE_SYSML11) {
			if (isCN) {
				existingChild.type := CLASS_STRUCTURE_COMPARTMENT_CN_SYSML14;
			} else {
				existingChild.type := CLASS_STRUCTURE_COMPARTMENT_SYSML14;
			};
			setPapyrusCSSForceValueVisible(existingChild, TRUE);
			// Calculate the new children
			existingChild.children := existingChild.children->map fromSysML11Shape(result);
			isStructureCompartmentExist := true;
			children += existingChild;
		} elif (existingChild.type = COMPARTMENT_SHAPE_DISPLAY) {
			children += existingChild;
		};
	};
	
	// If the shape is not in the diagram, this is a Child node
	if (not isCN) {
		type := CLASS_SHAPE_SYSML14;
		
		if(not isClassNameDecorationNodeExist){
			children += createDefaultNameLabelDecorationNode(CLASS_NAME_LABEL_DECORATIONNODE_SYSML14);
		};
		children += createDefaultFloatingNameLabelDecorationNode(CLASS_FLOATING_LABEL_DECORATIONNODE_SYSML14);
		
		if(not isStructureCompartmentExist){
			children += createDefaultBasicCompartement(CLASS_STRUCTURE_COMPARTMENT_SYSML14);
		};
		
	} else {
		type := CLASS_SHAPE_CN_SYSML14;
		
		if(not isClassNameDecorationNodeExist){
			children += createDefaultNameLabelDecorationNode(CLASS_NAME_LABEL_DECORATIONNODE_CN_SYSML14);
		};
		children += createDefaultFloatingNameLabelDecorationNode(CLASS_FLOATING_LABEL_DECORATIONNODE_CN_SYSML14);
		
		if(not isStructureCompartmentExist){
			children += createDefaultBasicCompartement(CLASS_STRUCTURE_COMPARTMENT_CN_SYSML14);
		};
	};
	
	// If the stereotype label decoration node and stereotype brace basic compartment are not available, create it
	children += existingChildren[notation::DecorationNode]->any(curr | curr.type = STEREOTYPE_LABEL_DECORATION_NODE)->map fromSysML11StereotypeLabel(result);
	if(result.children[notation::DecorationNode]->any(curr | curr.type = STEREOTYPE_LABEL_DECORATION_NODE).oclIsUndefined()){
		createStereotypeLabelDecorationNode(result, BLOCK_STEREOTYPE_QN);
	};
	children += existingChildren[notation::BasicCompartment]->any(curr | curr.type = STEREOTYPE_BRACE_COMPARTMENT)->map fromSysML11StereotypeBraceAndCompartment(result);
	if(result.children[notation::BasicCompartment]->any(curr | curr.type = STEREOTYPE_BRACE_COMPARTMENT).oclIsUndefined()){
		createStereotypeBasicCompartment(result, STEREOTYPE_BRACE_COMPARTMENT, BLOCK_STEREOTYPE_QN);
	};
	children += createTitleBasicCompartement(COMPARTMENT_SHAPE_DISPLAY);
	children += existingChildren[notation::BasicCompartment]->any(curr | curr.type = STEREOTYPE_COMPARTMENT_COMPARTMENT)->map fromSysML11StereotypeBraceAndCompartment(result);
	if(result.children[notation::BasicCompartment]->any(curr | curr.type = STEREOTYPE_BRACE_COMPARTMENT).oclIsUndefined()){
		createStereotypeBasicCompartment(result, STEREOTYPE_COMPARTMENT_COMPARTMENT, BLOCK_STEREOTYPE_QN);
	};
}

mapping notation::Shape::fromSysML11ConstraintPropertyAsContraintProperty(parent:notation::View) : notation::Shape when {self.oclIsTypeOf(notation::Shape) and self.type = CONSTRAINTBLOCKPROPERTY_AS_COMPOSITE_SYSML11} {
	init {
		result := self;
	}
	
	if(self.layoutConstraint.oclIsKindOf(notation::Bounds)){
		result.layoutConstraint.oclAsType(notation::Bounds).width := self.layoutConstraint.oclAsType(notation::Bounds).width;
		result.layoutConstraint.oclAsType(notation::Bounds).height := self.layoutConstraint.oclAsType(notation::Bounds).height;
	};
	
	// Remove the existing children
	var existingChildren:OrderedSet(notation::Node) := self.children;
	children := object OrderedSet(notation::Node){};
	
	var isClassNameDecorationNodeExist:Boolean := false;
	var isStructureCompartmentExist:Boolean := false;
	
	// Loop on existing children to map with the new correct type
	existingChildren->forEach(existingChild){
		if (existingChild.type = PROPERTY_LABEL_DECORATIONNODE_SYSML11) {
			existingChild.type := PROPERTY_NAME_LABEL_DECORATIONNODE_SYSML14;
			setPapyrusCSSForceValueVisible(existingChild, TRUE);
			isClassNameDecorationNodeExist := true;
			children += existingChild;
		} elif (existingChild.type = BLOCKPROPERTY_STRUCTURE_COMPARTMENT_SYSML11) {
			existingChild.type := PROPERTY_STRUCTURE_COMPARTMENT_SYSML14;
			setPapyrusCSSForceValueVisible(existingChild, TRUE);
			// Calculate the new children
			existingChild.children := existingChild.children->map fromSysML11Shape(result);
			isStructureCompartmentExist := true;
			children += existingChild;
		} elif (existingChild.type = "shape_uml_constraint_as_label") {
			existingChild.type := CONSTRAINTS_COMPARTMENT_SYSML14;
			// TODO: This must be a contraint, not a compartment
			children += existingChild;
		} elif (existingChild.type = COMPARTMENT_SHAPE_DISPLAY) {
			children += existingChild;
		};
	};
	
	type := CONSTRAINTPROPERTYCOMPOSITE_SHAPE_SYSML14;
	
	if(not isClassNameDecorationNodeExist){
		children += createDefaultNameLabelDecorationNode(PROPERTY_NAME_LABEL_DECORATIONNODE_SYSML14);
	};
	children += createDefaultFloatingNameLabelDecorationNode(PROPERTY_FLOATING_LABEL_DECORATIONNODE_SYSML14);
	
	if(not isStructureCompartmentExist){
		children += createDefaultBasicCompartement(PROPERTY_STRUCTURE_COMPARTMENT_SYSML14);
	};
	
	children += existingChildren[notation::DecorationNode]->any(curr | curr.type = STEREOTYPE_LABEL_DECORATION_NODE)->map fromSysML11StereotypeLabel(result);
	children += existingChildren[notation::BasicCompartment]->any(curr | curr.type = STEREOTYPE_BRACE_COMPARTMENT)->map fromSysML11StereotypeBraceAndCompartment(result);
	children += existingChildren[notation::BasicCompartment]->any(curr | curr.type = STEREOTYPE_COMPARTMENT_COMPARTMENT)->map fromSysML11StereotypeBraceAndCompartment(result);
	// Manage affixed ports
	children += existingChildren[notation::Shape]->map fromSysML11AffixedPortAsParameterBorderItem(result);
}

mapping notation::Shape::fromSysML11PropertyAsProperty(parent:notation::View) : notation::Shape when {self.oclIsTypeOf(notation::Shape) and self.type = BLOCKPROPERTY_AS_COMPOSITE_SYSML11} {
	init {
		result := self;
	}
	
	// Remove the existing children
	var existingChildren:OrderedSet(notation::Node) := self.children;
	children := object OrderedSet(notation::Node){};
	
	var isClassNameDecorationNodeExist:Boolean := false;
	var isStructureCompartmentExist:Boolean := false;
	
	// Loop on existing children to map with the new correct type
	existingChildren->forEach(existingChild){
		if (existingChild.type = PROPERTY_LABEL_DECORATIONNODE_SYSML11) {
			existingChild.type := PROPERTY_NAME_LABEL_DECORATIONNODE_SYSML14;
			setPapyrusCSSForceValueVisible(existingChild, TRUE);
			isClassNameDecorationNodeExist := true;
			children += existingChild;
		} elif (existingChild.type = BLOCKPROPERTY_STRUCTURE_COMPARTMENT_SYSML11) {
			existingChild.type := PROPERTY_STRUCTURE_COMPARTMENT_SYSML14;
			setPapyrusCSSForceValueVisible(existingChild, TRUE);
			// Calculate the new children
			existingChild.children := existingChild.children->map fromSysML11Shape(result);
			isStructureCompartmentExist := true;
			children += existingChild;
		} elif (existingChild.type = COMPARTMENT_SHAPE_DISPLAY) {
			children += existingChild;
		};
	};
	
	type := PROPERTY_SHAPE_SYSML14;
	
	if(not isClassNameDecorationNodeExist){
		children += createDefaultNameLabelDecorationNode(PROPERTY_NAME_LABEL_DECORATIONNODE_SYSML14);
	};
	children += createDefaultFloatingNameLabelDecorationNode(PROPERTY_FLOATING_LABEL_DECORATIONNODE_SYSML14);
	
	if(not isStructureCompartmentExist){
		children += createDefaultBasicCompartement(PROPERTY_STRUCTURE_COMPARTMENT_SYSML14);
	};
	
	children += existingChildren[notation::DecorationNode]->any(curr | curr.type = STEREOTYPE_LABEL_DECORATION_NODE)->map fromSysML11StereotypeLabel(result);
	children += existingChildren[notation::BasicCompartment]->any(curr | curr.type = STEREOTYPE_BRACE_COMPARTMENT)->map fromSysML11StereotypeBraceAndCompartment(result);
	children += existingChildren[notation::BasicCompartment]->any(curr | curr.type = STEREOTYPE_COMPARTMENT_COMPARTMENT)->map fromSysML11StereotypeBraceAndCompartment(result);
	// Manage affixed ports
	children += existingChildren[notation::Shape]->map fromSysML11AffixedPropertyAsAffixedPort(result);
}

mapping notation::Shape::fromSysML11StereotypeComment(parent:notation::View) : notation::Shape when {self.type = STEREOTYPE_COMMENT} {
	init {
		result := self;
	}
	
	childrenToRemove += result;
}

mapping notation::Shape::fromSysML11DefaultShape(parent:notation::View) : notation::Shape when {self.oclIsTypeOf(notation::Shape)} {
	init {
		var existingChildren:OrderedSet(notation::Node) := self.children;
		result := self;
		result.children := object OrderedSet(notation::Node){};
		result.children := existingChildren->map fromSysML11Shape(result);
	}
}

mapping notation::BasicCompartment::fromSysML11BasicCompartment(parent:notation::View) : notation::BasicCompartment disjuncts
	notation::BasicCompartment::fromSysML11StereotypeBraceAndCompartment,
	notation::BasicCompartment::fromSysML11BasicCompartmentDefault
{}

mapping notation::BasicCompartment::fromSysML11BasicCompartmentDefault(parent:notation::View) : notation::BasicCompartment when {self.oclIsTypeOf(notation::BasicCompartment) and self.type <> REQUIREMENT_IDINFO_COMPARTMENT_SYSML11}{
	init{
		result := self;
		setPapyrusCSSForceValueVisible(result, TRUE);
	}
}

mapping notation::BasicCompartment::fromSysML11StereotypeBraceAndCompartment(parent:notation::View) : notation::BasicCompartment when {self.oclIsTypeOf(notation::BasicCompartment) and (self.type = STEREOTYPE_BRACE_COMPARTMENT or self.type = STEREOTYPE_COMPARTMENT_COMPARTMENT) }{
	init{
		result := self;
		if(self.element.oclIsKindOf(UML::Stereotype)){
			var stereotype:UML::Stereotype := self.element.oclAsType(UML::Stereotype).toSysML14Stereotype(inS14Profile.objectsOfType(UML::Stereotype));
			if (stereotype.oclIsUndefined()) {
				// The stereotype was not find in SysML1.4, remove the compartment
				childrenToRemove += result;
			} else {
				result.element := stereotype.oclAsType(ecore::EObject);
			}
		};
	}
}

mapping notation::DecorationNode::fromSysML11DecorationNode(parent:notation::View) : notation::DecorationNode disjuncts
	notation::DecorationNode::fromSysML11StereotypeLabel,
	notation::DecorationNode::fromSysML11DecorationNodeDefault
{}

mapping notation::DecorationNode::fromSysML11StereotypeLabel(parent:notation::View) : notation::DecorationNode when {self.oclIsTypeOf(notation::DecorationNode) and self.type = STEREOTYPE_LABEL_DECORATION_NODE}{
	init{
		result := self;
		if(self.element.oclIsKindOf(UML::Stereotype)){
			var stereotype:UML::Stereotype := self.element.oclAsType(UML::Stereotype).toSysML14Stereotype(inS14Profile.objectsOfType(UML::Stereotype));
			if (stereotype.oclIsUndefined()) {
				// The stereotype was not find in SysML1.4, remove the decoration node
				childrenToRemove += result;
			} else {
				result.element := stereotype.oclAsType(ecore::EObject);
			}
		};
	}
}

mapping notation::DecorationNode::fromSysML11DecorationNodeDefault(parent:notation::View) : notation::DecorationNode when {self.oclIsTypeOf(notation::DecorationNode)} {
	init{
		result := self;
		setPapyrusCSSForceValueVisible(result, TRUE);
	}
}

// Helpers to create stereotypes decoration nodes and compartments
helper createStereotypeLabelDecorationNode(inout parent:notation::View, stereotypeQualifiedName:String){
	var stereotypeElement:UML::Stereotype := inS14Profile.objectsOfType(UML::Stereotype)->any(curr | curr.getQualifiedName()=stereotypeQualifiedName);
	if(not stereotypeElement.oclIsUndefined()){
		var createdStereotypeLabelDecorationNode:notation::DecorationNode := object DecorationNode{
			type := STEREOTYPE_LABEL_DECORATION_NODE;
			styles += object notation::StringValueStyle{
				name := "stereotype";
				stringValue := stereotypeQualifiedName;
			};
			layoutConstraint := object notation::Bounds{};
			element := stereotypeElement.oclAsType(ecore::EObject);
		};
		parent.children += createdStereotypeLabelDecorationNode;
	};
}

helper createStereotypeBasicCompartment(inout parent:notation::View, typeCompartment:String, stereotypeQualifiedName:String){
	var stereotypeElement:UML::Stereotype := inS14Profile.objectsOfType(UML::Stereotype)->any(curr | curr.getQualifiedName()=stereotypeQualifiedName);
	if(not stereotypeElement.oclIsUndefined()){
		var createdStereotypeBraceBasicCompartment:notation::BasicCompartment := object BasicCompartment{
			type := typeCompartment;
			styles += object notation::TitleStyle{};
			styles += object notation::StringValueStyle{
				name := "stereotype";
				stringValue := stereotypeQualifiedName;
			};
			layoutConstraint := object notation::Bounds{};
			element := stereotypeElement.oclAsType(ecore::EObject);
		};
		parent.children += createdStereotypeBraceBasicCompartment;
	};
}

// Edges management
mapping notation::Edge::fromSysML11Edge() : notation::Edge disjuncts
	notation::Edge::fromSysML11StereotypeCommentLink,
	notation::Edge::fromSysML11ConnectorAsConnector,
	notation::Edge::fromSysML11ConstraintAsContraint,
	notation::Edge::fromSysML11DependencyAsManifestation, // Must be done before Abstraction
	notation::Edge::fromSysML11DependencyAsRealization,  // Must be done before Abstraction
	notation::Edge::fromSysML11DependencyAsUsage,   // Must be done before Abstraction
	notation::Edge::fromSysML11DependencyAsAbstraction, // Must be done before Dependency
	notation::Edge::fromSysML11DependencyAsDependency,
	notation::Edge::fromSysML11DefaultEdge
{}

mapping notation::Edge::fromSysML11DependencyAsAbstraction() : notation::Edge when {self.element.oclIsKindOf(UML::Abstraction) and self.type = LINK_UML_DEPENDENCY_SYSML11} {
	init {
		result := self;
	}
	type := ABSTRATION_EDGE_SYSML14;
	
	var existingChildren:OrderedSet(notation::Node) := self.children;
	children := object OrderedSet(notation::Node){};
	
	var isNameLabelCompartmentExist:Boolean := false;
	var isStereotypeLabelCompartmentExist:Boolean := false;
	
	existingChildren->forEach(existingChild){
		if (existingChild.type = NAMEDELEMENT_LINK_NAME_DECORATIONODE_SYSML11) {
			existingChild.type := ABSTRACTION_NAME_LABEL_DECORATIONNODE_SYSML14;
			setPapyrusCSSForceValueVisible(existingChild, TRUE);
			isNameLabelCompartmentExist := true;
			children += existingChild;
		} elif (existingChild.type = APPLIEDSTEREOTYPE_LINK_LABEL_DECORATIONODE_SYSML11) {
			existingChild.type := ABSTRACTION_STEREOTYPE_LABEL_DECORATIONNODE_SYSML14;
			setPapyrusCSSForceValueVisible(existingChild, TRUE);
			isStereotypeLabelCompartmentExist := true;
			children += existingChild;
		};
	};
	
	if(not isNameLabelCompartmentExist){
		var nameLabelDecorationNode:notation::DecorationNode := createDefaultFloatingNameLabelDecorationNode(ABSTRACTION_NAME_LABEL_DECORATIONNODE_SYSML14);
		nameLabelDecorationNode.layoutConstraint.oclAsType(notation::Location).y := 40;
		children += nameLabelDecorationNode;
	};
	if(not isStereotypeLabelCompartmentExist){
		var stereotypeLabelDecorationNode:notation::DecorationNode := createDefaultFloatingNameLabelDecorationNode(ABSTRACTION_STEREOTYPE_LABEL_DECORATIONNODE_SYSML14);
		stereotypeLabelDecorationNode.layoutConstraint.oclAsType(notation::Location).y := 60;
		children += stereotypeLabelDecorationNode;
	};
}

mapping notation::Edge::fromSysML11ConnectorAsConnector() : notation::Edge when {self.type = LINK_UML_CONNECTOR_SYSML11} {
	init {
		result := self;
	}
	type := CONNECTOR_EDGE_SYSML14;
	
	var existingChildren:OrderedSet(notation::Node) := self.children;
	children := object OrderedSet(notation::Node){};
	
	var isNameLabelCompartmentExist:Boolean := false;
	var isStereotypeLabelCompartmentExist:Boolean := false;
	var isSourceMultiplicityCompartmentExist:Boolean := false;
	var isTargetMultiplicityCompartmentExist:Boolean := false;
	
	existingChildren->forEach(existingChild){
		if (existingChild.type = CONNECTOR_NAME_LABEL_DECORATIONNODE_SYSML11) {
			existingChild.type := CONNECTOR_NAME_LABEL_DECORATIONNODE_SYSML14;
			setPapyrusCSSForceValueVisible(existingChild, TRUE);
			isNameLabelCompartmentExist := true;
			children += existingChild;
		} elif (existingChild.type = APPLIEDSTEREOTYPE_LINK_LABEL_DECORATIONODE_SYSML11) {
			existingChild.type := CONNECTOR_STEREOTYPE_LABEL_DECORATIONNODE_SYSML14;
			setPapyrusCSSForceValueVisible(existingChild, TRUE);
			isStereotypeLabelCompartmentExist := true;
			children += existingChild;
		} elif (existingChild.type = CONNECTOR_SOURCE_MULTIPLICITY_DECORATIONODE_SYSML11) {
			existingChild.type := CONNECTOR_SOURCEMULTIPLICITY_LABEL_DECORATIONNODE_SYSML14;
			setPapyrusCSSForceValueVisible(existingChild, TRUE);
			isSourceMultiplicityCompartmentExist := true;
			children += existingChild;
		} elif (existingChild.type = CONNECTOR_TARGET_MULTIPLICITY_DECORATIONODE_SYSML11) {
			existingChild.type := CONNECTOR_TARGETMULTIPLICITY_LABEL_DECORATIONNODE_SYSML14;
			setPapyrusCSSForceValueVisible(existingChild, TRUE);
			isTargetMultiplicityCompartmentExist := true;
			children += existingChild;
		};
	};
	
	if(not isStereotypeLabelCompartmentExist){
		var stereotypeLabelDecorationNode:notation::DecorationNode := createDefaultFloatingNameLabelDecorationNode(CONNECTOR_STEREOTYPE_LABEL_DECORATIONNODE_SYSML14);
		stereotypeLabelDecorationNode.layoutConstraint.oclAsType(notation::Location).y := 60;
		children += stereotypeLabelDecorationNode;
	};
	if(not isNameLabelCompartmentExist){
		var nameLabelDecorationNode:notation::DecorationNode := createDefaultFloatingNameLabelDecorationNode(CONNECTOR_NAME_LABEL_DECORATIONNODE_SYSML14);
		nameLabelDecorationNode.layoutConstraint.oclAsType(notation::Location).y := -20;
		children += nameLabelDecorationNode;
	};
	if(not isSourceMultiplicityCompartmentExist){
		var nameLabelDecorationNode:notation::DecorationNode := createDefaultFloatingNameLabelDecorationNode(CONNECTOR_SOURCEMULTIPLICITY_LABEL_DECORATIONNODE_SYSML14);
		nameLabelDecorationNode.layoutConstraint.oclAsType(notation::Location).y := 20;
		children += nameLabelDecorationNode;
	};
	if(not isTargetMultiplicityCompartmentExist){
		var stereotypeLabelDecorationNode:notation::DecorationNode := createDefaultFloatingNameLabelDecorationNode(CONNECTOR_TARGETMULTIPLICITY_LABEL_DECORATIONNODE_SYSML14);
		stereotypeLabelDecorationNode.layoutConstraint.oclAsType(notation::Location).y := 20;
		children += stereotypeLabelDecorationNode;
	};
}

mapping notation::Edge::fromSysML11ConstraintAsContraint() : notation::Edge when {self.type = CONSTRAINT_CONTEXTEDGE_SHAPE_SYSML11} {
	init {
		result := self;
	}
	type := CONSTRAINT_CONSTRAINEDELEMENTEDGE_SHAPE_SYSML14;
	children := object OrderedSet(notation::Node){};
}

mapping notation::Edge::fromSysML11DependencyAsDependency() : notation::Edge when {self.element.oclIsKindOf(UML::Dependency) and self.type = LINK_UML_DEPENDENCY_SYSML11} {
	init {
		result := self;
	}
	type := DEPENDENCY_EDGE_SYSML14;
	
	var existingChildren:OrderedSet(notation::Node) := self.children;
	children := object OrderedSet(notation::Node){};
	
	var isNameLabelCompartmentExist:Boolean := false;
	var isStereotypeLabelCompartmentExist:Boolean := false;
	
	existingChildren->forEach(existingChild){
		if (existingChild.type = NAMEDELEMENT_LINK_NAME_DECORATIONODE_SYSML11) {
			existingChild.type := DEPENDENCY_NAME_LABEL_DECORATIONNODE_SYSML14;
			setPapyrusCSSForceValueVisible(existingChild, TRUE);
			isNameLabelCompartmentExist := true;
			children += existingChild;
		} elif (existingChild.type = APPLIEDSTEREOTYPE_LINK_LABEL_DECORATIONODE_SYSML11) {
			existingChild.type := DEPENDENCY_STEREOTYPE_LABEL_DECORATIONNODE_SYSML14;
			setPapyrusCSSForceValueVisible(existingChild, TRUE);
			isStereotypeLabelCompartmentExist := true;
			children += existingChild;
		};
	};
	
	if(not isNameLabelCompartmentExist){
		var nameLabelDecorationNode:notation::DecorationNode := createDefaultFloatingNameLabelDecorationNode(DEPENDENCY_NAME_LABEL_DECORATIONNODE_SYSML14);
		nameLabelDecorationNode.layoutConstraint.oclAsType(notation::Location).y := 40;
		children += nameLabelDecorationNode;
	};
	if(not isStereotypeLabelCompartmentExist){
		var stereotypeLabelDecorationNode:notation::DecorationNode := createDefaultFloatingNameLabelDecorationNode(DEPENDENCY_STEREOTYPE_LABEL_DECORATIONNODE_SYSML14);
		stereotypeLabelDecorationNode.layoutConstraint.oclAsType(notation::Location).y := 60;
		children += stereotypeLabelDecorationNode;
	};
}

mapping notation::Edge::fromSysML11DependencyAsManifestation() : notation::Edge when {self.element.oclIsKindOf(UML::Manifestation) and self.type = LINK_UML_DEPENDENCY_SYSML11} {
	init {
		result := self;
	}
	type := MANIFESTATION_EDGE_SYSML14;
	
	var existingChildren:OrderedSet(notation::Node) := self.children;
	children := object OrderedSet(notation::Node){};
	
	var isNameLabelCompartmentExist:Boolean := false;
	var isStereotypeLabelCompartmentExist:Boolean := false;
	
	existingChildren->forEach(existingChild){
		if (existingChild.type = NAMEDELEMENT_LINK_NAME_DECORATIONODE_SYSML11) {
			existingChild.type := MANIFESTATION_NAME_LABEL_DECORATIONNODE_SYSML14;
			setPapyrusCSSForceValueVisible(existingChild, TRUE);
			isNameLabelCompartmentExist := true;
			children += existingChild;
		} elif (existingChild.type = APPLIEDSTEREOTYPE_LINK_LABEL_DECORATIONODE_SYSML11) {
			existingChild.type := MANIFESTATION_STEREOTYPE_LABEL_DECORATIONNODE_SYSML14;
			setPapyrusCSSForceValueVisible(existingChild, TRUE);
			isStereotypeLabelCompartmentExist := true;
			children += existingChild;
		};
	};
	
	if(not isNameLabelCompartmentExist){
		var nameLabelDecorationNode:notation::DecorationNode := createDefaultFloatingNameLabelDecorationNode(MANIFESTATION_NAME_LABEL_DECORATIONNODE_SYSML14);
		nameLabelDecorationNode.layoutConstraint.oclAsType(notation::Location).y := 40;
		children += nameLabelDecorationNode;
	};
	if(not isStereotypeLabelCompartmentExist){
		var stereotypeLabelDecorationNode:notation::DecorationNode := createDefaultFloatingNameLabelDecorationNode(MANIFESTATION_STEREOTYPE_LABEL_DECORATIONNODE_SYSML14);
		stereotypeLabelDecorationNode.layoutConstraint.oclAsType(notation::Location).y := 60;
		children += stereotypeLabelDecorationNode;
	};
}

mapping notation::Edge::fromSysML11DependencyAsRealization() : notation::Edge when {self.element.oclIsKindOf(UML::Realization) and self.type = LINK_UML_DEPENDENCY_SYSML11} {
	init {
		result := self;
	}
	type := REALIZATION_EDGE_SYSML14;
	
	var existingChildren:OrderedSet(notation::Node) := self.children;
	children := object OrderedSet(notation::Node){};
	
	var isNameLabelCompartmentExist:Boolean := false;
	var isStereotypeLabelCompartmentExist:Boolean := false;
	
	existingChildren->forEach(existingChild){
		if (existingChild.type = NAMEDELEMENT_LINK_NAME_DECORATIONODE_SYSML11) {
			existingChild.type := REALIZATION_NAME_LABEL_DECORATIONNODE_SYSML14;
			setPapyrusCSSForceValueVisible(existingChild, TRUE);
			isNameLabelCompartmentExist := true;
			children += existingChild;
		} elif (existingChild.type = APPLIEDSTEREOTYPE_LINK_LABEL_DECORATIONODE_SYSML11) {
			existingChild.type := REALIZATION_STEREOTYPE_LABEL_DECORATIONNODE_SYSML14;
			setPapyrusCSSForceValueVisible(existingChild, TRUE);
			isStereotypeLabelCompartmentExist := true;
			children += existingChild;
		};
	};
	
	if(not isStereotypeLabelCompartmentExist){
		var stereotypeLabelDecorationNode:notation::DecorationNode := createDefaultFloatingNameLabelDecorationNode(REALIZATION_STEREOTYPE_LABEL_DECORATIONNODE_SYSML14);
		stereotypeLabelDecorationNode.layoutConstraint.oclAsType(notation::Location).y := 40;
		children += stereotypeLabelDecorationNode;
	};
	if(not isNameLabelCompartmentExist){
		var nameLabelDecorationNode:notation::DecorationNode := createDefaultFloatingNameLabelDecorationNode(REALIZATION_NAME_LABEL_DECORATIONNODE_SYSML14);
		nameLabelDecorationNode.layoutConstraint.oclAsType(notation::Location).y := 60;
		children += nameLabelDecorationNode;
	};
}

mapping notation::Edge::fromSysML11DependencyAsUsage() : notation::Edge when {self.element.oclIsKindOf(UML::Usage) and self.type = LINK_UML_DEPENDENCY_SYSML11} {
	init {
		result := self;
	}
	type := USAGE_EDGE_SYSML14;
	
	var existingChildren:OrderedSet(notation::Node) := self.children;
	children := object OrderedSet(notation::Node){};
	
	var isNameLabelCompartmentExist:Boolean := false;
	var isStereotypeLabelCompartmentExist:Boolean := false;
	
	existingChildren->forEach(existingChild){
		if (existingChild.type = NAMEDELEMENT_LINK_NAME_DECORATIONODE_SYSML11) {
			existingChild.type := USAGE_NAME_LABEL_DECORATIONNODE_SYSML14;
			setPapyrusCSSForceValueVisible(existingChild, TRUE);
			isNameLabelCompartmentExist := true;
			children += existingChild;
		} elif (existingChild.type = APPLIEDSTEREOTYPE_LINK_LABEL_DECORATIONODE_SYSML11) {
			existingChild.type := USAGE_STEREOTYPE_LABEL_DECORATIONNODE_SYSML14;
			setPapyrusCSSForceValueVisible(existingChild, TRUE);
			isStereotypeLabelCompartmentExist := true;
			children += existingChild;
		};
	};
	
	if(not isNameLabelCompartmentExist){
		var nameLabelDecorationNode:notation::DecorationNode := createDefaultFloatingNameLabelDecorationNode(USAGE_NAME_LABEL_DECORATIONNODE_SYSML14);
		nameLabelDecorationNode.layoutConstraint.oclAsType(notation::Location).y := 40;
		children += nameLabelDecorationNode;
	};
	if(not isStereotypeLabelCompartmentExist){
		var stereotypeLabelDecorationNode:notation::DecorationNode := createDefaultFloatingNameLabelDecorationNode(USAGE_STEREOTYPE_LABEL_DECORATIONNODE_SYSML14);
		stereotypeLabelDecorationNode.layoutConstraint.oclAsType(notation::Location).y := 60;
		children += stereotypeLabelDecorationNode;
	};
}

mapping notation::Edge::fromSysML11StereotypeCommentLink() : notation::Edge when {self.type = STEREOTYPE_COMMENT_LINK} {
	init {
		result := self;
	}
	
	childrenToRemove += result;
}

mapping notation::Edge::fromSysML11DefaultEdge() : notation::Edge {
	init {
		result := self;
	}
}