/**
 *                                                                            
 *  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.perspective.scoping

import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.EReference
import org.eclipse.osbp.dsl.xtext.lazyresolver.api.EcoreUtil3
import org.eclipse.osbp.ecview.semantic.uimodel.UiIDEView
import org.eclipse.osbp.xtext.blip.Blip
import org.eclipse.osbp.xtext.blip.BlipUserTask
import org.eclipse.osbp.xtext.dialogdsl.Dialog
import org.eclipse.osbp.xtext.perspective.Perspective
import org.eclipse.osbp.xtext.perspective.PerspectiveDialog
import org.eclipse.osbp.xtext.perspective.PerspectiveDslPackage
import org.eclipse.osbp.xtext.perspective.PerspectiveGrid
import org.eclipse.osbp.xtext.perspective.PerspectivePartStack
import org.eclipse.osbp.xtext.perspective.PerspectiveSashContainer
import org.eclipse.osbp.xtext.perspective.PerspectiveSelection
import org.eclipse.osbp.xtext.perspective.PerspectiveTable
import org.eclipse.osbp.xtext.table.Table
import org.eclipse.osbp.xtext.table.TableGrid
import org.eclipse.osbp.xtext.table.TableSelection
import org.eclipse.osbp.xtext.table.TableTable
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
import org.eclipse.xtext.xbase.annotations.typesystem.XbaseWithAnnotationsBatchScopeProvider

class PerspectiveScopeProvider extends XbaseWithAnnotationsBatchScopeProvider {

	@Override
	override IScope getScope(EObject context, EReference reference) {
		if (reference == PerspectiveDslPackage.Literals.PERSPECTIVE_SASH_CONTAINER__SELECTED_ELEMENT) {
			return getScope_CCPerspectiveSashContainer_selected_element(context)
		} else if (reference == PerspectiveDslPackage.Literals.PERSPECTIVE_PART_STACK__SELECTED_ELEMENT) {
			return getScope_CCPerspectivePartStack_selected_element(context)
		} else if (reference == PerspectiveDslPackage.Literals.PERSPECTIVE__USER_TASK) {
			return getScope_CCPerspectivePartStack_USER_TASK(context as Perspective)
		} else if (reference == PerspectiveDslPackage.Literals.PERSPECTIVE_DIALOG__REF) {
			return getScope_CCPerspectivePartStack_PERSPECTIVE_DIALOG__REF(context as PerspectiveDialog, reference)
		} else if (reference == PerspectiveDslPackage.Literals.PERSPECTIVE_SELECTION__REF) {
			return getScope_CCPerspectivePartStack_PERSPECTIVE_SELECTION__REF(context as PerspectiveSelection, reference)
		} else if (reference == PerspectiveDslPackage.Literals.PERSPECTIVE_TABLE__REF) {
			return getScope_CCPerspectivePartStack_PERSPECTIVE_TABLE__REF(context as PerspectiveTable, reference)
		} else if (reference == PerspectiveDslPackage.Literals.PERSPECTIVE_GRID__REF) {
			return getScope_CCPerspectivePartStack_PERSPECTIVE_GRID__REF(context as PerspectiveGrid, reference)
		}
		return super.getScope(context, reference)
	}

	def getScope_CCPerspectivePartStack_PERSPECTIVE_DIALOG__REF(PerspectiveDialog dialogView, EReference reference) {
		val superScope = super.getScope(dialogView, reference)
		var result = <IEObjectDescription>newArrayList
		var perspective = dialogView.eContainer
		while ((perspective != null) && !(perspective instanceof Perspective)) {
			perspective = perspective.eContainer
		}
		if ((perspective as Perspective)?.userTask == null) {
			return superScope
		} else {
			val humanTask = EcoreUtil3.resolve((perspective as Perspective)?.userTask, dialogView.eResource.resourceSet) as BlipUserTask
			val operativeDto = humanTask.operativeLDto
			if (operativeDto?.name == null) {
				return superScope
			} else {
				for (element : superScope.allElements) {
					if (element.EObjectOrProxy instanceof Dialog) {
						var dialog = element.EObjectOrProxy as Dialog
						dialog = EcoreUtil3.resolve(dialog, dialogView.eResource.resourceSet) as Dialog
						if(dialog.uiView != null) {
							val uiViewObj = EcoreUtil3.resolve(dialog.uiView as EObject, dialogView.eResource.resourceSet)
							if (uiViewObj instanceof UiIDEView) {
								val uiView = uiViewObj as UiIDEView
								for (beanSlot : uiView.beanSlots) {
									if (operativeDto.name.equals(beanSlot?.jvmType?.type?.simpleName)) {
										result.add(element)
									}
								}
							}
						} else if(dialog.dto != null) {
							if (operativeDto.name.equals(dialog.dto.name)) {
								result.add(element)
							}
						}
					}
				}
			}
			return MapBasedScope.createScope(IScope.NULLSCOPE, result)
		}
	}

	def getScope_CCPerspectivePartStack_PERSPECTIVE_TABLE__REF(PerspectiveTable tableView, EReference reference) {
		var superScope = super.getScope(tableView, reference)
		var result = <IEObjectDescription>newArrayList
		// extract pure table tables
		for (element : superScope.allElements) {
			if (element.EObjectOrProxy instanceof Table) {
				var table = element.EObjectOrProxy as Table
				table = EcoreUtil3.resolve(table, tableView.eResource.resourceSet) as Table
				if (table.tabletype instanceof TableTable) {
					result.add(element)
				}
				else if (table.tabletype instanceof TableGrid) {
					result.add(element)
				}
			}
		}
		superScope = MapBasedScope.createScope(IScope.NULLSCOPE, result)
		result = <IEObjectDescription>newArrayList
		// check for blip requirements
		var perspective = tableView.eContainer
		while ((perspective != null) && !(perspective instanceof Perspective)) {
			perspective = perspective.eContainer
		}
		if ((perspective as Perspective)?.userTask == null) {
			return superScope
		} else {
			// Even not using the return value of this line it is mandatory to initialize lazy loading for bpmn
			EcoreUtil3.resolve((perspective as Perspective)?.process, tableView.eResource.resourceSet) as Blip
			val humanTask = EcoreUtil3.resolve((perspective as Perspective)?.userTask, tableView.eResource.resourceSet) as BlipUserTask
			val operativeDto = humanTask.operativeLDto
			if (operativeDto?.name == null) {
				return superScope
			} else {
				for (element : superScope.allElements) {
					if (element.EObjectOrProxy instanceof Table) {
						var table = element.EObjectOrProxy as Table
						table = EcoreUtil3.resolve(table, tableView.eResource.resourceSet) as Table
						if (table.tabletype instanceof TableGrid) {
							val tableGrid = table.tabletype as TableGrid
							val tableDtoDatasource = tableGrid?.source
							val rootTypeDto = tableDtoDatasource?.dtoSource
							if (operativeDto.name.equals(rootTypeDto.name)) {
								result.add(element)
							}
						} else if (table.tabletype instanceof TableTable) {
							result.add(element)
						}
					}
				}
			}
			return MapBasedScope.createScope(IScope.NULLSCOPE, result)
		}
	}

	def getScope_CCPerspectivePartStack_PERSPECTIVE_SELECTION__REF(PerspectiveSelection selectionView, EReference reference) {
		var superScope = super.getScope(selectionView, reference)
		var result = <IEObjectDescription>newArrayList
		// extract pure select tables
		for (element : superScope.allElements) {
			if (element.EObjectOrProxy instanceof Table) {
				var table = element.EObjectOrProxy as Table
				table = EcoreUtil3.resolve(table, selectionView.eResource.resourceSet) as Table
				if (table.tabletype instanceof TableSelection) {
					result.add(element)
				}
			}
		}
		superScope = MapBasedScope.createScope(IScope.NULLSCOPE, result)
		result = <IEObjectDescription>newArrayList
		// check for blip requirements
		var perspective = selectionView.eContainer
		while ((perspective != null) && !(perspective instanceof Perspective)) {
			perspective = perspective.eContainer
		}
		if ((perspective as Perspective)?.userTask == null) {
			return superScope
		} else {
			// Even not using the return value of this line it is mandatory to initialize lazy loading for bpmn
			EcoreUtil3.resolve((perspective as Perspective)?.process, selectionView.eResource.resourceSet) as Blip
			val humanTask = EcoreUtil3.resolve((perspective as Perspective)?.userTask, selectionView.eResource.resourceSet) as BlipUserTask
			val operativeDto = humanTask.operativeLDto
			if (operativeDto?.name == null) {
				return superScope
			} else {
				for (element : superScope.allElements) {
					if (element.EObjectOrProxy instanceof Table) {
						var table = element.EObjectOrProxy as Table
						table = EcoreUtil3.resolve(table, selectionView.eResource.resourceSet) as Table
						if (table.tabletype instanceof TableSelection) {
							result.add(element)
						}
					}
				}
			}
			return MapBasedScope.createScope(IScope.NULLSCOPE, result)
		}
	}

	def getScope_CCPerspectivePartStack_PERSPECTIVE_GRID__REF(PerspectiveGrid gridView, EReference reference) {
		val superScope = super.getScope(gridView, reference)
		var result = <IEObjectDescription>newArrayList
		for (element : superScope.allElements) {
			if (element.EObjectOrProxy instanceof Table) {
				var table = element.EObjectOrProxy as Table
				table = EcoreUtil3.resolve(table, gridView.eResource.resourceSet) as Table
				if (table.tabletype instanceof TableGrid) {
					result.add(element)
				}
			}
		}
		return MapBasedScope.createScope(IScope.NULLSCOPE, result)
	}

	def getScope_CCPerspectivePartStack_USER_TASK(Perspective perspective) {
		var result = <IEObjectDescription>newArrayList
		var blipProcess = perspective.process
		if (blipProcess != null) {
			for (item : blipProcess.items) {
				if (item instanceof BlipUserTask) {
					result.add(EObjectDescription.create(item.name, item))
				}
			}
		}
		return MapBasedScope.createScope(IScope.NULLSCOPE, result)
	}

	def getScope_CCPerspectivePartStack_selected_element(EObject object) {
		var result = <IEObjectDescription>newArrayList
		if (object instanceof PerspectivePartStack) {
			var stack = object as PerspectivePartStack
			for (part : stack.elements) {
				result.add(EObjectDescription.create(part.elementId, part))
			}
		}
		return MapBasedScope.createScope(IScope.NULLSCOPE, result)
	}

	def getScope_CCPerspectiveSashContainer_selected_element(EObject object) {
		var result = <IEObjectDescription>newArrayList
		if (object instanceof PerspectiveSashContainer) {
			var sash = object as PerspectiveSashContainer
			for (part : sash.elements) {
				result.add(EObjectDescription.create(part.elementId, part))
			}
		}
		return MapBasedScope.createScope(IScope.NULLSCOPE, result)
	}
}
