/**
 * Copyright (c) 2009, 2011, 2012 Borland Software Corporation & 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:
 *    Artem Tikhomirov (Borland) - initial API and implementation
 *    Guillaume Hillairet (Montages A.G.)
 */
library Mappings;

import Utils;
import ModelFacets;
import Palette;
import Viewmaps;
import ModeledViewmaps;
import Identity;
import Behaviours;

modeltype GMFMAP uses mappings('http://www.eclipse.org/gmf/2006/mappings');
modeltype GMFTOOL uses tooldef('http://www.eclipse.org/gmf/2005/ToolDefinition');
modeltype GMFGEN uses gmfgen('http://www.eclipse.org/gmf/2009/GenModel');
modeltype GMFGRAPH uses gmfgraph('http://www.eclipse.org/gmf/2006/GraphicalDefinition');
modeltype ECORE uses ecore('http://www.eclipse.org/emf/2002/Ecore');
modeltype GENMODEL uses genmodel('http://www.eclipse.org/emf/2002/GenModel');

--
--	Mapping
--

property genEditorGenerator : GMFGEN::GenEditorGenerator = null;

mapping GMFMAP::Mapping::structure() : GMFGEN::GenEditorGenerator {
	init {
		result := object GMFGEN::GenEditorGenerator {
			diagram := self.diagram.map structure();
		}
	}
	genEditorGenerator := result;
	
	childReferences := self.getChildReferences();
	self.nodes->map structure();
	diagram.links := self.links->map structure();
		
	diagram.getAllNodes()->forEach(n) { setupElementType(n) };
	diagram.links->forEach(l) { setupElementType(l) };
		 
	if self.expressionsByLanguages()->notEmpty() then 
		expressionProviders := self.map createProviderContainer()
	endif;
}

mapping GMFMAP::Mapping::createProviderContainer(): GMFGEN::GenExpressionProviderContainer {
	self.expressionsByLanguages()->forEach(e) {
		providers += e.map createExpressionProvider()
	}
}

mapping GMFMAP::CanvasMapping::structure() : GMFGEN::GenDiagram {
	init {
		result := object GenDiagram {
			viewmap := self.viewmap();
			domainDiagramElement := self.domainMetaElement.findGenClass();
			iconProviderPriority := GMFGEN::ProviderPriority::Low;
			validationProviderPriority := GMFGEN::ProviderPriority::Low;
		}
	}
	
	result.visualID := result.visualID();
	
	if result.domainDiagramElement.oclIsUndefined() then 
		result.elementType := object GMFGEN::NotationType {}
	else
		result.elementType := result.domainDiagramElement.getOrCreateRuntimeMetamodelType()
	endif;
}

-- 
-- TopLevelNode
-- 

mapping GMFMAP::TopNodeReference::structure() : GMFGEN::GenTopLevelNode {
	init {
		result := object GenTopLevelNode {
			modelFacet := self.createModelFacet();
			viewmap := self.viewmap();		
		}
	}
	genEditorGenerator.diagram.topLevelNodes += result;
	result.visualID := result.visualID();
	self.child.tool.map paletteEntry().oclAsType(ToolEntry).genNodes += result;
	
	self.child.map abstractStructure(result);
		
	labels += self.child.labelMappings->map createNodeLabel(self, result);
	behaviour += self.child.relatedDiagrams.handleRelatedDiagram(self.child);
	behaviour += self.child.visualEffects->map createVisualEffects(result, self.child.diagramNode); 
}

