/*****************************************************************************
 * Copyright (c) 2016 CEA LIST.
 *
 * 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:
 *  Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
 *****************************************************************************/
 
import Rpy2PapyrusSemanticElements;
import RpyUtils;
import SysMLRpyUtils;
import RpyToPapyrusDiagamCommon;
import org.eclipse.papyrus.interoperability.rpy.blackboxes.Rpy2PapyrusNotationBlackboxes;

modeltype umlrpy "strict" uses 'http://www.eclipse.org/Papyrus/UMLRpy/1.0.0';
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 sysml11 "strict" uses 'http://www.eclipse.org/papyrus/0.7.0/SysML';
modeltype ecore "strict" uses 'http://www.eclipse.org/emf/2002/Ecore';
modeltype sash "strict" uses 'http://www.eclipse.org/papyrus/0.7.0/sashdi';
modeltype UMLPrimitivesTypes "strict" uses 'http://www.eclipse.org/uml2/5.0.0/Types' ;



transformation SysML11BlockDefinitionDiagram(in semantics : umlrpy, out graphics : notation, inout model:uml ,in Sysml11Profile:sysml11, in primitives:UMLPrimitivesTypes) 
access transformation Rpy2PapyrusSemanticElements(in inModel:umlrpy, out outModel:uml, in primitives:UMLPrimitivesTypes) 
extends Rpy2PapyrusSemanticElements(in inModel:umlrpy, out outModel:uml, in primitives:UMLPrimitivesTypes)
{
	//TODO : maybe we should have a transform method here
}

mapping rpymetamodel::IDiagram::iDiagramToSysML11BlockDefinitionDiagram(rpyProject:IProject):Diagram when{self.isUserModelDiagram() and self.isSysMLBlockDefinitionDiagram()}{
	//1. creating the diagram object
	init {
		//we are looking for the owner of the diagram
		
		//TODO : check the owner part!
		//TODO : don't use the default subsystem
		var subsystem: ISubsystem:= semantics.rootObjects()[IProject].defaultSubsystem![ISubsystem]; //TODO : could probably be replaced by the owner of the IDiagram (like done for StateMachine)
		var owner:EObject:= subsystem.oclAsType(DefaultSubsystemType).resolveIn (umlrpy::DefaultSubsystemType::iDefaultSubsystemTypeToPackage, uml::Package)![EObject];
		
		var iDiagramOwner:ecore::EObject:=self[EObject].eContainer()![EObject];
		if(iDiagramOwner.oclIsKindOf(umlrpy::IClass)){
			owner:= iDiagramOwner.resolveIn(ecore::EObject::generalMappingToUMLElement, uml::Element)![EObject];
		};
		//TODO : check owner and owner!
		result:=self.map createAndInitDiagram(rpyProject,getPapyrusDiagramType(), owner, owner);
	}	
	
	//1. find some objects
	var cgiClassChart:CGIClassChart:=self.graphicChart->oclAsSet().selectByType(CGIClassChart)->any(true);
	var cgiClass:CGIClass:=cgiClassChart.graphElements->selectByType(CGIClass)->any(true);
	var cgiDiagramFrame:CGIDiagramFrame:=cgiClassChart.graphElements->selectByType(CGIDiagramFrame)->any(true);
	
	
	children:= self.graphicChart.graphElements.map toSysML11BlockDefinitionDiagramShape(cgiClassChart, cgiClass->asSequence());
	edges:=self.graphicChart.graphElements.map toSysML11BlockDefinitionDiagramEdge();
	
}

/**
* Returns the type of the diagram to create
*/
query getPapyrusDiagramType():String{
	return 'BlockDefinition';
};


mapping GraphElementsType::toLayoutConstraint() : Bounds
{

if (self.oclIsTypeOf(CGIState) )
{
if (not (self[CGIState].m_transform.oclIsUndefined()->any(true)) and self[CGIState].m_transform->size()>5)
{
	var x:String :=self![CGIState].m_transform->at(5);
	var y:String :=self![CGIState].m_transform->at(6);

if (x.asInteger().oclIsUndefined() or x.asInteger().oclIsInvalid())
{
	result.x:=x.asFloat().round();

}
else 
{	
	result.x:=x.asInteger();
	
};
if (y.asInteger().oclIsUndefined() or y.asInteger().oclIsInvalid())
{
	
	result.y:=y.asFloat().round();
}
else 
{	
	
	result.y:=y.asInteger();
};
	var mtransform:List(String):= self![CGIState].m_transform->asList();
	var mpolygon:List(String):= self![CGIState].m_polygon->asList();
	result.height:=getStateHeight(mpolygon, mtransform).oclAsType(Integer);
	result.width:=getStateWidth(mpolygon, mtransform).oclAsType(Integer);

if ( not (self[CGIState].m_pParent.oclIsUndefined()->any(true)))
{
if (not (self[CGIState].m_pParent![CGIState].m_transform.oclIsUndefined()->any(true)) and self[CGIState].m_pParent![CGIState].m_transform->size()>5)
{
var xratio:String :=self[CGIState].m_pParent![CGIState].m_transform->at(1);
var yratio:String :=self![CGIState].m_transform->at(4);
var xration:Float :=xratio.asFloat();
var yration:Float :=yratio.asFloat();
result.x:=(result.x * xration).round();
result.y:=(result.y * yration).round();
result.width:=(result.width * xration).round();
result.height:=(result.height *yration).round();
}
}
}
elif (self[CGIState].m_type![String].equalsIgnoreCase("5"))
{
// do not specify the location for pseudo state
	//result.x:=18;
	//result.y:=9;
}
}
else if ( self.oclIsTypeOf(CGIClass))
{
if ( (not (self[CGIClass].m_transform.oclIsUndefined()->any(true)) and self[CGIClass].m_transform->size()>5))
{
var x:String :=self![CGIClass].m_transform->at(5);
var y:String :=self![CGIClass].m_transform->at(6);
var astypeX:Integer := x.oclAsType(Integer);
var astypeY:Integer := y.oclAsType(Integer);
if (x.asInteger().oclIsUndefined() or x.asInteger().oclIsInvalid())
{
	result.x:=x.asFloat().round();

}
else 
{	
	result.x:=x.asInteger();
	
};
if (y.asInteger().oclIsUndefined() or y.asInteger().oclIsInvalid())
{
	
	result.y:=y.asFloat().round();
}
else 
{	
	
	result.y:=y.asInteger();
};
	var mtransform:List(String):= self![CGIClass].m_transform->asList();
	var mpolygon:List(String):= self![CGIClass].m_polygon->asList();
	result.height:=getStateHeight(mpolygon, mtransform).oclAsType(Integer);
	result.width:=getStateWidth(mpolygon, mtransform).oclAsType(Integer);
}
	
}
}

