/**
 *                                                                            
 * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 *                                                                            
 * All rights reserved. This program and the accompanying materials           
 * are made available under the terms of the Eclipse Public License 2.0        
 * which accompanies this distribution, and is available at                  
 * https://www.eclipse.org/legal/epl-2.0/                                 
 *                                 
 * SPDX-License-Identifier: EPL-2.0                                 
 *                                                                            
 * Contributors:   
 * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation 
 * 
 * 
 *  This copyright notice shows up in the generated Java code
 *
 */
 
package org.eclipse.osbp.xtext.reportdsl.ui.contentassist

import com.google.inject.Inject
import org.eclipse.emf.ecore.EObject
import org.eclipse.jface.text.contentassist.ICompletionProposal
import org.eclipse.jface.viewers.StyledString
import org.eclipse.osbp.preferences.ProductConfiguration
import org.eclipse.osbp.xtext.basic.ui.contentassist.BasicDSLProposalProviderHelper
import org.eclipse.osbp.xtext.datamartdsl.DatamartEntity
import org.eclipse.osbp.xtext.reportdsl.AutoText
import org.eclipse.osbp.xtext.reportdsl.BinaryAggregationTypeEnum
import org.eclipse.osbp.xtext.reportdsl.Color
import org.eclipse.osbp.xtext.reportdsl.DatamartTable
import org.eclipse.osbp.xtext.reportdsl.DatamartTableAttribute
import org.eclipse.osbp.xtext.reportdsl.DatamartTableDetail
import org.eclipse.osbp.xtext.reportdsl.DatamartTableFooter
import org.eclipse.osbp.xtext.reportdsl.DatamartTableGroup
import org.eclipse.osbp.xtext.reportdsl.DatamartTableHeader
import org.eclipse.osbp.xtext.reportdsl.Image
import org.eclipse.osbp.xtext.reportdsl.MultipleAggregationTypeEnum
import org.eclipse.osbp.xtext.reportdsl.PageDetail
import org.eclipse.osbp.xtext.reportdsl.PageTemplate
import org.eclipse.osbp.xtext.reportdsl.StringBinder
import org.eclipse.osbp.xtext.reportdsl.SubSubTitle
import org.eclipse.osbp.xtext.reportdsl.SubTitle
import org.eclipse.osbp.xtext.reportdsl.TableAggregation
import org.eclipse.osbp.xtext.reportdsl.TableAttribute
import org.eclipse.osbp.xtext.reportdsl.TableBinaryAggregation
import org.eclipse.osbp.xtext.reportdsl.TableMultipleAggregation
import org.eclipse.osbp.xtext.reportdsl.TableUnaryAggregation
import org.eclipse.osbp.xtext.reportdsl.Text
import org.eclipse.osbp.xtext.reportdsl.Title
import org.eclipse.osbp.xtext.reportdsl.UnaryAggregationTypeEnum
import org.eclipse.osbp.xtext.reportdsl.common.ColorUtilities
import org.eclipse.osbp.xtext.reportdsl.ui.ReportDSLUiDocumentationTranslator
import org.eclipse.swt.graphics.RGB
import org.eclipse.swt.layout.FillLayout
import org.eclipse.swt.widgets.ColorDialog
import org.eclipse.swt.widgets.FileDialog
import org.eclipse.swt.widgets.Shell
import org.eclipse.xtext.Assignment
import org.eclipse.xtext.EnumLiteralDeclaration
import org.eclipse.xtext.Keyword
import org.eclipse.xtext.ParserRule
import org.eclipse.xtext.RuleCall
import org.eclipse.xtext.common.ui.contentassist.TerminalsProposalProvider
import org.eclipse.xtext.ui.editor.contentassist.ConfigurableCompletionProposal
import org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext
import org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor
import org.eclipse.xtext.ui.editor.contentassist.ReplacementTextApplier
import org.eclipse.osbp.xtext.reportdsl.Grid
import org.eclipse.osbp.fork.mihalis.opal.widgets.ImageSelectorDialog

class IconNameTextApplier extends ReplacementTextApplier {
	var ContentAssistContext context
	var String[] extensions

