/*
 * Copyright (c) 2008, 2009 Borland Software Corp.
 * 
 * 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/2008/Widget'»

«EXTENSION Widgets»

// TODO pass only those widgets that would be accessed from outside
// (i.e. listeners/enablement code) to minimize number of class fields
«DEFINE Fields FOR Sequence(widget::Widget)-»
«FOREACH allWidgets(self) AS w-»
	private «EXPAND className FOR w» «fieldName(w)»;
«ENDFOREACH»«REM»XXX think of an alternative Button myR1, myR2, myR3 to save some line count«ENDREM»
«ENDDEFINE»

«DEFINE className FOR widget::Widget»«ERROR 'Abstract className FOR Widget'»«ENDDEFINE»
«DEFINE className FOR widget::TextEntry»Text«ENDDEFINE»
«DEFINE className FOR widget::CheckBox»Button«ENDDEFINE»
«DEFINE className FOR widget::RadioButton»Button«ENDDEFINE»
«DEFINE className FOR widget::Spin»Spinner«ENDDEFINE»
«DEFINE className FOR widget::Composite»Composite«ENDDEFINE»
«DEFINE className FOR widget::Group»Group«ENDDEFINE»
«DEFINE className FOR widget::Combo»Combo«ENDDEFINE»

«DEFINE Main(compositeVar : String, formToolkit : String/*var or accessor*/) FOR Sequence(widget::Widget)-»
«EXPAND Visuals(compositeVar, formToolkit) FOREACH self-»
«ENDDEFINE»

«DEFINE ExtraMethods(extendedToolkit : Boolean, formToolkitAccess : String) FOR Sequence(widget::Widget)-»
«IF createsAnyLabel(self)»
	private org.eclipse.swt.widgets.Label createLabel(org.eclipse.swt.widgets.Composite parent, String label) {
		org.eclipse.swt.widgets.Label l = new org.eclipse.swt.widgets.Label(parent, SWT.NONE);
		if (label != null) l.setText(label);
        «formToolkitAccess».adapt(l, false, false); 
		return l;
	}
«ENDIF-»
«IF not allWidgets(self)[widget::Group]->isEmpty() /* the only reason to have that method even with extended toolkit is null check for label*/»
	private org.eclipse.swt.widgets.Group createGroup(org.eclipse.swt.widgets.Composite parent, String label) {
        org.eclipse.swt.widgets.Group g = new org.eclipse.swt.widgets.Group(parent, SWT.SHADOW_NONE);
        if (label != null) g.setText(label);
        «formToolkitAccess».adapt(g, false, false);
        «formToolkitAccess».paintBordersFor(g); 
		return g;
	}
«ENDIF-»
«ENDDEFINE»

/////////////////////////////////////////////////////////////////////////////////
// Create UI elements

// @param compositeVar, formToolkit - never null
«DEFINE Visuals(compositeVar : String, formToolkit : String) FOR widget::Widget»«ERROR 'abstract Visuals'»«ENDDEFINE»

«DEFINE Visuals(compositeVar : String, formToolkit : String) FOR widget::TextEntry-»
«IF label <> null-»
	createLabel(«compositeVar», "«label»");
«ENDIF-»
	«fieldName(self)» = «formToolkit».createText(«compositeVar», null);
«ENDDEFINE»

«DEFINE Visuals(compositeVar : String, formToolkit : String) FOR widget::RadioButton-»
	«fieldName(self)» = «formToolkit».createButton(«compositeVar», «EXPAND nullOrString(label)», SWT.RADIO);
«ENDDEFINE»

«DEFINE Visuals(compositeVar : String, formToolkit : String) FOR widget::CheckBox-»
	«fieldName(self)» = «formToolkit».createButton(«compositeVar», «EXPAND nullOrString(label)», SWT.CHECK);
«ENDDEFINE»

«DEFINE Visuals(compositeVar : String, formToolkit : String) FOR widget::Spin-»
«IF label <> null-»
	createLabel(«compositeVar», "«label»");
«ENDIF-»
	«fieldName(self)» = new Spinner(«compositeVar», SWT.FLAT);
	«fieldName(self)».setMinimum(«minimum»);
	«fieldName(self)».setMaximum(«maximum»);
	«fieldName(self)».setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER); // @see #145837
«ENDDEFINE»

«DEFINE Visuals(compositeVar : String, formToolkit : String) FOR widget::Composite-»
	«fieldName(self)» = «formToolkit».createComposite(«compositeVar»);
	«formToolkit».paintBordersFor(«fieldName(self)»);
	«EXPAND Visuals(fieldName(self), formToolkit) FOREACH children-»
	«IF layout <> null»«EXPAND Layout::Main(fieldName(self)) FOR layout»«ENDIF-»
«ENDDEFINE»

«DEFINE Visuals(compositeVar : String, formToolkit : String) FOR widget::Group-»
	«fieldName(self)» = createGroup(«compositeVar», «EXPAND nullOrString(label)»);
	«EXPAND Visuals(fieldName(self), formToolkit) FOREACH children-»
	«IF layout <> null»«EXPAND Layout::Main(fieldName(self)) FOR layout»«ENDIF-»
«ENDDEFINE»

«DEFINE Visuals(compositeVar : String, formToolkit : String) FOR widget::Combo-»
«IF label <> null-»
	createLabel(«compositeVar», "«label»");
«ENDIF-»
	«fieldName(self)» = new Combo(«compositeVar», SWT.FLAT | SWT.READ_ONLY);
	«fieldName(self)».setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TEXT_BORDER);
    «formToolkit».adapt(«fieldName(self)», false, false); 
«ENDDEFINE»

«DEFINE nullOrString(label : String) FOR OclAny»«IF label <> null»"«label»"«ELSE»null«ENDIF»«ENDDEFINE»