/*
 * 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/Binding'»

«EXTENSION Forms»
«EXTENSION Widgets»

«DEFINE Main FOR binding::Section-»
package org.eclipse.gmf.dsl.internal.project.ui.editor.pages.deploy;
«EXPAND imports»
«EXPAND _class('public ')»
«ENDDEFINE»

«DEFINE imports FOR binding::Section-»
import org.eclipse.gmf.dsl.internal.ui.emf.AttachAdapter;
import org.eclipse.gmf.dsl.internal.ui.emf.ChangeTracker;
import org.eclipse.gmf.dsl.internal.ui.emf.FeatureTracker;
import org.eclipse.gmf.dsl.internal.project.ui.editor.CommitOperation;
import org.eclipse.gmf.dsl.internal.project.ui.editor.sections.GridToolkit;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.*;
import org.eclipse.ui.forms.*;
import org.eclipse.ui.forms.widgets.*;
«ENDDEFINE»

«DEFINE _class(classModifiers : String) FOR binding::Section-»
«classModifiers»class «className» extends SectionPart implements ChangeTracker, Listener { 

	«EXPAND Update::AdaptersField-»

	private boolean myIsCommit;
	private boolean myIsRefresh;
	private Object myInput;

«EXPAND Visual::Fields FOR children->asSequence()»

	public «className»(Composite parent, IManagedForm form) {
		super(parent, form.getToolkit(), Section.TITLE_BAR | Section.TWISTIE | Section.DESCRIPTION);
	}

	@Override
	public void initialize(IManagedForm form) {
		super.initialize(form);
		Composite c = form.getToolkit().createComposite(getSection());
		form.getToolkit().paintBordersFor(c);
		org.eclipse.jface.layout.GridLayoutFactory.fillDefaults().applyTo(getSection());
		org.eclipse.jface.layout.GridDataFactory.fillDefaults().grab( true, true ).applyTo(c);
		createContents(c);
		getSection().setClient(c);
	}

	protected void createContents(Composite parent) {
		getSection().setText("Generated Section");
		final FormToolkit ftk = getManagedForm().getToolkit();
«EXPAND Visual::Main('parent', 'ftk') FOR children->asSequence()»
«IF layout <> null»«EXPAND Layout::Main('parent') FOR layout»«ENDIF-»
«EXPAND Update::PopulateWidgets-»
		// getEditor().getGlobalActionSupport().register(«FOREACH self.textWidgets() AS te SEPARATOR ', '»«fieldName(te)»«ENDFOREACH»);
«EXPAND Update::registerListeners-»
	}

	@Override
	public void commit(boolean onSave) {
		try {
			myIsCommit = true;
			«EXPAND Update::Commit»
		} finally {
			super.commit(onSave);
			myIsCommit = false;
		}
	}

	@Override
	public void refresh() {
		myIsRefresh = true;
		«EXPAND Update::Refresh»
		myIsRefresh = false;
	}

	@Override
	public void dispose() {
		if (myInput != null) {
			detach();
		}
	}

	public void modelChanged(Notification msg) {
		if (!myIsCommit && Display.getCurrent() != null) {
			refresh();
		}
	}

	@Override
	public boolean setFormInput(Object input) {
		// super.setFormInput(input); // Do I really need that? 
		if (myInput != null) {
			detach();
		}
		myInput = input;
		if (input != null) {
			attach();
		}
		return false;
	}

	public void handleEvent(Event event) {
		if (myIsRefresh) {
			return;
		}
«EXPAND Update::handleEventMethodBody-»
	}

	private void attach() {
	«EXPAND Update::AttachAdapters-»
	}

	private void detach() {
	«EXPAND Update::DetachAdapters-»
	}

	protected void applyChanges() {
		new CommitOperation(this, TransactionalEditingDomain.Factory.INSTANCE.getEditingDomain(getInput().eResource().getResourceSet())).go();
	}

	protected void discardChanges() {
		refresh();
	}

	private «deduceInputType(self).name» getInput() {
		// TODO implement;
		// XXX or move cast to setInput?
		return («deduceInputType(self).name») myInput;
	}
«EXPAND Visual::ExtraMethods(false, 'getManagedForm().getToolkit()') FOR children->asSequence()-»
}
«ENDDEFINE»