//TODO--------------------------------------- rewrite me!

mapping Sequence(String)::toLayoutConstraints() : Bounds
{
if (self->size()>5)
{
	var num:String :=self->at(4);
	var num2:String :=self->at(1);
	result.x:=self->at(5).asInteger();
	result.y:=self->at(6).asInteger();
	
	var h:Real:=num.asFloat()*1233;
	var w:Real:=num2.asFloat()*1058;
	result.height:=h.round().oclAsType(Integer);
	result.width:=w.round().oclAsType(Integer);
}

}

mapping umlrpy::GraphElementsType::toDecorationNode(): notation::DecorationNode {


type:= 
		if self.oclIsTypeOf(CGIClass) then '5029' 
		elif (self.oclIsTypeOf(CGIState) and self[CGIState].m_type![String].equalsIgnoreCase("8")) then '6001' 
		elif (self.oclIsTypeOf(CGIState) and self[CGIState].m_type![String].equalsIgnoreCase("5")) then '8001'
		endif;
		if  (self.oclIsTypeOf(CGIState) )
		{
			if  (self[CGIState].m_type![String].equalsIgnoreCase("8"))
			
				layoutConstraint:= object Bounds
				{
					//	width:=63;
				}
			elif (self[CGIState].m_type![String].equalsIgnoreCase("5"))
			{
			// for the pseudo state
				layoutConstraint:= object Location
				{
						//x:=25;
						//y:=3;
				}
			}
		}
}

/**
*
* This mapping allows to create all views in a Papyrus SysML 1.1 BDD according to the Rpy Model
* @param
*		cgiClassChart : the class chart of the diagram, it is useful to find child to create for the created element
* @param
* 		rpyAllowedParent : the list of the allowed Rpy parent to manage the object.
*		if the Rpy parent is not in this list, the object won't be mapped
*/
mapping umlrpy::GraphElementsType::toSysML11BlockDefinitionDiagramShape(cgiClassChart:CGIClassChart, rpyAllowedParent:Sequence(GraphElementsType)) : Shape 
	disjuncts 
	umlrpy::CGIGenericElement::toSysML11BDDDataTypeShape, //TODO split with value type
	umlrpy::CGIGenericElement::toSysML11BDDUnitShape,
	umlrpy::CGIGenericElement::toSysML11BDDDimensionShape,
	umlrpy::CGIGenericElement::toSysML11BDDEnumerationShape,
	umlrpy::CGIGenericElement::toSysML11BDDBlockShape,
	umlrpy::CGIClass::toSysML11BDDBlockShape,
	umlrpy::CGIClass::toSysML11BDDConstraintBlockShape,
	umlrpy::CGIClass::toSysML11BDDFlowSpecificationShape,
	umlrpy::CGIBasicClass::toSysML11BDDActorShape,
	umlrpy::CGIPackage::toSysML11BDDPackageShape, 
	umlrpy::CGIGenericElement::toSysML11BDDSignalShape
	{}
	
mapping umlrpy::GraphElementsType::toSysML11BlockDefinitionDiagramEdge() : Edge 
	disjuncts 
	umlrpy::CGIAssociationEnd::toSysML11BDDAssociationEdge
	{}
	
/**
* This mapping creates the Block Shape with its compartment and their children
*/	
mapping umlrpy::CGIGenericElement::toSysML11BDDBlockShape(cgiClassChart:CGIClassChart, rpyAllowedParent:Sequence(GraphElementsType)) : Shape when {self.m_pModelObject.oclIsKindOf(IType) and self.m_pModelObject.oclAsType(IType).isUMLClass() and self.m_pParent.oclIsKindOf(GraphElementsType) and rpyAllowedParent->includes(self.m_pParent.oclAsType(GraphElementsType))}{
	type:="shape_sysml_block_as_classifier";
	element := self.m_pModelObject.resolveone().oclAsType(EObject);
	var decorationNode:notation::DecorationNode:= object DecorationNode{type:="label_sysml_block_name"};
	children+=decorationNode;
	var sysmlPropertyCompartment:=self.map toListCompartment("compartment_sysml_property_as_list", "Attribute");
	sysmlPropertyCompartment.children+=self.map toSysML11BDDBlockPropertyNode();//TODO : add check to distinghuish properties, from port, part, reference,  ...
	//TODO : do the mapping ofr all others children
	var sysmlPartCompartment:=self.map toListCompartment("compartment_sysml_part_as_list", null);
	var sysmlReferenceCompartment:=self.map toListCompartment("compartment_sysml_reference_as_list", null);
	var umlPortCompartment:=self.map toListCompartment("compartment_uml_port_as_list", null);
	var sysmlFlowportCompartment:=self.map toListCompartment("compartment_sysml_flowport_as_list", null);
	var umlOperationCompartment:=self.map toListCompartment("compartment_uml_operation_as_list", null);
	var sysmlContraintCompartment:=self.map toListCompartment("compartment_sysml_constraint_as_list", null);
	var sysmlValueCompartment:=self.map toListCompartment("compartment_sysml_value_as_list", null);
	children+= sysmlPropertyCompartment;
	children+= sysmlPartCompartment;
	children+= sysmlReferenceCompartment;
	children+= umlPortCompartment;
	children+= sysmlFlowportCompartment;
	children+= umlOperationCompartment;
	children+= sysmlContraintCompartment;
	children+= sysmlValueCompartment;
	
	layoutConstraint:= object Bounds{ x:=getX(self); y:=getY(self); width :=getRectangleWidth(self); height := getRectangleHeight(self)};
}