	def setContext(ContentAssistContext context) {
		this.context = context
	}

	def setExtensions(String[] fileExtensions) {
		extensions = fileExtensions
	}

	// this will inject a file dialog when selecting the file picker proposal 
	override getActualReplacementString(ConfigurableCompletionProposal proposal) {
		var display = context.getViewer().getTextWidget().getDisplay();
		var shell = new Shell(display);
		shell.setLayout(new FillLayout());
		var imageSelectorDialog = new ImageSelectorDialog(shell, 16);
		imageSelectorDialog.setFilterExtensions(extensions)
		var imageFileName = imageSelectorDialog.open(true);
		return "\"".concat(imageFileName).concat("\"");
	}

}

class ColorTextApplier extends ReplacementTextApplier {
	var ContentAssistContext context

	def setContext(ContentAssistContext context) {
		this.context = context
	}

	// this will inject a file dialog when selecting the file picker proposal 
	override getActualReplacementString(ConfigurableCompletionProposal proposal) {
		var display = context.getViewer().getTextWidget().getDisplay();
		var shell = new Shell(display);
		shell.setLayout(new FillLayout());
		var colorDialog = new ColorDialog(shell);
		if ((context.currentModel as Color).color instanceof String) {
			try {
				var awtColor = ColorUtilities.convertToAwtColor(context.currentModel as Color);
				colorDialog.setRGB(new RGB(awtColor.red, awtColor.green, awtColor.blue));
			} finally {
			}
		}
		var newColor = colorDialog.open();
		if (newColor !== null) {
			return String.format("\"#%02x%02x%02x\"", newColor.red, newColor.green, newColor.blue);
		}
	}
}

class FileNameTextApplier extends ReplacementTextApplier {
	var ContentAssistContext context
	var String[] extensions

	def setContext(ContentAssistContext context) {
		this.context = context
	}

	def setExtensions(String[] fileExtensions) {
		extensions = fileExtensions
	}

	// this will inject a file dialog when selecting the file picker proposal 
	override getActualReplacementString(ConfigurableCompletionProposal proposal) {
		var display = context.getViewer().getTextWidget().getDisplay();
		var fileDialog = new FileDialog(display.getActiveShell());
		fileDialog.setFilterExtensions(extensions)
		var fileName = fileDialog.open();
		fileName = fileName.replace("\\", "/")
		return "\"".concat(fileName).concat("\"");
	}
}

/**
 * see http://www.eclipse.org/Xtext/documentation.html#contentAssist on how to customize content assistant
 */
class ReportDSLProposalProvider extends AbstractReportDSLProposalProvider {

	@Inject TerminalsProposalProvider provider
	@Inject BasicDSLProposalProviderHelper providerHelper
	
	ICompletionProposal proposal

	def iconPickerProposal(EObject model, Assignment assignment, ContentAssistContext context,
		ICompletionProposalAcceptor acceptor, String fileExtensions) {
		var fileName = createCompletionProposal("Select icon...", context) as ConfigurableCompletionProposal
		if (fileName != null) {
			var applier = new IconNameTextApplier()
			applier.setExtensions(fileExtensions.split(","))
			applier.setContext(context)
			fileName.setTextApplier = applier
		}
		acceptor.accept(fileName)
	}

	override completeTableTrend_Icon(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		iconPickerProposal(model, assignment, context, acceptor, ".png")
	}

	override completeTableIcon_Icon(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		iconPickerProposal(model, assignment, context, acceptor, ".png")
	}
		
	// overriding the completeKeyword method to filter the available proposals
	override void completeKeyword(Keyword keyword, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor) {
		if (keyword.allowedKeyword(contentAssistContext, acceptor)){
			super.completeKeyword(keyword, contentAssistContext, acceptor)
		}
	}
	
//	override createProposals(ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
//		var nullSafe = new NullSafeCompletionProposalAcceptor(acceptor);
//		var selector = createSelector(context, nullSafe);
//		for (AbstractElement element : context.getFirstSetGrammarElements()) {
//			selector.accept(element);
//		}
//	}
	
