/**
 *                                                                            
 *  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 2.0        
 *  which accompanies this distribution, and is available at                  
 *  https://www.eclipse.org/legal/epl-2.0/                                 
 *                                 
 *  SPDX-License-Identifier: EPL-2.0                                 
 *                                                                            
 *  Contributors:                                                      
 * 	   Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
 * 
 * 
 *  This copyright notice shows up in the generated Java code
 * 
 */

package org.eclipse.osbp.xtext.chart.scoping

import java.util.ArrayList
import java.util.List
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.EReference
import org.eclipse.osbp.xtext.chart.Chart
import org.eclipse.osbp.xtext.chart.ChartDSLPackage
import org.eclipse.osbp.xtext.chart.ChartDatamart
import org.eclipse.osbp.xtext.datamartdsl.AxisEnum
import org.eclipse.osbp.xtext.datamartdsl.DatamartAxis
import org.eclipse.osbp.xtext.datamartdsl.DatamartCube
import org.eclipse.osbp.xtext.datamartdsl.DatamartCubeAxis
import org.eclipse.osbp.xtext.datamartdsl.DatamartDefinition
import org.eclipse.osbp.xtext.datamartdsl.DatamartEntity
import org.eclipse.osbp.xtext.datamartdsl.DatamartMember
import org.eclipse.osbp.xtext.datamartdsl.DatamartOwner
import org.eclipse.osbp.xtext.datamartdsl.DatamartTask
import org.eclipse.osbp.xtext.oxtype.resource.EcoreUtil3
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.action.ActionToolbar
import org.eclipse.osbp.xtext.action.ActionToolbarItem
import org.eclipse.osbp.xtext.action.ActionButton
import org.eclipse.osbp.xtext.action.ChartActionEnum
import org.eclipse.osbp.xtext.action.ActionChart
import org.eclipse.osbp.xtext.action.ActionInclude
import org.eclipse.osbp.xtext.action.ActionFunction

class ChartDSLScopeProvider extends AbstractChartDSLScopeProvider {
	@Override
	override IScope getScope(EObject context, EReference reference) {
		if (reference == ChartDSLPackage.Literals.CHART_AXIS__AXIS) {
			return getScope_Chart_Axis_axis(context)
		} else if (reference == ChartDSLPackage.Literals.CHART_DATAMART__DATAMART_REF) {
			return getScope_Chart_DatamartRef(context as ChartDatamart, reference)
		} else if (reference == ChartDSLPackage.Literals.CHART__TOOLBAR) {
			return getScope_Chart_Toolbar(context as Chart, reference)
		}
		return super.getScope(context, reference)
	}
	
	def IScope getScope_Chart_Toolbar(Chart chart, EReference reference) {
		var superScope = super.getScope(chart, reference)
		return new FilteringScope(superScope, [
			if (it.EObjectOrProxy instanceof ActionToolbar) {
				var toolbar = it.EObjectOrProxy as ActionToolbar
				toolbar = EcoreUtil3.resolve(toolbar, chart.eResource.resourceSet) as ActionToolbar
				return toolbar.filterToolbarScopeCondition
			}
			return false
		])
	}

	private def filterToolbarScopeCondition (ActionToolbar toolbar) {
		return toolbar.iterateToolbarScopeCondition
	}
	
	private def boolean iterateToolbarScopeCondition(ActionToolbar toolbar) {
		var allItemsOfChart = true
		if (toolbar !== null) {
			for(item:toolbar.actions) {
				if(item instanceof ActionButton) {
					if(!(item.command.actionType instanceof ActionChart) && !(item.command.actionType instanceof ActionFunction)) {
						allItemsOfChart = false
					}
				} else if(item instanceof ActionInclude) {
					allItemsOfChart = (item as ActionInclude).include.iterateToolbarScopeCondition 
				}
				
			}
		}
		return allItemsOfChart
	}

	def IScope getScope_Chart_Axis_axis(EObject object) {
		var result = <IEObjectDescription>newArrayList
		var eObj = object
		while (!(eObj instanceof ChartDatamart)) {
			eObj = eObj.eContainer
		}
		if (eObj !== null) {
			var datamart = (eObj as ChartDatamart).datamartRef
			if (datamart !== null && datamart.source !== null) {
				if (datamart.source instanceof DatamartCube) {
					for (axis : (datamart.source as DatamartCube).axisslicer) {
						if (axis instanceof DatamartCubeAxis) {
							var literal = (axis as DatamartCubeAxis).axis.name.literal
							result.add(EObjectDescription.create(literal, (axis as DatamartCubeAxis).axis))
						}
					}
				} else if (datamart.source instanceof DatamartEntity) {
					getEntityAxes(datamart.source as DatamartEntity, result)
				} else if (datamart.source instanceof DatamartTask) {
					result.add(EObjectDescription.create(AxisEnum.COLUMNS.literal, (datamart.source as DatamartTask)))
					result.add(EObjectDescription.create(AxisEnum.ROWS.literal, (datamart.source as DatamartTask)))
				}
			}
		}
		return MapBasedScope.createScope(IScope.NULLSCOPE, result)
	}
	
	def IScope getScope_Chart_DatamartRef(ChartDatamart chartDatamart, EReference reference) {
		var superScope = super.getScope(chartDatamart, reference)
		return new FilteringScope(superScope, [
					if (it.EObjectOrProxy instanceof DatamartDefinition) {
						var datamart = it.EObjectOrProxy as DatamartDefinition
						datamart = EcoreUtil3.resolve(datamart, chartDatamart.eResource.resourceSet) as DatamartDefinition
						return datamart.filterScopeCondition
					}
					return false
				])
		
	}

	def void getEntityAxes(DatamartEntity entity, ArrayList<IEObjectDescription> result) {
		for (datamartAxis : entity.createEntityAxesList) {
			result.add(EObjectDescription.create(datamartAxis.name.literal, datamartAxis))
		}
	}
	
	private def filterScopeCondition (DatamartDefinition datamart) {
		if (datamart !== null && datamart.source !== null) {
			if (datamart.source instanceof DatamartCube) {
				for (axis : (datamart.source as DatamartCube).axisslicer) {
					if (axis instanceof DatamartCubeAxis) {
						return true
					}
				}
			} else if (datamart.source instanceof DatamartEntity) {
				if ((datamart.source as DatamartEntity).createEntityAxesList.size > 0){
					return true
				}
			} else if (datamart.source instanceof DatamartTask) {
				return true
			}
		}
		return false
	}
	
	private def List<DatamartAxis> createEntityAxesList(DatamartEntity entity) {
		var datamartAxisList = newArrayList()
		for (navigation : entity.navigations) {
			if (navigation instanceof DatamartMember) {
				datamartAxisList.addAll((navigation as DatamartMember).datamartEntity.createEntityAxesList)
				for (attribute : (navigation as DatamartMember).datamartEntity.attributes) {
					datamartAxisList.add(attribute.axis)
				}
			}
			if (navigation instanceof DatamartOwner) {
				datamartAxisList.addAll((navigation as DatamartOwner).datamartEntity.createEntityAxesList)
				for (attribute : (navigation as DatamartOwner).datamartEntity.attributes) {
					datamartAxisList.add(attribute.axis)
				}
			}
		}
		for (attribute : entity.attributes) {
			datamartAxisList.add(attribute.axis)
		}
		datamartAxisList
	}

}