//TODO merge me with the previous one
/**
* This mapping creates the Block Shape with its compartment and their children
*/	
mapping umlrpy::CGIClass::toSysML11BDDBlockShape(cgiClassChart:CGIClassChart, rpyAllowedParent:Sequence(GraphElementsType)) : Shape when {self.oclIsTypeOf(CGIClass) and self.m_pParent<>null and  self.m_pModelObject.oclIsTypeOf(IClass) and not (self.m_pModelObject.oclAsType(IClass).isSysMLFlowSpecification() or self.m_pModelObject.oclAsType(IClass).isSysMLConstraintBlock()) and self.m_pParent.oclIsKindOf(GraphElementsType) and rpyAllowedParent->includes(self.m_pParent.oclAsType(GraphElementsType))}{
	var res:Boolean= self.m_pModelObject.oclIsTypeOf(IClass);

	type:="shape_sysml_block_as_classifier";
	element := self.m_pModelObject.resolveone().oclAsType(EObject);
	var decorationNode:notation::DecorationNode:= object DecorationNode{type:="label_sysml_block_name"};
	children+=decorationNode;
	var sysmlPropertyCompartment:=self.map toListCompartment("compartment_sysml_property_as_list", "Attribute");
	sysmlPropertyCompartment.children+=self.map toSysML11BDDBlockPropertyNode();//TODO : add check to distinghuish properties, from port, part, reference,  ...
	//TODO : do the mapping ofr all others children
	var sysmlPartCompartment:=self.map toListCompartment("compartment_sysml_part_as_list", null);
	var sysmlReferenceCompartment:=self.map toListCompartment("compartment_sysml_reference_as_list", null);
	var umlPortCompartment:=self.map toListCompartment("compartment_uml_port_as_list", null);
	var sysmlFlowportCompartment:=self.map toListCompartment("compartment_sysml_flowport_as_list", null);
	var umlOperationCompartment:=self.map toListCompartment("compartment_uml_operation_as_list", "Operation");
	var sysmlContraintCompartment:=self.map toListCompartment("compartment_sysml_constraint_as_list", null);
	var sysmlValueCompartment:=self.map toListCompartment("compartment_sysml_value_as_list", null);
	children+= sysmlPropertyCompartment;
	children+= sysmlPartCompartment;
	children+= sysmlReferenceCompartment;
	children+= umlPortCompartment;
	children+= sysmlFlowportCompartment;
	children+= umlOperationCompartment;
	children+= sysmlContraintCompartment;
	children+= sysmlValueCompartment;
	
	layoutConstraint:= object Bounds{ x:=getX(self); y:=getY(self); width :=getRectangleWidth(self); height := getRectangleHeight(self)};
}

/**
* This mapping creates the Block Shape with its compartment and their children
*/	
//TODO : merge me with previous one ?
mapping umlrpy::CGIClass::toSysML11BDDConstraintBlockShape(cgiClassChart:CGIClassChart, rpyAllowedParent:Sequence(GraphElementsType)) : Shape when {self.oclIsTypeOf(CGIClass) and self.m_pParent<>null and self.m_pModelObject.oclIsTypeOf(IClass) and self.m_pModelObject.oclAsType(IClass).isSysMLConstraintBlock() and self.m_pParent.oclIsKindOf(GraphElementsType) and rpyAllowedParent->includes(self.m_pParent.oclAsType(GraphElementsType))}{

// <children xmi:type="notation:Shape" xmi:id="_Mr2uIIlmEeaNf9-vLHMoKw" type="shape_sysml_flowspecification_as_classifier">
//    <children xmi:type="notation:DecorationNode" xmi:id="_Mr3VMIlmEeaNf9-vLHMoKw" type="label_sysml_flowspecification_name"/>
//    <children xmi:type="notation:ListCompartment" xmi:id="_Mr3VMYlmEeaNf9-vLHMoKw" type="compartment_sysml_flowproperty_as_list">
//      <styles xmi:type="notation:DrawerStyle" xmi:id="_Mr3VMolmEeaNf9-vLHMoKw"/>
//      <styles xmi:type="notation:TitleStyle" xmi:id="_Mr3VM4lmEeaNf9-vLHMoKw"/>
//      <styles xmi:type="notation:SortingStyle" xmi:id="_Mr3VNIlmEeaNf9-vLHMoKw"/>
//      <styles xmi:type="notation:FilteringStyle" xmi:id="_Mr3VNYlmEeaNf9-vLHMoKw"/>
//    </children>
//    <element xmi:type="uml:Interface" href="model.uml#_MpVloIlmEeaNf9-vLHMoKw"/>
//    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_Mr2uIYlmEeaNf9-vLHMoKw" x="89" y="90" width="327" height="226"/>
//  </children>

	//TODO : I probably forgot several compartment for this usecase!
	type:="shape_sysml_constraintblock_as_classifier";
	element := self.m_pModelObject.resolveone().oclAsType(EObject);
	
	var decorationNode:notation::DecorationNode:= object DecorationNode{type:="label_sysml_constraintblock_name"};
	children+=decorationNode;
	var sysmlParameterCompartment:=self.map toListCompartment("compartment_sysml_parameter_as_list", "ConstraintParameter");
	sysmlParameterCompartment.children+=self.map toSysML11BDDConstraintParameterNode("ConstraintParameter");//TODO : add check to distinghuish properties, from port, part, reference,  ...
	var sysmlPropertyCompartment:=self.map toListCompartment("compartment_sysml_constraint_as_list", "Constraint");
//	sysmlPropertyCompartment.children+=self.map toSysML11BDDBlockPropertyNode();//TODO : add check to distinghuish properties, from port, part, reference,  ...
	//TODO : do the mapping ofr all others children
//	var sysmlPartCompartment:=self.map toListCompartment("compartment_sysml_part_as_list", null);
//	var sysmlReferenceCompartment:=self.map toListCompartment("compartment_sysml_reference_as_list", null);
//	var umlPortCompartment:=self.map toListCompartment("compartment_uml_port_as_list", null);
//	var sysmlFlowportCompartment:=self.map toListCompartment("compartment_sysml_flowport_as_list", null);
//	var umlOperationCompartment:=self.map toListCompartment("compartment_uml_operation_as_list", null);
//	var sysmlContraintCompartment:=self.map toListCompartment("compartment_sysml_constraint_as_list", null);
//	var sysmlValueCompartment:=self.map toListCompartment("compartment_sysml_value_as_list", null);
	children+= sysmlParameterCompartment;
	children+= sysmlPropertyCompartment;
//	children+= sysmlPartCompartment;
//	children+= sysmlReferenceCompartment;
//	children+= umlPortCompartment;
//	children+= sysmlFlowportCompartment;
//	children+= umlOperationCompartment;
//	children+= sysmlContraintCompartment;
//	children+= sysmlValueCompartment;
	
	layoutConstraint:= object Bounds{ x:=getX(self); y:=getY(self); width :=getRectangleWidth(self); height := getRectangleHeight(self)};
}