	def private boolean allowedKeyword(Keyword keyword, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor){
		if (contentAssistContext.isInPageTemplate && keyword.isAPageTemplateNotAllowedTableRule(contentAssistContext, acceptor)){
			return false
		}
		if (!contentAssistContext.isPageDetail && keyword.isAHeaderFooterNotAllowedTableRule(contentAssistContext, acceptor)){
			return false
		}
		if (contentAssistContext.isTableHeader && keyword.isAHeaderNotAllowedTableRule(contentAssistContext, acceptor)){
			return false
		}
		if (contentAssistContext.isTableGroupHeader && keyword.isAHeaderFooterNotAllowedTableRule(contentAssistContext, acceptor)){
			return false
		}
		if (keyword.isDatamartTableGroupNotAllowed(contentAssistContext, acceptor)){
			return false
		}
		return true
	}
	
	def private boolean isAPageTemplateNotAllowedTableRule(Keyword keyword, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor){
		return ((keyword.isDatamartTableRule(contentAssistContext, acceptor))
			 || (keyword.isDatamartTableAttributeRule(contentAssistContext, acceptor))
			 || (keyword.isTableAttributeRule(contentAssistContext, acceptor))
			 || (keyword.isDatamartTableGroupRule(contentAssistContext, acceptor))
			 || (keyword.isTableAggregationRule(contentAssistContext, acceptor))
			 || (keyword.isTableUnaryAggregationRule(contentAssistContext, acceptor))
			 || (keyword.isTableMultipleAggregationRule(contentAssistContext, acceptor))
			 || (keyword.isTableBinaryAggregationRule(contentAssistContext, acceptor))
		)
	}
	
	def private boolean isAHeaderNotAllowedTableRule(Keyword keyword, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor){
		return ((keyword.isDatamartTableRule(contentAssistContext, acceptor))
			 || (keyword.isDatamartTableAttributeRule(contentAssistContext, acceptor))
			 || (keyword.isTableAttributeRule(contentAssistContext, acceptor))
			 || (keyword.isDatamartTableGroupRule(contentAssistContext, acceptor))
			 || (keyword.isImageAttributeRule(contentAssistContext, acceptor))
			 || (keyword.isTableAggregationRule(contentAssistContext, acceptor))
			 || (keyword.isStringBinderRule(contentAssistContext, acceptor))
			 || (keyword.isTitleBinderRule(contentAssistContext, acceptor))
			 || (keyword.isSubTitleBinderRule(contentAssistContext, acceptor))
			 || (keyword.isSubSubTitleBinderRule(contentAssistContext, acceptor))
			 || (keyword.isTextRule(contentAssistContext, acceptor))
			 || (keyword.isAutoTextRule(contentAssistContext, acceptor))
		)
	}
		
	def private boolean isAHeaderFooterNotAllowedTableRule(Keyword keyword, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor){
		return ((keyword.isDatamartTableRule(contentAssistContext, acceptor))
			 || (keyword.isDatamartTableAttributeRule(contentAssistContext, acceptor))
//			 || (keyword.isTableAttributeRule(contentAssistContext, acceptor))
			 || (keyword.isDatamartTableGroupRule(contentAssistContext, acceptor))
			 || (keyword.isTableUnaryAggregationRule(contentAssistContext, acceptor))
			 || (keyword.isTableMultipleAggregationRule(contentAssistContext, acceptor))
			 || (keyword.isTableBinaryAggregationRule(contentAssistContext, acceptor))
		)
	}
		
	def private boolean isDatamartTableGroupNotAllowed(Keyword keyword, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor){
		if (contentAssistContext.currentModel instanceof TableAggregation) {
			var aggregation = (contentAssistContext.currentModel as TableAggregation)
			var eObj = aggregation.eContainer
			// A group definition is allowed within a table, but not within a grid. 
			// So if the first container found is a Grid instead of a DatamartTable the group in defined within a grid. 
			while ((eObj !== null) && (!(eObj instanceof DatamartTable) && !(eObj instanceof Grid))){
				eObj = eObj.eContainer
			}
			if (eObj instanceof Grid){
				return true
			} 
		}
		return false	
	}
		