--
--
--
mapping GMFMAP::NodeMapping::abstractStructure(inout genNode: GMFGEN::GenNode) {
	var mapOfCompartments : Dict(CompartmentMapping, GenCompartment) = Dict{};
	self.compartments->forEach(c) {
		var childCompartment := object GMFGEN::GenCompartment {
			title := c.compartment.name;
			canCollapse := c.compartment.collapsible;
			needsTitle := c.compartment.needsTitle;
			viewmap := c.viewmap();
		};
		mapOfCompartments->put(c, childCompartment);
		genEditorGenerator.diagram.compartments += childCompartment;
		genNode.compartments += childCompartment;
		childCompartment.node := genNode;
		childCompartment.visualID := childCompartment.visualID();
	};
	
	self.children->forEach(childNodeRef) {
		var compartmentMapping := childNodeRef.compartment;
		var genChildContainer : GenChildContainer = null; 
		if not compartmentMapping.oclIsUndefined() and not mapOfCompartments->get(compartmentMapping).oclIsUndefined() then
			genChildContainer := mapOfCompartments->get(compartmentMapping)
		else
			 genChildContainer := genNode
		endif;
		
		var childNodeMapping := childNodeRef.child;
		var node := childNodeRef.findProcessableChildReference();
		var childNode := node.map structure(childNodeMapping);
		if genChildContainer.oclIsKindOf(GenCompartment) and childNodeMapping.children->size() > 0 then
			genChildContainer.oclAsType(GenCompartment).listLayout := false
		endif;
		genChildContainer.childNodes += childNode;
	};
}

-- 
-- GenChildNode
-- 
abstract mapping GMFMAP::ChildReference::abstractStructure(nodeMapping: GMFMAP::NodeMapping): GMFGEN::GenChildNode {
	modelFacet := self.createModelFacet();
	viewmap := self.viewmap(nodeMapping);

	self.child.tool.map paletteEntry().oclAsType(ToolEntry).genNodes += result;
}

mapping GMFMAP::ChildReference::structure(nodeMapping: GMFMAP::NodeMapping) : GMFGEN::GenChildNode
disjuncts 
	GMFMAP::ChildReference::createGenChildLabelNode, 
	GMFMAP::ChildReference::createGenChildSideAffixedNode, 
	GMFMAP::ChildReference::createGenChildNode 
{}

mapping GMFMAP::ChildReference::createGenChildLabelNode(nodeMapping: GMFMAP::NodeMapping) : GMFGEN::GenChildLabelNode
inherits GMFMAP::ChildReference::abstractStructure 
when { 
	nodeMapping.isPureLabelNode() 
} 
{
	init {
		result := object GMFGEN::GenChildLabelNode {}
	}
	genEditorGenerator.diagram.childNodes += result;
	result.visualID := result.visualID();
	
	var soleLabel := nodeMapping.labelMappings->first();
	labelModelFacet := soleLabel.map createLabelModelFacet(self);
	labelReadOnly := soleLabel.readOnly;
	labelElementIcon := soleLabel.diagramLabel.elementIcon;
}

mapping GMFMAP::ChildReference::createGenChildSideAffixedNode(nodeMapping: GMFMAP::NodeMapping) : GMFGEN::GenChildSideAffixedNode
inherits GMFMAP::ChildReference::abstractStructure 
when { 
	nodeMapping.diagramNode.affixedParentSide <> GMFGRAPH::Direction::NONE
} 
{
	init {
		result := object GMFGEN::GenChildSideAffixedNode {}
	}
	
	genEditorGenerator.diagram.childNodes += result;
	result.visualID := result.visualID();
	self.child.map abstractStructure(result);
	
	preferredSideName := nodeMapping.diagramNode.getAffixedSideAsPositionConstantsName();	
	labels += nodeMapping.labelMappings->map createNodeLabel(self, result);
	behaviour += nodeMapping.relatedDiagrams.handleRelatedDiagram(nodeMapping);
	behaviour +=  nodeMapping.visualEffects->map createVisualEffects(result, nodeMapping.diagramNode);
}

mapping GMFMAP::ChildReference::createGenChildNode(nodeMapping: GMFMAP::NodeMapping) : GMFGEN::GenChildNode 
inherits GMFMAP::ChildReference::abstractStructure
{
	init {
		result := object GMFGEN::GenChildNode {}
	}
	genEditorGenerator.diagram.childNodes += result;
	result.visualID := result.visualID();
	self.child.map abstractStructure(result);
	
	nodeMapping.labelMappings->map createNodeLabel(self, result); 	
	behaviour += nodeMapping.relatedDiagrams.handleRelatedDiagram(nodeMapping);
	behaviour +=  nodeMapping.visualEffects->map createVisualEffects(result, nodeMapping.diagramNode);
}

