/**
 * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), 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 v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *         Florian Pirchner - Initial implementation
 */
package org.eclipse.osbp.ecview.dsl.ui.contentassist;

import com.google.common.base.Objects;
import com.google.inject.Inject;
import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.osbp.ecview.dsl.ui.contentassist.AbstractUIGrammarProposalProvider;
import org.eclipse.osbp.ecview.semantic.uimodel.UiModel;
import org.eclipse.osbp.ide.core.api.i18n.II18nRegistry;
import org.eclipse.osbp.ide.core.ui.util.CoreUiUtil;
import org.eclipse.osbp.xtext.basic.ui.contentassist.BasicDSLProposalProviderHelper;
import org.eclipse.xtext.AbstractElement;
import org.eclipse.xtext.Assignment;
import org.eclipse.xtext.Keyword;
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;

/**
 * see http://www.eclipse.org/Xtext/documentation.html#contentAssist on how to customize content assistant
 */
@SuppressWarnings("all")
public class UIGrammarProposalProvider extends AbstractUIGrammarProposalProvider {
  @Inject
  private II18nRegistry i18nRegistry;
  
  @Inject
  private CoreUiUtil util;
  
  @Inject
  private TerminalsProposalProvider provider;
  
  @Inject
  private BasicDSLProposalProviderHelper providerHelper;
  
  @Override
  public void completeUiI18nInfo_Key(final EObject model, final Assignment assignment, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) {
    final IProject project = this.util.getProject(model);
    final String searchString = context.getPrefix().replaceAll("\"", "");
    final List<II18nRegistry.Proposal> proposals = this.i18nRegistry.findContentProposals(project, this.util.getLocale(), this.findPackage(model), searchString);
    final int replacementOffset = context.getReplaceRegion().getOffset();
    int _length = context.getReplaceRegion().getLength();
    final int replacementLength = (_length + 1);
    final boolean relativePath = searchString.startsWith(".");
    for (final II18nRegistry.Proposal proposal : proposals) {
      {
        String _replacementString = this.toReplacementString(proposal, relativePath);
        String _plus = ("\"" + _replacementString);
        String _plus_1 = (_plus + "\"");
        final ConfigurableCompletionProposal result = this.doCreateProposal(_plus_1, this.displayString(proposal), null, replacementOffset, replacementLength);
        result.setPriority(1);
        result.setMatcher(context.getMatcher());
        result.setReplaceContextLength(context.getReplaceContextLength());
        acceptor.accept(result);
      }
    }
  }
  
  public String toReplacementString(final II18nRegistry.Proposal proposal, final boolean relative) {
    if ((!relative)) {
      return proposal.getI18nKey();
    } else {
      final String[] pathTokens = proposal.getI18nKey().split("\\.");
      String _xifexpression = null;
      int _length = pathTokens.length;
      boolean _greaterThan = (_length > 0);
      if (_greaterThan) {
        int _length_1 = pathTokens.length;
        int _minus = (_length_1 - 1);
        String _get = pathTokens[_minus];
        _xifexpression = ("." + _get);
      } else {
        _xifexpression = "";
      }
      return _xifexpression;
    }
  }
  
  /**
   * Iterates the containment tree up to the UiModel and returns the package.
   */
  public String findPackage(final EObject model) {
    EObject temp = model;
    while (((!Objects.equal(temp, null)) && (!Objects.equal(temp.eContainer(), null)))) {
      {
        if ((temp instanceof UiModel)) {
          final UiModel uiModel = ((UiModel) temp);
          return uiModel.getPackageName();
        }
        temp = temp.eContainer();
        if ((temp instanceof UiModel)) {
          final UiModel uiModel_1 = ((UiModel) temp);
          return uiModel_1.getPackageName();
        }
      }
    }
    return "";
  }
  
