/**
 * 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 Palette;

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

-- 
-- Palette
-- 

mapping GMFMAP::CanvasMapping::palette() : GMFGEN::Palette
{
	var paletteItems := self.palette.tools.map paletteEntry();
	var topLevelTools := paletteItems->reject(e | e.oclIsKindOf(GMFGEN::ToolGroup));
	
	if topLevelTools->notEmpty() then {
		var defaultGroup := object GMFGEN::ToolGroup {
			title := 'Default';
			description := 'Holds top-level non-container tools';
			collapse := false;
			entries += topLevelTools;
		};
		result.groups := result.groups->prepend(defaultGroup);
	} endif;
	
	result.groups += paletteItems[GMFGEN::ToolGroup];
	result.flyout := true;
	
	if (self.palette._default <> null) then {
		var te := self.palette._default.resolveone(GMFGEN::ToolEntry);
		if te <> null then te._default := true else log ('There\'s default tool specified for palette, but can\'t find gmfgen counterpart') endif;
	} endif;
}

mapping GMFTOOL::AbstractTool::paletteEntry() : GMFGEN::ToolGroupItem {
	init {
		assert (false) with log('Can\'t dispatch paletteEntry() for ', self);
	}
}

mapping GMFTOOL::PaletteSeparator::paletteEntry() : GMFGEN::ToolGroupItem {
	init {
		result := object GMFGEN::Separator {};
	}
}

mapping GMFTOOL::CreationTool::paletteEntry() : GMFGEN::ToolGroupItem {
	init {
		var r := object GMFGEN::ToolEntry {};
		setupCommonToolEntry(self, r);
		result := r;
	}
}

mapping GMFTOOL::GenericTool::paletteEntry() : GMFGEN::ToolGroupItem 
when {
	not self.toolClass.oclIsUndefined() or self.toolClass->notEmpty()
}
{
	init {
		var r := object GMFGEN::ToolEntry {};
		r.qualifiedToolName := self.toolClass;
		setupCommonToolEntry(self, r);
		result := r;
	}
}

mapping GMFTOOL::StandardTool::paletteEntry() : GMFGEN::ToolGroupItem {
	init {
		var r := object GMFGEN::StandardEntry {};
		switch {
			case (self.toolKind = StandardToolKind::SELECT) r.kind := StandardEntryKind::SELECT;  
			case (self.toolKind = StandardToolKind::MARQUEE) r.kind := StandardEntryKind::MARQUEE;			
			case (self.toolKind = StandardToolKind::ZOOM_PAN) r.kind := StandardEntryKind::ZOOM;			
		};
		setupCommonToolEntry(self, r);
		result := r;
	}
}

mapping GMFTOOL::ToolGroup::paletteEntry() : GMFGEN::ToolGroupItem {
	init {
		var r := object GMFGEN::ToolGroup {};
		r.stack := self.stack;
		r.collapse := self.collapsible;
		setupCommonToolEntry(self, r);
		r.entries += self.tools.map paletteEntry();
		result := r;
	}
}

-- XXX or helper GMFGEN::EntryBase::setupCommonToolEntry()?
helper setupCommonToolEntry(in tool : GMFTOOL::AbstractTool, inout genTool : GMFGEN::EntryBase) {
	genTool.title := tool.title;
	genTool.description := tool.description;
	
	if tool.largeIcon.oclIsTypeOf(GMFTOOL::BundleImage) then 
		genTool.largeIconPath := tool.largeIcon.oclAsType(GMFTOOL::BundleImage).constructIconPath() 
	endif;
	
	if tool.smallIcon.oclIsTypeOf(GMFTOOL::BundleImage) then 
		genTool.smallIconPath := tool.smallIcon.oclAsType(GMFTOOL::BundleImage).constructIconPath()
	endif;
}

-- FIXME process path (makeRelative/makeAbsolute) as in original java code
query GMFTOOL::BundleImage::constructIconPath() : String =
	if self.path.oclIsUndefined() or self.path.trim().size() = 0 then null else
		if self.bundle.oclIsUndefined() or self.bundle.trim().size() = 0 then 
			self.path.makeRelative() 
		else 
			self.bundle.makeAbsolute() + self.path
		endif
	endif;

-- FIXME
query String::makeRelative(): String = self;

query String::makeAbsolute(): String =
	if self.startsWith('/') or self->exists(e | e = ':') then self + '/' else '/' + self + '/' endif;