-- 
-- NodeLabel
-- 

mapping GMFMAP::LabelMapping::createNodeLabel(node: NodeReference, inout genNode: GMFGEN::GenNode) : GMFGEN::GenNodeLabel {
	init {
		if self.diagramLabel.external then
			result := object GenExternalNodeLabel {}
		else 
			result := object GenNodeLabel {}
		endif
	}
	
	result.viewmap := self.viewmap();
	result.modelFacet := self.map createLabelModelFacet(node);
	result.readOnly := self.readOnly;
	result.elementIcon := self.diagramLabel.elementIcon;
	genNode.labels += result;
	result.visualID := result.visualID();
}

--
--	GenLink
--
mapping GMFMAP::LinkMapping::structure() : GMFGEN::GenLink 
when {
	not self.diagramLink.oclIsUndefined() and
	not self.linkMetaFeature.oclIsUndefined()
}{
	init {
		result := object GMFGEN::GenLink {
			-- model facet
			if not (self.domainMetaElement.oclIsUndefined() and self.linkMetaFeature.oclIsUndefined()) then 
				modelFacet := self.map createModelFacet()
			endif;
			
			viewmap := self.viewmap();		
		}
	}
	
	genEditorGenerator.diagram.links += result;
	result.visualID := result.visualID();
	
	-- labels
	self.labelMappings->map structure(self, result);
			
	self.tool.map paletteEntry().oclAsType(ToolEntry).genLinks += result;
	result.creationConstraints := self.creationConstraints.map structure();
	
	behaviour += self.visualEffects->map createVisualEffects(result, self.diagramLink);
}

mapping LabelMapping::structure(link: GMFMAP::LinkMapping, inout genLink: GMFGEN::GenLink): GenLinkLabel {
	init {
		result := object GMFGEN::GenLinkLabel {
			readOnly := self.readOnly;
			elementIcon := self.diagramLabel.elementIcon;
			modelFacet := self.map createLabelModelFacet(link);
			viewmap := self.viewmap();
			
			var alignmentFacet := self.diagramLabel.findAlignmentFacet();
			if not alignmentFacet.oclIsUndefined() then
				alignment := switch  {
					case (alignmentFacet.alignment = GMFGRAPH::Alignment::BEGINNING) LinkLabelAlignment::SOURCE;
					case (alignmentFacet.alignment = GMFGRAPH::Alignment::CENTER) LinkLabelAlignment::MIDDLE;
					case (alignmentFacet.alignment = GMFGRAPH::Alignment::END) LinkLabelAlignment::TARGET;
					else LinkLabelAlignment::MIDDLE;
				}
			endif;
		}
	}
	
	genLink.labels += result;
	result.visualID := result.visualID()
}


-- XXX ElementType as return value, disjunct?
mapping GENMODEL::GenClass::gmfRuntimeMetamodelType() : GMFGEN::MetamodelType {}

--
--	Helpers
--

query GENMODEL::GenClass::getOrCreateRuntimeMetamodelType() : GMFGEN::ElementType {
	var mmt = self.resolveoneIn(GENMODEL::GenClass::gmfRuntimeMetamodelType, GMFGEN::MetamodelType);
	if mmt.oclIsUndefined() then 
		return self.map gmfRuntimeMetamodelType() 
	endif;
	return object GMFGEN::SpecializationType { metamodelType := mmt }
}

