/**
 *                                                                            
 * 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 v1.0       
 * which accompanies this distribution, and is available at                  
 * http://www.eclipse.org/legal/epl-v10.html                                 
 *                                                                            
 * Contributors:   
 * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation 
 * 
 * 
 *  This copyright notice shows up in the generated Java code
 * 
 */
package org.eclipse.osbp.xtext.authorizationdsl.scoping

import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.EReference
import org.eclipse.osbp.xtext.authorizationdsl.AuthorizationDSLPackage
import org.eclipse.osbp.xtext.authorizationdsl.RoleBean
import org.eclipse.osbp.xtext.authorizationdsl.RoleBeanAttribute
import org.eclipse.osbp.xtext.authorizationdsl.RoleBeanReference
import org.eclipse.osbp.xtext.authorizationdsl.RoleBlipProcess
import org.eclipse.osbp.xtext.authorizationdsl.RoleBlipUserTask
import org.eclipse.osbp.xtext.authorizationdsl.RoleDto
import org.eclipse.osbp.xtext.authorizationdsl.RoleDtoAttribute
import org.eclipse.osbp.xtext.authorizationdsl.RoleDtoReference
import org.eclipse.osbp.xtext.authorizationdsl.RoleEntity
import org.eclipse.osbp.xtext.authorizationdsl.RoleEntityAttribute
import org.eclipse.osbp.xtext.authorizationdsl.RoleEntityReference
import org.eclipse.osbp.xtext.blip.BlipUserTask
import org.eclipse.xtext.resource.EObjectDescription
import org.eclipse.xtext.resource.IEObjectDescription
import org.eclipse.xtext.scoping.IScope
import org.eclipse.xtext.scoping.impl.MapBasedScope

class AuthorizationDSLScopeProvider extends AbstractAuthorizationDSLScopeProvider {

	@Override
	override IScope getScope(EObject context, EReference reference) {
		if (reference == AuthorizationDSLPackage.Literals.ROLE_BLIP_USER_TASK__USER_TASK) {
			return getScope_RoleBlipProcess_UserTask(context as RoleBlipUserTask)
		} else if (reference == AuthorizationDSLPackage.Literals.ROLE_ENTITY_FEATURE__ENTITY_ATTRI_COL) {
			return getScope_RoleEntityAttribute(context)
		} else if (reference == AuthorizationDSLPackage.Literals.ROLE_BEAN_FEATURE__BEAN_ATTRI_COL) {
			return getScope_RoleEntityAttribute(context)
		} else if (reference == AuthorizationDSLPackage.Literals.ROLE_DTO_FEATURE__DTO_ATTRI_COL) {
			return getScope_RoleEntityAttribute(context)
		}
		return super.getScope(context, reference)
	}

	def getScope_RoleEntityAttribute(EObject context) {
		var result = <IEObjectDescription>newArrayList
		switch (context) {
			RoleEntityAttribute: {
				var entity = (context.eContainer as RoleEntity).entityRef
				if (entity !== null) {
					for (attr : entity.allAttributes) {
						if (attr.name !== null) {
							result.add(EObjectDescription.create(attr.name, attr))
						}
					}
				}
			}
			RoleEntityReference: {
				var entity = (context.eContainer as RoleEntity).entityRef
				if (entity !== null) {
					for (ref : entity.allReferences) {
						if (ref.name !== null) {
							result.add(EObjectDescription.create(ref.name, ref))
						}
					}
				}

			}
			RoleBeanAttribute: {
				var bean = (context.eContainer as RoleBean).beanRef
				if (bean !== null) {
					for (attr : bean.allAttributes) {
						if (attr.name !== null) {
							result.add(EObjectDescription.create(attr.name, attr))
						}
					}
				}
			}
			RoleBeanReference: {
				var bean = (context.eContainer as RoleBean).beanRef
				if (bean !== null) {
					for (ref : bean.allReferences) {
						if (ref.name !== null) {
							result.add(EObjectDescription.create(ref.name, ref))
						}
					}
				}

			}
			RoleDtoAttribute: {
				var dto = (context.eContainer as RoleDto).dtoRef
				if (dto !== null) {
					for (attr : dto.attributes) {
						if (attr.name !== null) {
							result.add(EObjectDescription.create(attr.name, attr))
						}
					}
				}
			}
			RoleDtoReference: {
				var dto = (context.eContainer as RoleDto).dtoRef
				if (dto !== null) {
					for (ref : dto.references) {
						if (ref.name !== null) {
							result.add(EObjectDescription.create(ref.name, ref))
						}
					}
				}

			}
		}
		return MapBasedScope.createScope(IScope.NULLSCOPE, result)
	}

	def getScope_RoleEntityReference(RoleEntityReference roleEntityReference) {
		var result = <IEObjectDescription>newArrayList
		var entity = (roleEntityReference.eContainer as RoleEntity).entityRef
		if (entity !== null) {
			for (ref : entity.allReferences) {
				if (ref.name !== null) {
					result.add(EObjectDescription.create(ref.name, ref))
				}
			}
		}
		return MapBasedScope.createScope(IScope.NULLSCOPE, result)
	}

	def getScope_RoleBlipProcess_UserTask(RoleBlipUserTask roleBlipUserTask) {
		var result = <IEObjectDescription>newArrayList
		var process = (roleBlipUserTask.eContainer as RoleBlipProcess).process
		if (process !== null) {
			for (item : process.items) {
				if (item instanceof BlipUserTask) {
					result.add(EObjectDescription.create(item.name, item))
				}
			}
		}
		return MapBasedScope.createScope(IScope.NULLSCOPE, result)
	}
}
