package org.eclipse.osbp.xtext.perspective.scoping

import java.util.ArrayList
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.EReference
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.datainterchange.DataInterchangeGroup
import org.eclipse.osbp.xtext.dialogdsl.Dialog
import org.eclipse.osbp.xtext.oxtype.resource.EcoreUtil3
import org.eclipse.osbp.xtext.perspective.Perspective
import org.eclipse.osbp.xtext.perspective.PerspectiveDataInterchange
import org.eclipse.osbp.xtext.perspective.PerspectiveDialog
import org.eclipse.osbp.xtext.perspective.PerspectiveDslPackage
import org.eclipse.osbp.xtext.perspective.PerspectiveEvent
import org.eclipse.osbp.xtext.perspective.PerspectiveGrid
import org.eclipse.osbp.xtext.perspective.PerspectivePart
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.FilteringScope
import org.eclipse.xtext.scoping.impl.MapBasedScope
import org.eclipse.osbp.xtext.perspective.PerspectiveElement

/**
 * This class contains custom scoping description.
 * 
 * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#scoping
 * on how and when to use it.	
 */
class PerspectiveDslScopeProvider extends AbstractPerspectiveDslScopeProvider {

	@Override
	override IScope getScope(EObject context, EReference reference) {
		if (reference == PerspectiveDslPackage.Literals.PERSPECTIVE_SASH_CONTAINER__SELECTED_ELEMENT) {
			return getSashContainerSelectedElement(context)
		}
		else if (reference == PerspectiveDslPackage.Literals.PERSPECTIVE_EVENT__TARGET) {
			return getTargetParts(context)
		} 
		else if (reference == PerspectiveDslPackage.Literals.PERSPECTIVE_EVENT__ALLOWEDSOURCES) {
			return getAcceptedSenders(context)
		} 
		else if (reference == PerspectiveDslPackage.Literals.PERSPECTIVE_PART_STACK__SELECTED_ELEMENT) {
			return getPartStackSelectedElement(context)
		} else if (reference == PerspectiveDslPackage.Literals.PERSPECTIVE_PART_STACK__SYNCHRONIZE) {
			return getAllPartStacks(context)
		} else if (reference == PerspectiveDslPackage.Literals.PERSPECTIVE__USER_TASK) {
			return getUserTask(context as Perspective)
		} else if (reference == PerspectiveDslPackage.Literals.PERSPECTIVE_DIALOG__REF) {
			return getDialogRef(context as PerspectiveDialog, reference)
		} else if (reference == PerspectiveDslPackage.Literals.PERSPECTIVE_SELECTION__REF) {
			return getSelectionRef(context as PerspectiveSelection,	reference)
		} else if (reference == PerspectiveDslPackage.Literals.PERSPECTIVE_TABLE__REF) {
			return getTableRef(context as PerspectiveTable, reference)
		} else if (reference == PerspectiveDslPackage.Literals.PERSPECTIVE_GRID__REF) {
			return getGridRef(context as PerspectiveGrid, reference)
		} else if (reference == PerspectiveDslPackage.Literals.PERSPECTIVE_DATA_INTERCHANGE__REF) {
			return getDataRef(context as PerspectiveDataInterchange, reference)
		}
		return super.getScope(context, reference)
	}
	
