﻿/*
 * Copyright (c) 2006, 2010 Borland Software Corporation 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:
 *    Artem Tikhomirov (Borland) - initial API and implementation
 */

«IMPORT 'http://www.eclipse.org/gmf/2006/GraphicalDefinition'»

«EXTENSION Util»

«DEFINE ClassBody(cuName : String) FOR gmfgraph::Figure»«ERROR 'abstract ClassBody(Figure)'»«ENDDEFINE»

«DEFINE ClassBody(cuName : String) FOR gmfgraph::FigureRef-»
«EXPAND ClassBody(cuName, self) FOR figure-»
«ENDDEFINE»

«DEFINE ClassBody(cuName : String) FOR gmfgraph::RealFigure-»
«EXPAND ClassBody(cuName, null) FOR self-»
«ENDDEFINE»

«DEFINE ClassBody(cuName : String, figureRef : gmfgraph::FigureRef) FOR gmfgraph::RealFigure-»
	/**
	 * @generated
	 */
	public «cuName»() {
«clearBorders()-»
		«EXPAND Layout::Init('this') FOR layout-»
		«EXPAND Attrs::Init('this')-»
«IF not figureRef->isEmpty()-»
		// «figureRef.figure.name» 
		// Process FigureRef details
		«EXPAND Layout::Init('this') FOR figureRef.layout-»
		«EXPAND Attrs::Init('this') FOR figureRef-»
«ENDIF-»		
«IF not (children)[gmfgraph::Figure]->isEmpty()-»
		createContents();
	}
«EXPAND Children::CreateChildren-»
«EXPAND Border::InitMethods»
«ELSE-»
	}
«ENDIF-»
«EXPAND Extras::extraMethods»
«EXPAND additions-»
«ENDDEFINE»

«DEFINE ClassBody(cuName : String, figureRef : gmfgraph::FigureRef) FOR gmfgraph::PolylineConnection-»
	/**
	 * @generated
	 */
	public «cuName»() {
		«EXPAND Attrs::Init('this')»
«IF not (children)[gmfgraph::Label]->isEmpty()-»
		createContents();
«ENDIF-»
«IF hasSourceDecoration(self)-»
		setSourceDecoration(createSourceDecoration());
«ENDIF-»
«IF hasTargetDecoration(self)-»
		setTargetDecoration(createTargetDecoration());
«ENDIF-»
	}
«IF not (children)[gmfgraph::Label]->isEmpty()»
«REM»
	Copy of Children::CreateChildren with temp workaround to generate child figures for labels only.
	Though this is temp workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=193180, I'm not sure
	what's the right approach with e.g. decoration as child of a link.
«ENDREM»
	/**
	 * @generated
	 */
	private void createContents(){
«EXPAND Children::instantiate(0, self, 'this') FOREACH (children)[gmfgraph::Label]»
	}
«ENDIF-»
«IF hasSourceDecoration(self)»
	/**
	 * @generated
	 */
	private org.eclipse.draw2d.RotatableDecoration createSourceDecoration() {
		«EXPAND Decoration::Instantiate('df') FOR sourceDecoration-»
		return df;
	}
«ENDIF-»
«IF hasTargetDecoration(self)»
	/**
	 * @generated
	 */
	private org.eclipse.draw2d.RotatableDecoration createTargetDecoration() {
		«EXPAND Decoration::Instantiate('df') FOR targetDecoration-»
		return df;
	}
«ENDIF-»
«EXPAND additions-»
«ENDDEFINE»

«REM»Our regular way to add smth inside generated class body«ENDREM»
«DEFINE additions FOR gmfgraph::Figure»«ENDDEFINE»