package xpt.plugin

import com.google.inject.Inject
import org.eclipse.gmf.codegen.gmfgen.GenDiagram
import org.eclipse.gmf.codegen.gmfgen.GenEditorGenerator
import org.eclipse.gmf.codegen.gmfgen.GenExpressionInterpreter
import org.eclipse.gmf.codegen.gmfgen.GenPlugin
import plugin.Activator
import xpt.Common
import xpt.editor.DocumentProvider
import xpt.expressions.OCLExpressionFactory
import xpt.expressions.getExpression
import xpt.providers.ElementInitializers

@com.google.inject.Singleton class ActivatorImpl {
	@Inject extension Common;
	
	@Inject Activator xptActivator;
	@Inject DocumentProvider xptDocProvider;
	@Inject ElementInitializers xptElementInitializers;
	@Inject getExpression xptExpr;
	@Inject OCLExpressionFactory oclFactory;
	
	def ActivatorImpl(GenPlugin it)'''
		«copyright(editorGen)»
		package «xptActivator.packageName(it)»;

		«generatedClassComment»
		public class «xptActivator.className(it)» extends org.eclipse.ui.plugin.AbstractUIPlugin {

		«attrs»
		«constructor»
		«start»
		«stop(editorGen)»
		«getInstance»
		«createAdapterFactory(editorGen.diagram)»
		«fillItemProviderFactories(editorGen)»
		«getItemProvidersAdaptorFactory»
		«getItemImageDescriptor»
		«getBundleDescriptorImage»
		«findImageDescriptor»
		«getBundleImage»
		«getString»
		«documentProviderGetter(editorGen.diagram)»
		«linkConstraint(editorGen.diagram)»
		«initializerGetter(editorGen.diagram)»
		«initializerSetter(editorGen.diagram)»
		«providersAccessMethods»
		«logError(it)»
		«logInfo»
		«getLogError(it)»
		«additions»
	}
'''

def attrs(GenPlugin it)'''
	«generatedMemberComment»
	public static final String ID = "«ID»"; //$NON-NLS-1$

	«generatedMemberComment»
	private org.eclipse.gmf.tooling.runtime.LogHelper myLogHelper;

	«generatedMemberComment»
	public static final org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint DIAGRAM_PREFERENCES_HINT =
			new org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint(ID);

	«generatedMemberComment»
	private static «xptActivator.className(it)» instance;

	«generatedMemberComment»
	private org.eclipse.emf.edit.provider.ComposedAdapterFactory adapterFactory;	

	«generatedMemberComment»
	private «xptDocProvider.qualifiedClassName(editorGen.diagram)» documentProvider;

	«IF editorGen.diagram.links.exists(l| !l.sansDomain)»
		«generatedMemberComment»
		private «editorGen.diagram.getLinkCreationConstraintsQualifiedClassName()» linkConstraints;
	«ENDIF»

	«generatedMemberComment»
	private «xptElementInitializers.qualifiedClassName(editorGen.diagram)» initializers;

	«IF it.editorGen.expressionProviders != null»
		«FOR p : it.editorGen.expressionProviders.providers.filter(typeof(GenExpressionInterpreter))»
			«generatedMemberComment»
			private «xptExpr.getExpressionInterpriterQualifiedClassName(p)» «p.language»Factory;
		«ENDFOR»
	«ENDIF»
'''

def constructor(GenPlugin it)'''
	«generatedMemberComment»
	public «xptActivator.className(it)»() {
	}
'''

def start(GenPlugin it)'''
	«generatedMemberComment»
	public void start(org.osgi.framework.BundleContext context) throws Exception {
		super.start(context);
		instance = this;
		myLogHelper = new org.eclipse.gmf.tooling.runtime.LogHelper(this);
		org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint.registerPreferenceStore(DIAGRAM_PREFERENCES_HINT, getPreferenceStore());
		adapterFactory = createAdapterFactory();
	}
'''

def stop(GenEditorGenerator it)'''
	«generatedMemberComment»
	public void stop(org.osgi.framework.BundleContext context) throws Exception {
		adapterFactory.dispose();
		adapterFactory = null;
		«IF diagram.links.exists(l| !l.sansDomain)»
			linkConstraints = null;
		«ENDIF»
		initializers = null;
		«IF expressionProviders != null»
			«FOR p : expressionProviders.providers.filter(typeof(GenExpressionInterpreter))»
				«p.language»Factory = null;
			«ENDFOR»
		«ENDIF»
		instance = null;
		super.stop(context);
	}
'''

def getInstance(GenPlugin it)'''
	«generatedMemberComment»
	public static «xptActivator.className(it)» getInstance() {
		return instance;
	}
'''

def createAdapterFactory(GenDiagram it)'''
	«generatedMemberComment»
	protected org.eclipse.emf.edit.provider.ComposedAdapterFactory createAdapterFactory() {
		java.util.ArrayList<org.eclipse.emf.common.notify.AdapterFactory> factories = new java.util.ArrayList<org.eclipse.emf.common.notify.AdapterFactory>();
		fillItemProviderFactories(factories);
		return new org.eclipse.emf.edit.provider.ComposedAdapterFactory(factories);
	}
'''

def fillItemProviderFactories(GenEditorGenerator it)'''
	«generatedMemberComment»
	protected void fillItemProviderFactories(java.util.List<org.eclipse.emf.common.notify.AdapterFactory> factories) {
		«populateItemProviderFactories('factories', it)»
		factories.add(new org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory());
		factories.add(new org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory());
	}
'''

	def populateItemProviderFactories(String factoryListVar, GenEditorGenerator it)'''
		«FOR genPackage : it.getAllDomainGenPackages(true)»
			«factoryListVar».add(new «genPackage.qualifiedItemProviderAdapterFactoryClassName»());
		«ENDFOR»
	'''

def getItemProvidersAdaptorFactory(GenPlugin it)'''
	«generatedMemberComment»
	public org.eclipse.emf.common.notify.AdapterFactory getItemProvidersAdapterFactory() {
		return adapterFactory;
	}
'''

def getItemImageDescriptor(GenPlugin it)'''
	«generatedMemberComment»
	public org.eclipse.jface.resource.ImageDescriptor getItemImageDescriptor(Object item) {
		org.eclipse.emf.edit.provider.IItemLabelProvider labelProvider =
				(org.eclipse.emf.edit.provider.IItemLabelProvider) adapterFactory.adapt(
						item, org.eclipse.emf.edit.provider.IItemLabelProvider.class);
		if (labelProvider != null) {
			return org.eclipse.emf.edit.ui.provider.ExtendedImageRegistry.getInstance().getImageDescriptor(
					labelProvider.getImage(item));
		}
		return null;
	}
'''

def getBundleDescriptorImage(GenPlugin it)'''
	«generatedMemberComment(
	  'Returns an image descriptor for the image file at the given\n'
	+ 'plug-in relative path.\n',
	  '@param path the path\n'
	+ '@return the image descriptor')»
	public static org.eclipse.jface.resource.ImageDescriptor getBundledImageDescriptor(String path) {
		return org.eclipse.ui.plugin.AbstractUIPlugin.imageDescriptorFromPlugin(ID, path);
	}
'''

def findImageDescriptor(GenPlugin it)'''
	«generatedMemberComment(
	  'Respects images residing in any plug-in. If path is relative,\n'
	+ 'then this bundle is looked up for the image, otherwise, for absolute\n'
	+ 'path, first segment is taken as id of plug-in with image\n',
	  '@param path the path to image, either absolute (with plug-in id as first segment), or relative for bundled images\n'
	+ '@return the image descriptor')»
	public static org.eclipse.jface.resource.ImageDescriptor findImageDescriptor(String path) {
		final org.eclipse.core.runtime.IPath p = new org.eclipse.core.runtime.Path(path);
		if (p.isAbsolute() && p.segmentCount() > 1) {
			return org.eclipse.ui.plugin.AbstractUIPlugin.imageDescriptorFromPlugin(
					p.segment(0), p.removeFirstSegments(1).makeAbsolute().toString());
		} else {
			return getBundledImageDescriptor(p.makeAbsolute().toString());
		} 
	}
	
'''

def getBundleImage(GenPlugin it)'''
	«generatedMemberComment(
	  'Returns an image for the image file at the given plugin relative path.\n'
	+ 'Client do not need to dispose this image. Images will be disposed automatically.\n',
	  '@param path the path\n'
	+ '@return image instance')»
	public org.eclipse.swt.graphics.Image getBundledImage(String path) {
		org.eclipse.swt.graphics.Image image = getImageRegistry().get(path);
		if (image == null) {
			getImageRegistry().put(path, getBundledImageDescriptor(path));
			image = getImageRegistry().get(path);
		}
		return image;
	}
'''

def getString(GenPlugin it)'''
	«generatedMemberComment('Returns string from plug-in\'s resource bundle\n')»
	public static String getString(String key) {
		return org.eclipse.core.runtime.Platform.getResourceString(
				getInstance().getBundle(), "%" + key); «nonNLS»
	}
'''

def documentProviderGetter(GenDiagram it)'''
	«generatedMemberComment»
	public «xptDocProvider.qualifiedClassName(it)» getDocumentProvider() {
		if (documentProvider == null) {
			documentProvider = new «xptDocProvider.qualifiedClassName(it)»();
		}
		return documentProvider;
	}
'''

def linkConstraint(GenDiagram it)'''
	«IF links.exists(l| !l.sansDomain) »
		«linkConstraintsGetter(it)»
		
		«linkConstraintsSetter(it)»
	«ENDIF»
'''

def linkConstraintsGetter(GenDiagram it)'''
	«generatedMemberComment»
	public «getLinkCreationConstraintsQualifiedClassName()» getLinkConstraints() {
		return linkConstraints;
	}
'''

def linkConstraintsSetter(GenDiagram it)'''
	«generatedMemberComment»
	public void setLinkConstraints(«getLinkCreationConstraintsQualifiedClassName()» lc) {
		this.linkConstraints = lc;
	}
'''

def initializerGetter(GenDiagram it)'''
	«generatedMemberComment»
	public «xptElementInitializers.qualifiedClassName(it)» getElementInitializers() {
		return initializers;
	}
'''

def initializerSetter(GenDiagram it)'''
	«generatedMemberComment»
	public void setElementInitializers(«xptElementInitializers.qualifiedClassName(it)» i) {
		this.initializers = i;
	}
'''

def providersAccessMethods(GenPlugin it)'''
	«IF it.editorGen.expressionProviders != null»
		«FOR p : it.editorGen.expressionProviders.providers.filter(typeof(GenExpressionInterpreter))»
			«providerGetter(p)»
	
			«providerSetter(p)»
		«ENDFOR»
	«ENDIF»
'''

def providerGetter(GenExpressionInterpreter it)'''
	«generatedMemberComment»
	public «oclFactory.qualifiedClassName(it)» get«oclFactory.className(it)»() {
		return «language»Factory;
	}
'''

def providerSetter(GenExpressionInterpreter it)'''
	«generatedMemberComment»
	public void set«oclFactory.className(it)»(«oclFactory.qualifiedClassName(it)» f) {
		this.«language»Factory = f;
	}
'''

def logError(GenPlugin it)'''
	«generatedMemberComment»
	public void logError(String error) {
		getLogHelper().logError(error, null);
	}
	
	«generatedMemberComment»
	public void logError(String error, Throwable throwable) {
		getLogHelper().logError(error, throwable);
	}
'''

def logInfo(GenPlugin it)'''
	«generatedMemberComment»
	public void logInfo(String message) {
		getLogHelper().logInfo(message, null);
	}

	«generatedMemberComment»
	public void logInfo(String message, Throwable throwable) {
		getLogHelper().logInfo(message, throwable);
	}
'''

def getLogError(GenPlugin it) '''
	«generatedMemberComment»
	public org.eclipse.gmf.tooling.runtime.LogHelper getLogHelper() {
		return myLogHelper;
	}
'''

// Perhaps, xpt:editor::Editor or some xpt::CommonCode would be better place for
// this accessor.
// XXX besides, consider using preference store directly, without a hint (see comment in Editor.xpt#getPreferencesHint)
def preferenceHintAccess(GenEditorGenerator it)'''«xptActivator.qualifiedClassName(plugin)».DIAGRAM_PREFERENCES_HINT'''

def additions(GenPlugin it)''''''
}