-- XXX review - Specialization type is created again and again - why not reuse it?
-- static, for some reasons, helpers couldn't specify 'inout' for context element
-- XXX, actually, don't need GenNode here, GenClass should be sufficient
helper setupElementType(inout genNode : GMFGEN::GenNode) {
	if genNode.modelFacet.oclIsUndefined() then genNode.elementType := object GMFGEN::NotationType {}
	else genNode.elementType := genNode.modelFacet.metaClass.getOrCreateRuntimeMetamodelType() endif;
	return;
}

helper setupElementType(inout genLink : GMFGEN::GenLink) {
	if genLink.modelFacet.oclIsUndefined() then 
		genLink.elementType := object GMFGEN::NotationType {}
	else 
		if genLink.modelFacet.oclIsKindOf(GMFGEN::TypeModelFacet) then
			genLink.elementType := genLink.modelFacet.oclAsType(GMFGEN::TypeModelFacet).metaClass.getOrCreateRuntimeMetamodelType()
		else { -- ref-based link; specialize null
			genLink.elementType := object GMFGEN::SpecializationType {};
		--	genLink.elementType.displayName := genLink.modelFacet.oclAsType(FeatureLinkModelFacet).metaFeature.ecoreFeature.name.firstToUpper();
		} endif
	endif;
	return;
}

helper GMFMAP::CanvasMapping::viewmap(): Viewmap =
	if useModeledViewmaps then
		object ModeledViewmap {
			figureModel := self.diagramCanvas.oclAsType(EObject);
		}
	else
		self.diagramCanvas.map Viewmaps::viewmap()
	endif;

helper GMFMAP::TopNodeReference::viewmap(): Viewmap =
	if useModeledViewmaps then
		self.child.diagramNode.ModeledViewmaps::viewmap()
	else
		self.child.diagramNode.Viewmaps::viewmap()
	endif;

helper GMFMAP::ChildReference::viewmap(_mapping: NodeMapping): Viewmap =
	if useModeledViewmaps then
		self.child.diagramNode.ModeledViewmaps::viewmap()
	else
		self.Viewmaps::viewmap(_mapping)
	endif;

helper GMFMAP::LinkMapping::viewmap(): Viewmap =
	if useModeledViewmaps then
		self.diagramLink.ModeledViewmaps::viewmap()
	else
		self.diagramLink.Viewmaps::viewmap()
	endif;

helper GMFMAP::LabelMapping::viewmap(): Viewmap =
	if useModeledViewmaps then
		self.diagramLabel.ModeledViewmaps::viewmap()
	else
		self.diagramLabel.Viewmaps::viewmap()
	endif;

helper GMFMAP::CompartmentMapping::viewmap(): Viewmap =
	if useModeledViewmaps then
		self.compartment.ModeledViewmaps::viewmap()
	else
		self.compartment.Viewmaps::viewmap()
	endif;

--	
--	Queries
--
	
query GMFMAP::Mapping::expressionsByLanguages(): Sequence(ValueExpression) =
	GMFMAP::ValueExpression.allInstances()->iterate(it; res: Sequence(ValueExpression) = Sequence{} |
		if res->exists(e | e.language = it.language) then res else res->including(it) endif
	);

query GMFGRAPH::Node::getAffixedSideAsPositionConstantsName() : String =
	switch {
		case (self.affixedParentSide = GMFGRAPH::Direction::NONE) assert (false) with log('DiagramNode is not side-affixed', self);
		case (self.affixedParentSide = GMFGRAPH::Direction::EAST) return 'EAST';
		case (self.affixedParentSide = GMFGRAPH::Direction::WEST) return 'WEST';
		case (self.affixedParentSide = GMFGRAPH::Direction::NORTH) return 'NORTH';
		case (self.affixedParentSide = GMFGRAPH::Direction::SOUTH) return 'SOUTH';
		case (self.affixedParentSide = GMFGRAPH::Direction::NSEW) return 'NONE'; -- any side
		else return 'NONE'; -- any side
	};

query DiagramElement::findAlignmentFacet(): AlignmentFacet =
	self.facets->selectOne(e | e.oclIsKindOf(AlignmentFacet)).oclAsType(AlignmentFacet);