	def private boolean isDatamartTableRule(Keyword keyword, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor){
		return keyword.isFromRuleClass(contentAssistContext, acceptor, DatamartTable)
	}
	
	def private boolean isDatamartTableHeaderRule(Keyword keyword, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor){
		return keyword.isFromRuleClass(contentAssistContext, acceptor, DatamartTableHeader)
	}
	
	def private boolean isDatamartTableFooterRule(Keyword keyword, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor){
		return keyword.isFromRuleClass(contentAssistContext, acceptor, DatamartTableHeader)
	}
	
	def private boolean isDatamartTableAttributeRule(Keyword keyword, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor){
		return keyword.isFromRuleClass(contentAssistContext, acceptor, DatamartTableAttribute)
	}
	
	def private boolean isTableAttributeRule(Keyword keyword, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor){
		return keyword.isFromRuleClass(contentAssistContext, acceptor, TableAttribute)
	}
	
	def private boolean isDatamartTableGroupRule(Keyword keyword, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor){
		return keyword.isFromRuleClass(contentAssistContext, acceptor, DatamartTableGroup)
	}
	
	def private boolean isImageAttributeRule(Keyword keyword, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor){
		return keyword.isFromRuleClass(contentAssistContext, acceptor, Image)
	}
	
	def private boolean isTableUnaryAggregationRule(Keyword keyword, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor){
		return (keyword.isFromRuleClass(contentAssistContext, acceptor, UnaryAggregationTypeEnum) || keyword.isFromRuleClass(contentAssistContext, acceptor, TableUnaryAggregation))
	}
	
	def private boolean isTableMultipleAggregationRule(Keyword keyword, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor){
		return (keyword.isFromRuleClass(contentAssistContext, acceptor, MultipleAggregationTypeEnum) || keyword.isFromRuleClass(contentAssistContext, acceptor, TableMultipleAggregation))
	}
	
	def private boolean isTableBinaryAggregationRule(Keyword keyword, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor){
		return (keyword.isFromRuleClass(contentAssistContext, acceptor, BinaryAggregationTypeEnum) || keyword.isFromRuleClass(contentAssistContext, acceptor, TableBinaryAggregation))
	}
	
	def private boolean isTableAggregationRule(Keyword keyword, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor){
		return keyword.isFromRuleClass(contentAssistContext, acceptor, TableAggregation)
	}
	
	def private boolean isStringBinderRule(Keyword keyword, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor){
		return keyword.isFromRuleClass(contentAssistContext, acceptor, StringBinder)
	}
	
	def private boolean isTitleBinderRule(Keyword keyword, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor){
		return keyword.isFromRuleClass(contentAssistContext, acceptor, Title)
	}
	
	def private boolean isSubTitleBinderRule(Keyword keyword, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor){
		return keyword.isFromRuleClass(contentAssistContext, acceptor, SubTitle)
	}
	
	def private boolean isSubSubTitleBinderRule(Keyword keyword, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor){
		return keyword.isFromRuleClass(contentAssistContext, acceptor, SubSubTitle)
	}
	
	def private boolean isTextRule(Keyword keyword, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor){
		return keyword.isFromRuleClass(contentAssistContext, acceptor, Text)
	}
	
	def private boolean isAutoTextRule(Keyword keyword, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor){
		return keyword.isFromRuleClass(contentAssistContext, acceptor, AutoText)
	}
	
	// identifies if the keyword is from a defined rule class
	def private boolean isFromRuleClass(Keyword keyword, ContentAssistContext contentAssistContext,
			ICompletionProposalAcceptor acceptor, Class ruleClass){
		if	(keyword instanceof Keyword) {
			var ruleClassName = ruleClass.canonicalName
			var eObj = keyword.eContainer
			while ((eObj !== null) && (!(eObj instanceof ParserRule || eObj instanceof EnumLiteralDeclaration))) {
				eObj = eObj.eContainer
			}
			if	(eObj instanceof ParserRule) {
				var parserRule = eObj as ParserRule
				var type = parserRule.type
				var classifier = type.classifier
				var instanceClass = classifier.instanceClass
				return (instanceClass.canonicalName.equals(ruleClassName))
			} else if (eObj instanceof EnumLiteralDeclaration) {
				var enumLiteralDeclaration = eObj as EnumLiteralDeclaration
				var enumClassName = enumLiteralDeclaration.enumLiteral.instance.class.canonicalName
				return enumClassName.equals(ruleClassName)
			}
		}
		return false
	}
	