/**
* This mapping creates the Block Shape with its compartment and their children
*/	
//TODO : merge me with previous one ?
mapping umlrpy::CGIClass::toSysML11BDDFlowSpecificationShape(cgiClassChart:CGIClassChart, rpyAllowedParent:Sequence(GraphElementsType)) : Shape when {self.oclIsTypeOf(CGIClass) and self.m_pParent<>null and self.m_pModelObject.oclIsTypeOf(IClass) and self.m_pModelObject.oclAsType(IClass).isSysMLFlowSpecification() and self.m_pParent.oclIsKindOf(GraphElementsType) and rpyAllowedParent->includes(self.m_pParent.oclAsType(GraphElementsType))}{

// <children xmi:type="notation:Shape" xmi:id="_Mr2uIIlmEeaNf9-vLHMoKw" type="shape_sysml_flowspecification_as_classifier">
//    <children xmi:type="notation:DecorationNode" xmi:id="_Mr3VMIlmEeaNf9-vLHMoKw" type="label_sysml_flowspecification_name"/>
//    <children xmi:type="notation:ListCompartment" xmi:id="_Mr3VMYlmEeaNf9-vLHMoKw" type="compartment_sysml_flowproperty_as_list">
//      <styles xmi:type="notation:DrawerStyle" xmi:id="_Mr3VMolmEeaNf9-vLHMoKw"/>
//      <styles xmi:type="notation:TitleStyle" xmi:id="_Mr3VM4lmEeaNf9-vLHMoKw"/>
//      <styles xmi:type="notation:SortingStyle" xmi:id="_Mr3VNIlmEeaNf9-vLHMoKw"/>
//      <styles xmi:type="notation:FilteringStyle" xmi:id="_Mr3VNYlmEeaNf9-vLHMoKw"/>
//    </children>
//    <element xmi:type="uml:Interface" href="model.uml#_MpVloIlmEeaNf9-vLHMoKw"/>
//    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_Mr2uIYlmEeaNf9-vLHMoKw" x="89" y="90" width="327" height="226"/>
//  </children>
	type:="shape_sysml_flowspecification_as_classifier";
	element := self.m_pModelObject.resolveone().oclAsType(EObject);
	var decorationNode:notation::DecorationNode:= object DecorationNode{type:="label_sysml_flowspecification_name"};
	children+=decorationNode;
	var sysmlPropertyCompartment:=self.map toListCompartment("compartment_sysml_flowproperty_as_list", "FlowProperty");
	sysmlPropertyCompartment.children+=self.map toSysML11BDDFlowPropertyNode("FlowProperty");//TODO : add check to distinghuish properties, from port, part, reference,  ...
	//TODO : do the mapping ofr all others children
//	var sysmlPartCompartment:=self.map toListCompartment("compartment_sysml_part_as_list", null);
//	var sysmlReferenceCompartment:=self.map toListCompartment("compartment_sysml_reference_as_list", null);
//	var umlPortCompartment:=self.map toListCompartment("compartment_uml_port_as_list", null);
//	var sysmlFlowportCompartment:=self.map toListCompartment("compartment_sysml_flowport_as_list", null);
//	var umlOperationCompartment:=self.map toListCompartment("compartment_uml_operation_as_list", null);
//	var sysmlContraintCompartment:=self.map toListCompartment("compartment_sysml_constraint_as_list", null);
//	var sysmlValueCompartment:=self.map toListCompartment("compartment_sysml_value_as_list", null);
	children+= sysmlPropertyCompartment;
//	children+= sysmlPartCompartment;
//	children+= sysmlReferenceCompartment;
//	children+= umlPortCompartment;
//	children+= sysmlFlowportCompartment;
//	children+= umlOperationCompartment;
//	children+= sysmlContraintCompartment;
//	children+= sysmlValueCompartment;
	
	layoutConstraint:= object Bounds{ x:=getX(self); y:=getY(self); width :=getRectangleWidth(self); height := getRectangleHeight(self)};
}

