/**
 * generated by Xtext
 */
package org.xtext.example.domij.scoping;

import java.util.List;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.xtext.nodemodel.ICompositeNode;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider;
import org.eclipse.xtext.scoping.impl.FilteringScope;

import com.google.common.base.Predicate;

import er.*;
import er.impl.ErPackageImpl;

/**
 * This class contains custom scoping description.
 * 
 * see : http://www.eclipse.org/Xtext/documentation.html#scoping
 * on how and when to use it
 */
@SuppressWarnings("all")
public class ErDslScopeProvider extends AbstractDeclarativeScopeProvider {
	
	public IScope scope_Categorisation_categorisedEntity (final Categorisation context, EReference reference) {
		IScope delegateScope = delegateGetScope(context, reference);
		Predicate<IEObjectDescription> filter = new Predicate<IEObjectDescription>(){
		@Override
		public boolean apply(IEObjectDescription input) {
			EntityConcept ec = (EntityConcept) input.getEObjectOrProxy();
			ICompositeNode catcontext = NodeModelUtils.findActualNodeFor(context);
			if(catcontext!=null){
				try{
					String category = catcontext.getText().substring(catcontext.getText().indexOf("categorisationEntities")).substring(0, catcontext.getText().substring(catcontext.getText().indexOf("categorisationEntities")).indexOf(")"));
					if(input.getEObjectOrProxy() instanceof Entity  && category.contains(((Entity)ec).getName()))
							return false;
				}catch (java.lang.StringIndexOutOfBoundsException e) {}
			}
			return true;
		}
		};
		FilteringScope fs = new FilteringScope(delegateScope, filter);
		return fs;
	}
	
	
	public IScope scope_Categories_entities (final Categorisation context, EReference reference) {
		IScope delegateScope = delegateGetScope(context, reference);
		Predicate<IEObjectDescription> filter = new Predicate<IEObjectDescription>(){
		@Override
		public boolean apply(IEObjectDescription input) {
			EntityConcept ec = (EntityConcept) input.getEObjectOrProxy();
			ICompositeNode catcontext = NodeModelUtils.findActualNodeFor(context);
			if(catcontext!=null){
				try{
					String category = catcontext.getText().substring(catcontext.getText().indexOf("categorisedEntity")).substring(0, catcontext.getText().substring(catcontext.getText().indexOf("categorisedEntity")).indexOf("categorisationEntities"));
					if(input.getEObjectOrProxy() instanceof Entity  && category.contains(((Entity)ec).getName()))
							return false;
				}catch (java.lang.StringIndexOutOfBoundsException e) {}
			}
			return true;
		}
		};
		FilteringScope fs = new FilteringScope(delegateScope, filter);
		return fs;
	}
	
	public IScope scope_EntityConcept (final ISA context, EReference reference) {
		IScope delegateScope = delegateGetScope(context, reference);
		Predicate<IEObjectDescription> filter = new Predicate<IEObjectDescription>(){
		@Override
		public boolean apply(IEObjectDescription input) {
			EntityConcept ec = (EntityConcept) input.getEObjectOrProxy();
			ICompositeNode isacontext = NodeModelUtils.findActualNodeFor(context);
			if(isacontext!=null){
				try {
					String subtypes = isacontext.getText().substring(isacontext.getText().indexOf("subtypes")).substring(0, isacontext.getText().substring(isacontext.getText().indexOf("subtypes")).indexOf(')'));
					if(input.getEObjectOrProxy() instanceof Entity  && subtypes.contains(((Entity)ec).getName()))
							return false;
				}catch (java.lang.StringIndexOutOfBoundsException e) {}
			}
			return true;
		}
		};
		FilteringScope fs = new FilteringScope(delegateScope, filter);
		return fs;
	}
	
	public IScope scope_Entity (final ISA context, EReference reference) {
		IScope delegateScope = delegateGetScope(context, reference);
		Predicate<IEObjectDescription> filter = new Predicate<IEObjectDescription>(){
		@Override
		public boolean apply(IEObjectDescription input) {
			Entity e = (Entity) input.getEObjectOrProxy();
			if (context.getSupertype()!=null && e.equals(context.getSupertype().getEntity()))
					return false;
			return true;
		}
		};
		FilteringScope fs = new FilteringScope(delegateScope, filter);
		return fs;
	}
	