	// identifies if the current model of the content assist context is in a page template container  
	def private boolean isInPageTemplate(ContentAssistContext context){
		var eObj = context.currentModel
		while ((eObj!==null) && !(eObj instanceof PageTemplate)){
			eObj = eObj.eContainer
		}
		if ((eObj instanceof PageTemplate)){
			return true
		}
		return false
	}
	
	// identifies if the current model of the content assist context is in a page detail container  
	def private boolean isPageDetail(ContentAssistContext context){
		var eObj = context.currentModel
		while ((eObj!==null) && !(eObj instanceof PageDetail)){
			eObj = eObj.eContainer
		}
		if ((eObj instanceof PageDetail)){
			return true
		}
		return false
	}
	
	// identifies if the current model of the content assist context is in a table header container  
	def private boolean isTableHeader(ContentAssistContext context){
		var eObj = context.currentModel
		while ((eObj!==null) && !(eObj instanceof DatamartTableHeader)){
			eObj = eObj.eContainer
		}
		if ((eObj instanceof DatamartTableHeader)){
			return (eObj.eContainer instanceof DatamartTable)
		}
		return false
	}
	
	// identifies if the current model of the content assist context is in a table header in a group container  
	def private boolean isTableGroupHeader(ContentAssistContext context){
		var eObj = context.currentModel
		while ((eObj!==null) && !(eObj instanceof DatamartTableHeader)){
			eObj = eObj.eContainer
		}
		if ((eObj instanceof DatamartTableHeader)){
			return (eObj.eContainer instanceof DatamartTableGroup)
		}
		return false
	}
	
	// identifies if the current model of the content assist context is in a datamart table container  
	def private boolean isDatamartTable(ContentAssistContext context){
		var eObj = context.currentModel
		if ((eObj instanceof DatamartTable)){
			return true
		}
		return false
	}
	
	// identifies if the current model of the content assist context is in a datamart table header container  
	def private boolean isDatamartTableHeader(ContentAssistContext context){
		var eObj = context.currentModel
		if ((eObj instanceof DatamartTableHeader)){
			return true
		}
		return false
	}
	
	// identifies if the current model of the content assist context is in a datamart table footer container  
	def private boolean isDatamartTableFooter(ContentAssistContext context){
		var eObj = context.currentModel
		if ((eObj instanceof DatamartTableFooter)){
			return true
		}
		return false
	}
	
	override void completeColor_Color(EObject model, Assignment assignment, ContentAssistContext context,
		ICompletionProposalAcceptor acceptor) {
		var color = createCompletionProposal("Select color...", context) as ConfigurableCompletionProposal
		if (color !== null) {
			var applier = new ColorTextApplier()
			applier.setContext(context)
			color.setTextApplier = applier
		}
		acceptor.accept(color)
	}

	override void completeImage_Filename(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
//		var imageModel = context.currentModel as Image
//		if (imageModel.sourceType != ImageSourceEnum.URL){
//			filePickerProposal(model, assignment, context, acceptor, "*.*")
//		} else {
			provider.complete_STRING(model, (assignment.getTerminal() as RuleCall), context, acceptor)
//		}
	}

	override void completePersistenceUnit_Name(EObject model, Assignment assignment, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		var pref = ProductConfiguration.prefs()
		for (persistenceUnit : pref.persistenceUnits) {
			var proposal = createCompletionProposal("\"" + persistenceUnit.name + "\"", context);
			acceptor.accept(proposal);
		}
		
	}

	/**
	 * This override will enable 1 length non letter characters as keyword.
	 */
	override protected boolean isKeywordWorthyToPropose(Keyword keyword) {
		true
	}