mapping umlrpy::CGIGenericElement::toSysML11BDDUnitShape(cgiClassChart:CGIClassChart, rpyAllowedParent:Sequence(GraphElementsType)) : Shape when {self.m_pModelObject.oclIsKindOf(IType) and self.m_pModelObject.oclAsType(IType).isUMLInstanceSpecification() and self.m_pModelObject.oclAsType(IType).isSysMLUnit() and self.m_pParent.oclIsKindOf(GraphElementsType) and rpyAllowedParent->includes(self.m_pParent.oclAsType(GraphElementsType))}{
	type:="shape_sysml_unit_as_classifier";
	element := self.m_pModelObject.resolveone().oclAsType(EObject);
	var decorationNode:notation::DecorationNode:= object DecorationNode{type:="label_sysml_unit_name"};
	children+=decorationNode;
	//TODO : add compartment as hidden
	layoutConstraint:= object Bounds{ x:=getX(self); y:=getY(self); width :=getRectangleWidth(self); height := getRectangleHeight(self)};
}
mapping umlrpy::CGIGenericElement::toSysML11BDDDimensionShape(cgiClassChart:CGIClassChart, rpyAllowedParent:Sequence(GraphElementsType)) : Shape when {self.m_pModelObject.oclIsKindOf(IType) and self.m_pModelObject.oclAsType(IType).isUMLInstanceSpecification() and self.m_pModelObject.oclAsType(IType).isSysMLDimension() and self.m_pParent.oclIsKindOf(GraphElementsType) and rpyAllowedParent->includes(self.m_pParent.oclAsType(GraphElementsType))}{
	type:="shape_sysml_dimension_as_classifier";
	element := self.m_pModelObject.resolveone().oclAsType(EObject);
	var decorationNode:notation::DecorationNode:= object DecorationNode{type:="label_sysml_dimension_name"};
	children+=decorationNode;
	//TODO : add compartment as hidden
	layoutConstraint:= object Bounds{ x:=getX(self); y:=getY(self); width :=getRectangleWidth(self); height := getRectangleHeight(self)};
}

//TODO : check compartment of all created elements
//TODO : create comment link and other stuff to dispay stereotype in diagram
/**
* map the Rpy enumeration representation to the Papyrus Enumeration
*/
mapping umlrpy::CGIGenericElement::toSysML11BDDEnumerationShape(cgiClassChart:CGIClassChart, rpyAllowedParent:Sequence(GraphElementsType)) : Shape when {self.m_pModelObject.oclIsKindOf(IType) and self.m_pModelObject.oclAsType(IType).isUMLEnumeration() and self.m_pParent.oclIsKindOf(GraphElementsType) and rpyAllowedParent->includes(self.m_pParent.oclAsType(GraphElementsType))}{
	type:="shape_uml_enumeration_as_classifier";
	element := self.m_pModelObject.resolveone().oclAsType(EObject);
	var decorationNode:notation::DecorationNode:= object DecorationNode{type:="label_uml_namedelement_name"};
	children+=decorationNode;
	var enumLiteralCompartment:=self.map toListCompartment("compartment_uml_enumerationliteral_as_list", "EnumerationLiteral");
	enumLiteralCompartment.children+=self.map toSysML11BDDEnumerationLiteralNode();
	children+=enumLiteralCompartment;
	layoutConstraint:= object Bounds{ x:=getX(self); y:=getY(self); width :=getRectangleWidth(self); height := getRectangleHeight(self)};
}

mapping umlrpy::CGIGenericElement::toSysML11BDDDataTypeShape(cgiClassChart:CGIClassChart, rpyAllowedParent:Sequence(GraphElementsType)) : Shape when {self.m_pModelObject.oclIsKindOf(IType) and self.m_pModelObject.oclAsType(IType).isUMLDataType() and self.m_pParent.oclIsKindOf(GraphElementsType) and rpyAllowedParent->includes(self.m_pParent.oclAsType(GraphElementsType))}{
	type:="shape_uml_datatype_as_classifier";
	element := self.m_pModelObject.resolveone().oclAsType(EObject);
	var decorationNode:notation::DecorationNode:= object DecorationNode{type:="label_uml_namedelement_name"};
	children+=decorationNode;
	var propertyCompartment:=self.map toListCompartment("compartment_uml_property_as_list", null);
	var operationCompartment:=self.map toListCompartment("compartment_uml_operation_as_list", null);
	children+=propertyCompartment;
	children+=operationCompartment;
    layoutConstraint:= object Bounds{ x:=getX(self); y:=getY(self); width :=getRectangleWidth(self); height := getRectangleHeight(self)};
}

/**
* Create all View to represent wanted the EnumerationLiteral
*/
mapping CGIGenericElement::toSysML11BDDEnumerationLiteralNode() : OrderedSet(Node){
init{
	var isExplicit:boolean:=self.Compartments[CGICompartment].m_displayOption->includes("Explicit");
	var isAll:boolean:=self.Compartments[CGICompartment].m_displayOption->includes("All");
	var isPublic:boolean:=self.Compartments[CGICompartment].m_displayOption->includes("Public"); //IEnumrationLiteral can't be set as public or others
	if(isAll or isPublic){
		//in this case nothing is serialized in rpy file, so we create all view from the literal views
		//we can't use a mapping method because when EnumerationLiteral are represented several time on the same diagram,we will call the same mapping for the same element
		//and in this case, QVTO call the mapping only the first time and return directly the result the next time without creating new object!
		self.m_pModelObject.oclAsType(IType).Literals->forEach(lit){
				result+= lit.oclAsType(IEnumerationLiteral).toSysML11BDDEnumerationLiteralNode();
		};
	}elif(isExplicit){
			self.Compartments[CGICompartment].Items->forEach(lit){
					result+= lit.oclAsType(IEnumerationLiteral).toSysML11BDDEnumerationLiteralNode();
			};
		};	
	}
}