	public IScope scope_EntityConcept (final IdentificationDependency context, EReference reference) {
		IScope delegateScope = delegateGetScope(context, reference);
		Predicate<IEObjectDescription> filter = new Predicate<IEObjectDescription>(){
		@Override
		public boolean apply(IEObjectDescription input) {
			EntityConcept ec = (EntityConcept) input.getEObjectOrProxy();
			ICompositeNode idcontext = NodeModelUtils.findActualNodeFor(context);
			if(idcontext != null) {
				try {
					String weakentity = idcontext.getText().substring(idcontext.getText().indexOf("weakEntity")).substring(0, idcontext.getText().substring(idcontext.getText().indexOf("weakEntity")).indexOf("regularEntity"));
					if(input.getEObjectOrProxy() instanceof Entity  && weakentity.contains(((Entity)ec).getName()))
							return false;
				}catch (java.lang.StringIndexOutOfBoundsException e) {}
			}
			return true;
		}
		};
		FilteringScope fs = new FilteringScope(delegateScope, filter);
		return fs;
	}
	
	public IScope scope_Entity (final IdentificationDependency context, EReference reference) {
		IScope delegateScope = delegateGetScope(context, reference);
		Predicate<IEObjectDescription> filter = new Predicate<IEObjectDescription>(){
		@Override
		public boolean apply(IEObjectDescription input) {
			Entity e = (Entity) input.getEObjectOrProxy();
			if (context.getRegularEntity() != null && (e.equals(context.getRegularEntity().getEntity()))/* || (e.equals(context.getWeakEntity()))*/)
					return false;
			return true;
		}
		};
		FilteringScope fs = new FilteringScope(delegateScope, filter);
		return fs;
	}
	
	public IScope scope_Attribute (final ISA context, EReference reference) {
		IScope delegateScope = delegateGetScope(context, reference);
		Predicate<IEObjectDescription> filter = new Predicate<IEObjectDescription>(){
		@Override
		public boolean apply(IEObjectDescription input) {
			Attribute a = (Attribute) input.getEObjectOrProxy();
			try{
				if(context.getSupertype() != null && a.eContainer() instanceof Entity  && ((Entity) a.eContainer()).equals(context.getSupertype().getEntity()))
						return true;
				else if(context.getSupertype() != null && a.eContainer() instanceof Relationship  && ((Relationship) a.eContainer()).equals(((Gerund)context.getSupertype().getEntity()).getRelationship()))
						return true;
			}catch (java.lang.ClassCastException c){}
			return false;
		}
		};
		FilteringScope fs = new FilteringScope(delegateScope, filter);
		return fs;
	}
	
	public IScope scope_Attribute (final Key context, EReference reference) {
		IScope delegateScope = delegateGetScope(context, reference);
		Predicate<IEObjectDescription> filter = new Predicate<IEObjectDescription>(){
		@Override
		public boolean apply(IEObjectDescription input) {
			Attribute a = (Attribute) input.getEObjectOrProxy();
			if(a.eContainer() instanceof Entity && ((Entity) a.eContainer()).equals(context.eContainer()) /*&&  (!context.getKeyAttributes().contains(a))*/)
					return true;
			else if(a.eContainer() instanceof Relationship && ((Relationship) a.eContainer()).equals(context.eContainer())/* &&  (!context.getKeyAttributes().contains(a))*/)
					return true;
			return false;
		}
		};
		FilteringScope fs = new FilteringScope(delegateScope, filter);
		return fs;
	}
	
	public IScope scope_Key (final Entity context, EReference reference) {
		IScope delegateScope = delegateGetScope(context, reference);
		Predicate<IEObjectDescription> filter = new Predicate<IEObjectDescription>(){
		@Override
		public boolean apply(IEObjectDescription input) {
			Key k = (Key) input.getEObjectOrProxy();
			if(k.eContainer() instanceof Entity && ((Entity) k.eContainer()).equals(context))
					return true;
			return false;
		}
		};
		FilteringScope fs = new FilteringScope(delegateScope, filter);
		return fs;
	} 
	
	public IScope scope_Key (final Relationship context, EReference reference) {
		IScope delegateScope = delegateGetScope(context, reference);
		Predicate<IEObjectDescription> filter = new Predicate<IEObjectDescription>(){
		@Override
		public boolean apply(IEObjectDescription input) {
			Key k = (Key) input.getEObjectOrProxy();
			if(k.eContainer() instanceof Relationship && ((Relationship) k.eContainer()).equals(context))
					return true;
			return false;
		}
		};
		FilteringScope fs = new FilteringScope(delegateScope, filter);
		return fs;
	}
}