  @Override
  public void completeUiMaxLengthValidator_MaxLength(final EObject model, final Assignment assignment, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) {
    StyledString _styledString = new StyledString("any number");
    acceptor.accept(this.doCreateProposal("1", _styledString, null, 0, context));
    StyledString _styledString_1 = new StyledString("any number");
    acceptor.accept(this.doCreateProposal("2", _styledString_1, null, 0, context));
    StyledString _styledString_2 = new StyledString("any number");
    acceptor.accept(this.doCreateProposal("3", _styledString_2, null, 0, context));
    StyledString _styledString_3 = new StyledString("any number");
    acceptor.accept(this.doCreateProposal("4", _styledString_3, null, 0, context));
    StyledString _styledString_4 = new StyledString("any number");
    acceptor.accept(this.doCreateProposal("10", _styledString_4, null, 0, context));
    StyledString _styledString_5 = new StyledString("any number");
    acceptor.accept(this.doCreateProposal("12", _styledString_5, null, 0, context));
    StyledString _styledString_6 = new StyledString("any number");
    acceptor.accept(this.doCreateProposal("15", _styledString_6, null, 0, context));
    StyledString _styledString_7 = new StyledString("any number");
    acceptor.accept(this.doCreateProposal("20", _styledString_7, null, 0, context));
    StyledString _styledString_8 = new StyledString("any number");
    acceptor.accept(this.doCreateProposal("25", _styledString_8, null, 0, context));
    StyledString _styledString_9 = new StyledString("any number");
    acceptor.accept(this.doCreateProposal("125", _styledString_9, null, 0, context));
  }
  
  @Override
  public void completeUiMinLengthValidator_MinLength(final EObject model, final Assignment assignment, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) {
    StyledString _styledString = new StyledString("any number");
    acceptor.accept(this.doCreateProposal("1", _styledString, null, 0, context));
    StyledString _styledString_1 = new StyledString("any number");
    acceptor.accept(this.doCreateProposal("2", _styledString_1, null, 0, context));
    StyledString _styledString_2 = new StyledString("any number");
    acceptor.accept(this.doCreateProposal("3", _styledString_2, null, 0, context));
    StyledString _styledString_3 = new StyledString("any number");
    acceptor.accept(this.doCreateProposal("4", _styledString_3, null, 0, context));
    StyledString _styledString_4 = new StyledString("any number");
    acceptor.accept(this.doCreateProposal("10", _styledString_4, null, 0, context));
    StyledString _styledString_5 = new StyledString("any number");
    acceptor.accept(this.doCreateProposal("12", _styledString_5, null, 0, context));
    StyledString _styledString_6 = new StyledString("any number");
    acceptor.accept(this.doCreateProposal("15", _styledString_6, null, 0, context));
    StyledString _styledString_7 = new StyledString("any number");
    acceptor.accept(this.doCreateProposal("20", _styledString_7, null, 0, context));
    StyledString _styledString_8 = new StyledString("any number");
    acceptor.accept(this.doCreateProposal("25", _styledString_8, null, 0, context));
    StyledString _styledString_9 = new StyledString("any number");
    acceptor.accept(this.doCreateProposal("125", _styledString_9, null, 0, context));
  }
  
  @Override
  public void completeUiRegexpValidator_RegExpression(final EObject model, final Assignment assignment, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) {
    StyledString _styledString = new StyledString("any regular expression");
    acceptor.accept(this.doCreateProposal("*abc", _styledString, null, 0, context));
  }
  
  public StyledString displayString(final II18nRegistry.Proposal proposal) {
    String _i18nValue = proposal.getI18nValue();
    final StyledString displayText = new StyledString(_i18nValue, StyledString.QUALIFIER_STYLER).append(" : ").append(proposal.getLocale().toLanguageTag(), StyledString.DECORATIONS_STYLER).append(" - ").append(
      proposal.getI18nKey(), StyledString.DECORATIONS_STYLER);
    return displayText;
  }
  
  @Override
  public boolean isKeywordWorthyToPropose(final Keyword keyword) {
    return true;
  }
  
  @Override
  public void complete_ID(final EObject model, final RuleCall ruleCall, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) {
    this.provider.complete_ID(model, ruleCall, context, acceptor);
  }
  
  @Override
  public void complete_STRING(final EObject model, final RuleCall ruleCall, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) {
    this.provider.complete_STRING(model, ruleCall, context, acceptor);
  }
  
  @Override
  public void completeUiModel_PackageName(final EObject model, final Assignment assignment, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) {
    AbstractElement _terminal = assignment.getTerminal();
    this.providerHelper.complete_PackageName(model, ((RuleCall) _terminal), context, acceptor, this);
  }
  
  @Override
  public void complete_QualifiedNameWithWildcard(final EObject model, final RuleCall ruleCall, final ContentAssistContext context, final ICompletionProposalAcceptor acceptor) {
    this.providerHelper.complete_PackageName(model, ruleCall, context, acceptor, this);
  }
}