/**
* Create all View to represent wanted the SysML Properties
*/
mapping CGIGenericElement::toSysML11BDDBlockPropertyNode() : OrderedSet(Node){
init{
	var isExplicit:boolean:=self.Compartments[CGICompartment].m_displayOption->includes("Explicit");
	var isAll:boolean:=self.Compartments[CGICompartment].m_displayOption->includes("All");
	var isPublic:boolean:=self.Compartments[CGICompartment].m_displayOption->includes("Public"); //IEnumrationLiteral can't be set as public or others
	if(isAll or isPublic){ //TODO checlk in Rpy that for block : isAll or Public is equals? !
		//in this case nothing is serialized in rpy file, so we create all view from the literal views
		//we can't use a mapping method because when EnumerationLiteral are represented several time on the same diagram,we will call the same mapping for the same element
		//and in this case, QVTO call the mapping only the first time and return directly the result the next time without creating new object!
		self.m_pModelObject.oclAsType(IType).Attrs->forEach(attr){
				result+= attr.oclAsType(IAttribute).toSysML11BDDBlockPropertyNode();
		};
	}elif(isExplicit){
			self.Compartments[CGICompartment].Items->forEach(attr){
					result+= attr.oclAsType(IAttribute).toSysML11BDDBlockPropertyNode();
			};
		};	
	}
}



/**
* Create all View to represent wanted the SysML Properties
*/
//TODO : merge me with the previous one
mapping CGIClass::toSysML11BDDBlockPropertyNode() : OrderedSet(Node){ //TODO : the CGI comparmtent must probably be a parameter!
init{
	var isExplicit:boolean:=self.Compartments[CGICompartment].m_displayOption->includes("Explicit");
	var isAll:boolean:=self.Compartments[CGICompartment].m_displayOption->includes("All");
	var isPublic:boolean:=self.Compartments[CGICompartment].m_displayOption->includes("Public"); //IEnumrationLiteral can't be set as public or others
	if(isAll or isPublic){ //TODO checlk in Rpy that for block : isAll or Public is equals? !
		//in this case nothing is serialized in rpy file, so we create all view from the literal views
		//we can't use a mapping method because when EnumerationLiteral are represented several time on the same diagram,we will call the same mapping for the same element
		//and in this case, QVTO call the mapping only the first time and return directly the result the next time without creating new object!
		self.m_pModelObject.oclAsType(IType).Attrs->forEach(attr){
				result+= attr.oclAsType(IAttribute).toSysML11BDDBlockPropertyNode();
		};
	}elif(isExplicit){
			self.Compartments[CGICompartment].Items->forEach(attr){
					result+= attr.oclAsType(IAttribute).toSysML11BDDBlockPropertyNode();
			};
		};	
	}
}

/**
* This query create the Node View for a given SysML Property
*/
query umlrpy::IAttribute::toSysML11BDDBlockPropertyNode() : Node{
	return object Node{
		element:=self.resolveoneIn(umlrpy::IVariable::iVariableToUMLElement).oclAsType(EObject);
		type:="shape_uml_property_as_label";
		styles:= object ShapeStyle{};
		layoutConstraint:= object Location{};
	};
}

/**
* This query create the Node View for a given SysML Property
*/
//TODO : merge me with previous one
query umlrpy::IRelation::toSysML11BDDBlockConstraintNode() : Node{
	return object Node{
		element:=self.resolveoneIn(umlrpy::IRelation::iRelationToUMLElement).oclAsType(EObject);
		type:="shape_uml_property_as_label";
		styles:= object ShapeStyle{};
		layoutConstraint:= object Location{};
	};
}

//TODO : merge me with previous one
query umlrpy::IAttribute::toSysML11BDDFlowPorpertyNode() : Node{
	return object Node{
		element:=self.resolveoneIn(umlrpy::IVariable::iVariableToUMLElement).oclAsType(EObject);
		type:="shape_sysml_flowproperty_as_label";
		styles:= object ShapeStyle{};
		layoutConstraint:= object Location{};
	};
}

mapping CGIClass::toSysML11BDDFlowPropertyNode(rpyCptName:String) : OrderedSet(Node) when {self.m_pModelObject.oclIsTypeOf(IClass) and self.m_pModelObject.oclAsType(IClass).isSysMLFlowSpecification()}{
init{
	//TODO add a check for <>null for this compartment
	var rpyCpt:CGICompartment :=self.Compartments->selectByKind(CGICompartment)->selectOne(cpt | cpt.m_name=rpyCptName);
	
	var isExplicit:boolean:=rpyCpt.m_displayOption->includes("Explicit");
	var isAll:boolean:=rpyCpt.m_displayOption->includes("All");
	var isPublic:boolean:=rpyCpt.m_displayOption->includes("Public");
	if(isAll or isPublic){ //TODO checlk in Rpy that for block : isAll or Public is equals? !
		//in this case nothing is serialized in rpy file, so we create all view from the literal views
		//we can't use a mapping method because when EnumerationLiteral are represented several time on the same diagram,we will call the same mapping for the same element
		//and in this case, QVTO call the mapping only the first time and return directly the result the next time without creating new object!
		self.m_pModelObject.oclAsType(IClass).Attrs->selectByType(IAttribute)->forEach(attr){
//    		var res:uml::Element:=relation.resolveoneIn(umlrpy::IRelation::iRelationToUMLElement);
//    		if(res.oclAsType(uml::Property)){
	
		//TODO : check it is a flow property in RPY
    			result+= attr.toSysML11BDDFlowPorpertyNode();
    		}
//    		if(res.getAppliedStereotype(getSysML11Stereotype("ConstraintParameter").getQualifiedName())){//TODO : need to be checked
    			
//    		}
//    		if(relation.oclIsKindOf(ISysMLPort) and res<>null){
//    			var isysmlPort:umlrpy::ISysMLPort:=relation.oclAsType(ISysMLPort);
//    			isysmlPort.Stereotypes->forEach(istereotype){
//    			relation.map applyIStereotypeToUMLElement(res, istereotype.oclAsType(IStereotype));
//    		}	
			
//    	}C
//    };
//				result+= attr.oclAsType(ISysMLPort).toSysML11BDDBlockPropertyNode();
//		};
	}elif(isExplicit){

		//TODO : ISySML Port is not yet an Item in the metamodel	
//			self.Compartments[CGICompartment].Items->forEach(attr){
//					result+= attr.oclAsType(IAttribute).toSysML11BDDBlockPropertyNode();
//			};
		};	
	}
}