	def getContainingDatamartTable(EObject o) {
		var result = o
		while (!(result instanceof DatamartTable) && (result.eContainer !== null)) {
			result = result.eContainer
		}
		return result as DatamartTable
	}

	override protected boolean isValidProposal(String proposal, String prefix, ContentAssistContext context) {
		if (!super.isValidProposal(proposal, prefix, context)) {
			return false
		} else if ("on-group".equals(proposal)){
			return !context.isInPageTemplate
		} else if (context?.currentModel instanceof DatamartTableAttribute) {
			var eObject =  context?.currentModel.eContainer()
			while (eObject !== null && !(eObject instanceof DatamartTableDetail)){
				eObject = eObject.eContainer
			}
			if (eObject instanceof DatamartTableDetail && (eObject as DatamartTableDetail)?.style !== null){
				return !proposal.equals((eObject as DatamartTableDetail).style.name)
			}
			return true
		} else {

			//			var currentModel = context.getCurrentModel();
			//		if (context.getCurrentModel() instanceof Datamart) {
			//			return isDatamartValidProposal(context, proposal)
			//		}
			//			switch (currentModel) {
			//				CCTableProperty: 	{
			//					var source = getContainingDatamartTable(currentModel).datamartRef.source
			//					switch (source) {
			//						CCDatamartEntity: 	return datamartEntityContainsProperty(source, proposal)
			//						default:			return true
			//					}
			//				}
			//				default: 			return true //super.isValidProposal(proposal, prefix, context)
			//			}
			return true
		}
	}

	def protected boolean datamartEntityContainsProperty(DatamartEntity entity, String proposal) {
		for (navigation : entity.navigations) {
			if (datamartEntityContainsProperty(navigation.datamartEntity, proposal)) {
				return true
			}
		}
		for (property : entity.attributes) {
			//			val attribute = property.propertyRef as LEntityAttribute
			//			if	(attribute.name.equals(proposal)) {
			//				return true
			//			}
		}
		return false
	}
	
	def filePickerProposal(EObject model, Assignment assignment, ContentAssistContext context,
		ICompletionProposalAcceptor acceptor, String fileExtensions) {
		var fileName = createCompletionProposal("Select input file...", context) as ConfigurableCompletionProposal
		if (fileName !== null) {
			var applier = new FileNameTextApplier()
			applier.setExtensions(fileExtensions.split(","))
			applier.setContext(context)
			fileName.setTextApplier = applier
		}
		acceptor.accept(fileName)
	}

	//	def isDatamartValidProposal(ContentAssistContext context, String proposal) {
	//		var eObj = context.currentModel
	//		while (!(eObj instanceof Datamart)) {
	//			eObj = eObj.eContainer
	//		}
	//		
	//		return true
	//	}
	/**
	 * @see BasicDSLProposalProviderHelper#getKeywordDisplayString(Keyword, BasicDSLUiTranslator)
	 * @param keyword the keyword to get the displayed string for
	 * @return the displayed string
	 */
	override protected StyledString getKeywordDisplayString(Keyword keyword) {
		return BasicDSLProposalProviderHelper.getKeywordDisplayString(keyword,
			ReportDSLUiDocumentationTranslator.instance())
	}

	override public void complete_QualifiedName(EObject model, RuleCall ruleCall, ContentAssistContext context,
		ICompletionProposalAcceptor acceptor) {
		providerHelper.complete_PackageName(model, ruleCall, context, acceptor, this)
	}

	override complete_UnsignedNumber(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		providerHelper.createNumberProposal(context, acceptor, ruleCall, this)
	}

	override complete_SignedNumber(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		providerHelper.createNumberProposal(context, acceptor, ruleCall, this)
	}

	// ------------------------ delegates to TerminalsProposalProvider -----------------
	override public void complete_INT(EObject model, RuleCall ruleCall, ContentAssistContext context,
		ICompletionProposalAcceptor acceptor) {
		provider.complete_INT(model, ruleCall, context, acceptor)
	}