	def getDialogRef(PerspectiveDialog dialogView, EReference reference) {
		val superScope = super.getScope(dialogView, reference)
		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 {
				return new FilteringScope(superScope, [
					if (it.EObjectOrProxy instanceof Dialog) {
						var dialog = it.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)) {
										return true
									}
								}
							}
						} else if (dialog.dto !== null) {
							if (operativeDto.name.equals(dialog.dto.name)) {
								return true
							}
						}
					}
					return false
				])
			}
		}
	}

	def getTableRef(PerspectiveTable tableView, EReference reference) {
		var superScope = super.getScope(tableView, reference)
		val FilteringScope scope = new FilteringScope(superScope, [
			if (it.EObjectOrProxy instanceof Table) {
				var table = it.EObjectOrProxy as Table
				table = EcoreUtil3.resolve(table, tableView.eResource.resourceSet) as Table
				return table.tabletype instanceof TableTable
			}
			return false
		])

		return scope
		
	}

	def getDataRef(PerspectiveDataInterchange dataView, EReference reference) {
		var superScope = super.getScope(dataView, reference)
		val FilteringScope scope = new FilteringScope(superScope, [
			if (it.EObjectOrProxy instanceof DataInterchangeGroup) {
				var group = it.EObjectOrProxy as DataInterchangeGroup
				group = EcoreUtil3.resolve(group, dataView.eResource.resourceSet) as DataInterchangeGroup
				return group instanceof DataInterchangeGroup
			}
			return false
		])
		return scope
	}

	def getSelectionRef(PerspectiveSelection selectionView,
		EReference reference) {
		var superScope = super.getScope(selectionView, reference)
		val FilteringScope scope = new FilteringScope(superScope, [
			if (it.EObjectOrProxy instanceof Table) {
				var table = it.EObjectOrProxy as Table
				table = EcoreUtil3.resolve(table, selectionView.eResource.resourceSet) as Table
				return table.tabletype instanceof TableSelection
			}
			return false
		])

		return scope
				
	}

	def getGridRef(PerspectiveGrid gridView, EReference reference) {
		val superScope = super.getScope(gridView, reference)

		val FilteringScope scope = new FilteringScope(superScope, [
			if (it.EObjectOrProxy instanceof Table) {
				var table = it.EObjectOrProxy as Table
				table = EcoreUtil3.resolve(table, gridView.eResource.resourceSet) as Table
				return table.tabletype instanceof TableGrid
			}
			return false
		])

		// check for blip requirements
		var perspective = gridView.eContainer
		while ((perspective !== null) && !(perspective instanceof Perspective)) {
			perspective = perspective.eContainer
		}
		if ((perspective as Perspective)?.userTask === null) {
			return scope
		} 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, gridView.eResource.resourceSet) as Blip
			val humanTask = EcoreUtil3.resolve((perspective as Perspective)?.userTask,
				gridView.eResource.resourceSet) as BlipUserTask
			val operativeDto = humanTask.operativeLDto
			if (operativeDto?.name === null) {
				return scope
			} else {
				val FilteringScope scopeBlip = new FilteringScope(superScope, [
					if (it.EObjectOrProxy instanceof Table) {
						var table = it.EObjectOrProxy as Table
						table = EcoreUtil3.resolve(table, gridView.eResource.resourceSet) as Table
							if (table.tabletype instanceof TableGrid) {
								val tableGrid = table.tabletype as TableGrid
								val tableDtoDatasource = tableGrid?.source
								val rootTypeDto = tableDtoDatasource?.dtoSource
								return operativeDto.name.equals(rootTypeDto.name)
							}
					}
					return false
				])
				return scopeBlip
			}

		}
		
	}

	def getUserTask(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 getPartStackSelectedElement(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 getAllPartStacks(EObject object) {
		var result = <IEObjectDescription>newArrayList
		if (object.eContainer instanceof PerspectiveElement) {
			var pers = object.eContainer as PerspectiveElement
			for (element : pers.elements) {
				if(element instanceof PerspectivePartStack && !element.equals(object)) {
					result.add(EObjectDescription.create(element.elementId, element))
				} 
			}
		}
		return MapBasedScope.createScope(IScope.NULLSCOPE, result)
	}
	
	def getAcceptedSenders(EObject object) {
		var result = <IEObjectDescription>newArrayList
		if (object instanceof PerspectiveEvent) {
			var temp = object.eContainer
			while (!(temp instanceof Perspective)) {
				temp = temp.eContainer
			}
			var target =  object.target
			// going through all perspective element top down
			for (element : (temp as Perspective).elements) {
				if(element instanceof PerspectivePart && element !== target){
					result.add(EObjectDescription.create(element.elementId, element))						
				}
				else if (element instanceof PerspectivePartStack) {
					var stack = object as PerspectivePartStack
					for (source : stack.elements) {
						if(source !== target ){
							result.add(EObjectDescription.create(source.elementId, source))
						}
					}
				}
				else if (element instanceof PerspectiveSashContainer) {
					findSashContainerParts(element, target, result, false)
				}
			}
		}
		return MapBasedScope.createScope(IScope.NULLSCOPE, result)
	}
	
	def getTargetParts(EObject object) {
		var result = <IEObjectDescription>newArrayList
		if (object instanceof PerspectiveEvent) {
			var temp = object.eContainer
			while (!(temp instanceof Perspective)) {
				temp = temp.eContainer
			}
			// going through all perspective element top down
			for (element : (temp as Perspective).elements) {
				if(element instanceof PerspectivePart){
					result.add(EObjectDescription.create(element.elementId, element))						
				}
				else if (element instanceof PerspectivePartStack) {
					var stack = object as PerspectivePartStack
					for (part : stack.elements) {
						result.add(EObjectDescription.create(part.elementId, part))
					}
				}
				else if (element instanceof PerspectiveSashContainer) {
					findSashContainerParts(element, null, result, true)
				}
			}
		}
		return MapBasedScope.createScope(IScope.NULLSCOPE, result)
	}
	
	
	def findSashContainerParts(PerspectiveSashContainer sash, PerspectivePart target, ArrayList<IEObjectDescription> result, boolean istarget){
		for(sashCelmnt : sash.elements){
			if(sashCelmnt instanceof PerspectivePart){
				if(istarget){
					result.add(EObjectDescription.create(sashCelmnt.elementId, sashCelmnt))
				}
				else if(sashCelmnt !== target){
					result.add(EObjectDescription.create(sashCelmnt.elementId, sashCelmnt))
				}
			}
			else if (sashCelmnt instanceof PerspectivePartStack) {
				var stack = sashCelmnt as PerspectivePartStack
				for (source : stack.elements) {
					if(istarget){
						result.add(EObjectDescription.create(source.elementId, source))
					}
					else if(source !== target){
						result.add(EObjectDescription.create(source.elementId, source))
					}
				}
			}
			else if (sashCelmnt instanceof PerspectiveSashContainer) {
				findSashContainerParts(sashCelmnt, target, result, istarget)
			}
		}
	}

	def getSashContainerSelectedElement(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)
	}
}