mapping CGIClass::toSysML11BDDConstraintParameterNode(rpyCptName:String) : OrderedSet(Node) when {self.m_pModelObject.oclIsTypeOf(IClass) and self.m_pModelObject.oclAsType(IClass).isSysMLConstraintBlock()}{
init{
	var rpyCpt:CGICompartment :=self.Compartments->selectByKind(CGICompartment)->selectOne(cpt | cpt.m_name=rpyCptName);

	var isExplicit:boolean:=rpyCpt.m_displayOption->includes("Explicit");
	var isAll:boolean:=rpyCpt.m_displayOption->includes("All");
	var isPublic:boolean:=rpyCpt.m_displayOption->includes("Public");
	if(isAll or isPublic){ //TODO checlk in Rpy that for block : isAll or Public is equals? !
		//in this case nothing is serialized in rpy file, so we create all view from the literal views
		//we can't use a mapping method because when EnumerationLiteral are represented several time on the same diagram,we will call the same mapping for the same element
		//and in this case, QVTO call the mapping only the first time and return directly the result the next time without creating new object!
		self.m_pModelObject.oclAsType(IClass).Ports->forEach(relation){
//    		var res:uml::Element:=relation.resolveoneIn(umlrpy::IRelation::iRelationToUMLElement);
//    		if(res.oclAsType(uml::Property)){
    			result+= relation.toSysML11BDDBlockConstraintNode();
    		}
//    		if(res.getAppliedStereotype(getSysML11Stereotype("ConstraintParameter").getQualifiedName())){//TODO : need to be checked
    			
//    		}
//    		if(relation.oclIsKindOf(ISysMLPort) and res<>null){
//    			var isysmlPort:umlrpy::ISysMLPort:=relation.oclAsType(ISysMLPort);
//    			isysmlPort.Stereotypes->forEach(istereotype){
//    			relation.map applyIStereotypeToUMLElement(res, istereotype.oclAsType(IStereotype));
//    		}	
			
//    	}C
//    };
//				result+= attr.oclAsType(ISysMLPort).toSysML11BDDBlockPropertyNode();
//		};
	}elif(isExplicit){

		//TODO : ISySML Port is not yet an Item in the metamodel	
//			self.Compartments[CGICompartment].Items->forEach(attr){
//					result+= attr.oclAsType(IAttribute).toSysML11BDDBlockPropertyNode();
//			};
		};	
	}
}

/**
* This query create the Node View for a given IEnumerationLiteral
*/
query umlrpy::IEnumerationLiteral::toSysML11BDDEnumerationLiteralNode() : Node{
	return object Node{
		element:=self.resolveoneIn(umlrpy::IEnumerationLiteral::toUMLEnumerationLiteral).oclAsType(EObject);
		type:="shape_uml_enumerationliteral_as_label";
		styles:= object ShapeStyle{};
		layoutConstraint:= object Location{};
	};
}

mapping umlrpy::CGIAssociationEnd::toSysML11BDDAssociationEdge() : Connector 
{
	//TODO : use the class RpyNode for the anchors!
	var sourceNode:CGIClass:=self.m_pSource![CGIClass];
	var targetNode:CGIClass:=self.m_pTarget![CGIClass];
	
	var source_mtransform:List(String):= sourceNode.m_transform->asList();
	var source_mpolygon:List(String):= sourceNode.m_polygon->asList();
	var target_mtransform:List(String):= targetNode.m_transform->asList();
	var target_mpolygon:List(String):= targetNode.m_polygon->asList();
	var source_Port:List(String):= self.m_SourcePort->asList();
	var target_Port:List(String):= self.m_TargetPort->asList();
	

	//we try the new way for anchor calculus
//	var anchorsAndBendpoints:Sequence(String):=getAnchorsAndBendpoints(self, result);
//	var sourceAnchorId:String:=anchorsAndBendpoints->asSequence()->at(1);
//	var	targetAnchorId:String:=anchorsAndBendpoints->asSequence()->at(2);
	addAnchorsAndBendpoints(self, result);
	
	var rpySemanticElement:=self.m_pModelObject;
	
	//looking for the uml Association
	var association:Association:=null;
	if(rpySemanticElement.oclIsTypeOf(IAssociationEnd)){
		association:=self.m_pModelObject.resolveoneIn(umlrpy::IAssociationEnd::iAssociationEndToUMLAssociation, uml::Association);
	}elif(rpySemanticElement.oclIsTypeOf(IPart)){
		association:=self.m_pModelObject.resolveoneIn(umlrpy::IPart::iPartToUMLAssociation, uml::Association).oclAsType(Association);
	};
	
	
	result.element:=association.oclAsType(EObject);
	
	result.type := "link_sysml_association";
	result.source:= sourceNode.resolveIn(umlrpy::GraphElementsType::toSysML11BlockDefinitionDiagramShape, Shape)![View];
	result.target:= targetNode.resolveIn(umlrpy::GraphElementsType::toSysML11BlockDefinitionDiagramShape, Shape)![View];
	
	//no idea about this code!
//	result.children->forEach(element){
//		element.type:='6007'
//	};
//	result.sourceAnchor := object IdentityAnchor{
//		id:=sourceAnchorId;
//	};
//	result.targetAnchor := object IdentityAnchor{
//		id := targetAnchorId;
//	};
	
	
//	result.bendpoints:= object RelativeBendpoints{
////		points:= object RelativeBendpointList{
////		
////		}
//	};
	// add DecorationNode
	//	result.children := self.getDecorationNodes();
	
	
	//TODO : manage the place of each label of the association
	var True:String:="1";
	var False:String:="0";
	var res:=self.m_bShowLinkName;
	var showSourceRole:=self.m_bShowSourceRole;
	var showTargetRole:=self.m_bShowTargetRole;
	var showSourceMultiplicity:=self.m_bShowSourceMultiplicity;
	var showTargetMultiplicity:=self.m_bShowTargetMultiplicity;
	
	result.children+= object DecorationNode{
		type:="linklabel_uml_appliedstereotype";
//		visible:=self.m_bShowLinkName=True;
		layoutConstraint:= object Location{ y:=-30};
	};
	
	//TODO : we could manage maskLabel style too
	result.children+= object DecorationNode{
		type:="linklabel_uml_namedelement_name";
		visible:=self.m_bShowLinkName=True;
		layoutConstraint:= object Location{y:=-10};
	};

	result.children+= object DecorationNode{
		type:="linklabel_uml_association_source_role";
		visible:=self.m_bShowSourceRole=True;
		layoutConstraint:= object Location{y:=-10};
	};
	
	result.children+= object DecorationNode{
		type:="linklabel_uml_association_source_multiplicity";
		visible:=self.m_bShowSourceMultiplicity=True;
		layoutConstraint:= object Location{y:=10};
	};
	
	result.children+= object DecorationNode{
		type:="linklabel_uml_association_target_role";
		visible:=self.m_bShowTargetRole=True;
		layoutConstraint:= object Location{y:=-10};
	};
	
	result.children+= object DecorationNode{
		type:="linklabel_uml_association_target_multiplicity";
		visible:=self.m_bShowTargetMultiplicity=True;
		layoutConstraint:= object Location{y:=10};
	};

	result.styles+= object FontStyle{};
	
	result.styles+= object EObjectValueStyle{
		name:="semantic_source_end";
		eObjectValue:=association.memberEnd->asSequence()->at(1).oclAsType(EObject); //TODO
	};
	
	result.styles+= object EObjectValueStyle{
		name:="semantic_target_end";
		eObjectValue:=association.memberEnd->asSequence()->at(2).oclAsType(EObject); //TODO
	};
	
	//manage connector routing
	routing:=self.oclAsType(GraphElementsType).getConnectorRouting();	
	eAnnotations+=createCSSForceValue("routing");
}