	override public void complete_ID(EObject model, RuleCall ruleCall, ContentAssistContext context,
		ICompletionProposalAcceptor acceptor) {
		provider.complete_ID(model, ruleCall, context, acceptor)
	}

	override public void complete_TRANSLATABLESTRING(EObject model, RuleCall ruleCall, ContentAssistContext context,
		ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, ruleCall, context, acceptor)
	}

	override public void complete_STRING(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, ruleCall, context, acceptor)
	}

	override public void completeTableStringLookup_LookupValue(EObject model, Assignment assignment,
		ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, (assignment.getTerminal() as RuleCall), context, acceptor)
	}

	override public void completeReportPackage_ExternalCssURI(EObject model, Assignment assignment,
		ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, (assignment.getTerminal() as RuleCall), context, acceptor)
	}

	override public void completeReportPackage_ExternalCssURIBundle(EObject model, Assignment assignment,
		ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, (assignment.getTerminal() as RuleCall), context, acceptor)
	}

	override public void completeReport_ExternalCssURI(EObject model, Assignment assignment,
		ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, (assignment.getTerminal() as RuleCall), context, acceptor)
	}

	override public void completeReport_ExternalCssURIBundle(EObject model, Assignment assignment,
		ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, (assignment.getTerminal() as RuleCall), context, acceptor)
	}

	override public void completeFont_Family(EObject model, Assignment assignment, ContentAssistContext context,
		ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, (assignment.getTerminal() as RuleCall), context, acceptor)
	}

	override public void completeUomoFormat_Ui_pattern(EObject model, Assignment assignment,
		ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, (assignment.getTerminal() as RuleCall), context, acceptor)
	}

	override public void completeNumberFormat_Ui_pattern(EObject model, Assignment assignment,
		ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, (assignment.getTerminal() as RuleCall), context, acceptor)
	}

	override public void completeCurrencyFormat_Ui_pattern(EObject model, Assignment assignment,
		ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, (assignment.getTerminal() as RuleCall), context, acceptor)
	}

	override public void completeDateFormat_Ui_pattern(EObject model, Assignment assignment,
		ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, (assignment.getTerminal() as RuleCall), context, acceptor)
	}

	override public void completeDateTimeFormat_Ui_pattern(EObject model, Assignment assignment,
		ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, (assignment.getTerminal() as RuleCall), context, acceptor)
	}

	override public void completeTimeFormat_Ui_pattern(EObject model, Assignment assignment,
		ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, (assignment.getTerminal() as RuleCall), context, acceptor)
	}

	override public void completeUomoFormat_Report_pattern(EObject model, Assignment assignment,
		ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, (assignment.getTerminal() as RuleCall), context, acceptor)
	}

	override public void completeNumberFormat_Report_pattern(EObject model, Assignment assignment,
		ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, (assignment.getTerminal() as RuleCall), context, acceptor)
	}

	override public void completeCurrencyFormat_Report_pattern(EObject model, Assignment assignment,
		ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, (assignment.getTerminal() as RuleCall), context, acceptor)
	}

	override public void completeDateFormat_Report_pattern(EObject model, Assignment assignment,
		ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, (assignment.getTerminal() as RuleCall), context, acceptor)
	}

	override public void completeDateTimeFormat_Report_pattern(EObject model, Assignment assignment,
		ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, (assignment.getTerminal() as RuleCall), context, acceptor)
	}

	override public void completeTimeFormat_Report_pattern(EObject model, Assignment assignment,
		ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, (assignment.getTerminal() as RuleCall), context, acceptor)
	}

	override public void completeReportDesignFile_Name(EObject model, Assignment assignment,
		ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, (assignment.getTerminal() as RuleCall), context, acceptor)
	}

	override public void completeTableFormatter_Format(EObject model, Assignment assignment,
		ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, (assignment.getTerminal() as RuleCall), context, acceptor)
	}

	override public void completeTableImage_ImagePathPattern(EObject model, Assignment assignment,
		ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, (assignment.getTerminal() as RuleCall), context, acceptor)
	}

	override public void completeTableImage_ResizeString(EObject model, Assignment assignment,
		ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
		provider.complete_STRING(model, (assignment.getTerminal() as RuleCall), context, acceptor)
	}
}