/**
* Create the Actor Shape
*/ 
mapping umlrpy::CGIBasicClass::toSysML11BDDActorShape(cgiClassChart:CGIClassChart, rpyAllowedParent:Sequence(GraphElementsType)):notation::Shape when {self.m_pModelObject.oclIsTypeOf(IActor) and self.m_pParent.oclIsKindOf(GraphElementsType) and rpyAllowedParent->includes(self.m_pParent.oclAsType(GraphElementsType))}{
	element := self.m_pModelObject.resolveone().oclAsType(EObject);
	type:="shape_uml_actor_as_classifier";
	children+= object DecorationNode{
		type:="label_uml_namedelement_name";
	};
	children+=self.map toListCompartment("compartment_uml_property_as_list",null);
	children+=self.map toListCompartment("compartment_uml_operation_as_list",null);
  	layoutConstraint:= object Bounds{ x:=getX(self); y:=getY(self); width :=getRectangleWidth(self); height := getRectangleHeight(self)};
}

/**
* Create the package shape
*
*/
mapping umlrpy::CGIPackage::toSysML11BDDPackageShape(cgiClassChart:CGIClassChart, rpyAllowedParent:Sequence(GraphElementsType)):notation::Shape when {self.m_pModelObject.oclIsTypeOf(ISubsystem) and self.m_pParent.oclIsKindOf(GraphElementsType) and rpyAllowedParent->includes(self.m_pParent.oclAsType(GraphElementsType))}{
	element := self.m_pModelObject.resolveone().oclAsType(EObject);
	type:="Package_Shape";
	children+= object DecorationNode{
		type:="Package_NameLabel";
	};
	var blockPropertyStructure:BasicCompartment:= object BasicCompartment {
		type:="Package_PackagedElementCompartment";
		styles+=object TitleStyle{};
		layoutConstraint:=object Bounds{};
	};
	layoutConstraint:= object Bounds{ x:=getX(self); y:=getY(self); width :=getRectangleWidth(self); height := getRectangleHeight(self)};
	
	//create package contents
	
	blockPropertyStructure.children+=cgiClassChart.graphElements->select(a | a.isAllowedAsCompartmentChildren(blockPropertyStructure)).map toSysML11BlockDefinitionDiagramShape(cgiClassChart, self->asSequence());
	children+=blockPropertyStructure;
}

/**
* Returns true when the graph element can be set as a children of a given compartment
*/
query umlrpy::GraphElementsType::isAllowedAsCompartmentChildren(cpt:BasicCompartment):Boolean{
	return not self.oclIsTypeOf(CGIPortConnector);
}

/**
* Map the CGIGenericElement to a Signal Shape
*/
mapping umlrpy::CGIGenericElement::toSysML11BDDSignalShape(cgiClassChart:CGIClassChart, rpyAllowedParent:Sequence(GraphElementsType)):notation::Shape when{self.m_pModelObject.oclIsTypeOf(IEvent) and self.m_pParent.oclIsKindOf(GraphElementsType) and rpyAllowedParent->includes(self.m_pParent.oclAsType(GraphElementsType))}{
	element := self.m_pModelObject.resolveone().oclAsType(EObject);
	type:="shape_uml_signal_as_classifier";
	children+= object DecorationNode{
		type:="label_uml_namedelement_name";
	};
	children+=self.map toListCompartment("compartment_uml_property_as_list",null);
	children+=self.map toListCompartment("compartment_uml_operation_as_list",null);
	layoutConstraint:= object Bounds{ x:=getX(self); y:=getY(self); width :=getRectangleWidth(self); height := getRectangleHeight(self)};
}