/**
 *                                                                            
 *  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.strategy.jvmmodel

import javax.inject.Inject
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddable
import org.eclipse.osbp.ecview.core.common.model.core.YFocusable
import org.eclipse.osbp.ecview.core.common.model.core.YLayout
import org.eclipse.osbp.ecview.core.common.services.IWidgetAssocationsService
import org.eclipse.osbp.ecview.^extension.api.IFocusingStrategy
import org.eclipse.osbp.ecview.^extension.api.IFocusingStrategyProvider
import org.eclipse.osbp.ecview.^extension.model.YStrategyLayout
import org.eclipse.osbp.runtime.common.keystroke.KeyStrokeDefinition
import org.eclipse.osbp.utils.annotation.CommonUtils
import org.eclipse.osbp.xtext.strategy.FocusingEnum
import org.eclipse.osbp.xtext.strategy.FocusingStrategy
import org.eclipse.osbp.xtext.strategy.StrategyPackage
import org.eclipse.osbp.xtext.strategy.constants.StrategyConstants
import org.eclipse.xtext.common.types.JvmField
import org.eclipse.xtext.common.types.JvmGenericType
import org.eclipse.xtext.common.types.JvmVisibility
import org.eclipse.xtext.common.types.util.TypeReferences
import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor
import org.eclipse.xtext.xbase.jvmmodel.JvmAnnotationReferenceBuilder
import org.eclipse.xtext.xbase.jvmmodel.JvmTypeReferenceBuilder
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder
import org.osgi.service.component.annotations.Component
import org.eclipse.osbp.ecview.core.common.model.core.YElement
import org.eclipse.osbp.ecview.core.common.model.core.YView
import org.eclipse.xtext.xbase.typesystem.references.LightweightTypeReference

class StrategyDSLFocusingStrategyCreator {
	@Inject extension JvmTypesBuilder
	@Inject extension StrategyConstants
	@Inject extension CommonUtils
	@Inject
	private TypeReferences references;
	
	
	private JvmAnnotationReferenceBuilder _annotationTypesBuilder;
	private JvmTypeReferenceBuilder _typeReferenceBuilder;
	
	def void createFocusingStrategy(StrategyPackage pckg, FocusingStrategy focusingStrategy, IJvmDeclaredTypeAcceptor acceptor, JvmAnnotationReferenceBuilder annotationTypesBuilder, JvmTypeReferenceBuilder typeReferenceBuilder){
		_annotationTypesBuilder = annotationTypesBuilder
		_typeReferenceBuilder = typeReferenceBuilder
		
		// creation of the IFocusingStrategy implementation
		var clsStrategy = focusingStrategy.toClass('''«pckg.name».«focusingStrategy.strategyClassName»''')
			clsStrategy.getSuperTypes().add(_typeReferenceBuilder.typeRef(typeof(IFocusingStrategy)))
			acceptor.accept(clsStrategy,
				[
					//							it.addTranslatorClassesFields(dialog, null, true)
					//							it.addTranslatorBindingFields(dialog)
					it.toFields(focusingStrategy)
					it.toOperations(focusingStrategy)
				])
		
		// creation of the IFocusingStrategyProvider implementation
		var clsProvider = focusingStrategy.toClass('''«pckg.name».«focusingStrategy.strategyProviderClassName»''')
			clsProvider.getSuperTypes().add(_typeReferenceBuilder.typeRef(typeof(IFocusingStrategyProvider)))
			acceptor.accept(clsProvider,
				[
					var annotationRef = _annotationTypesBuilder.annotationRef(typeof(Component))
					// create the Boolean type
//					val booleanDeclaredType = references.findDeclaredType(typeof(Boolean), focusingStrategy) as JvmDeclaredType
					annotationRef.addAnnAttr(focusingStrategy, /*references, booleanDeclaredType, */"immediate", true)
//					val classDeclaredType = references.findDeclaredType(typeof(IFocusingStrategyProvider), focusingStrategy) as JvmDeclaredType
					annotationRef.addAnnAttr(focusingStrategy, /*references, classDeclaredType, */"service", _typeReferenceBuilder.typeRef(IFocusingStrategyProvider))
					
					var propContent = '''ecview.focusing.id=«focusingStrategy.ecviewFocusingId»'''
					annotationRef.addAnnAttr(focusingStrategy, /*references, */"property", propContent)
					annotations += annotationRef
//					val componentAnnoParams = newArrayList("immediate=true", "service = IFocusingStrategyProvider.class");
//					annotations += _annotationTypesBuilder.annotationRef(typeof(Component),componentAnnoParams)
					//							it.addTranslatorClassesFields(dialog, null, true)
					//							it.addTranslatorBindingFields(dialog)
					it.toProviderFields(focusingStrategy)
					it.toProviderOperations(focusingStrategy)
				])
		
	}
	
	// Strategy Fields
	def void toFields(JvmGenericType type, FocusingStrategy focusingStrategy) {
		var JvmField field = null
		// create index
		field = focusingStrategy.toField('''down''', _typeReferenceBuilder.typeRef(boolean))
		field.visibility = JvmVisibility.PRIVATE
		field.documentation = '''Now fix, but it has to come from the StrategyDSL'''
		field.initializer = ([append('''false''')])
		type.members += field
	}
	
	// Strategy Methods
	def void toOperations(JvmGenericType type, FocusingStrategy focusingStrategy){
			// create focus
			type.members += focusingStrategy.toMethod("focus", _typeReferenceBuilder.typeRef(Void::TYPE),
				[
					annotations += _annotationTypesBuilder.annotationRef(typeof(Override))
					visibility = JvmVisibility.PUBLIC
					parameters += focusingStrategy.toParameter("source", _typeReferenceBuilder.typeRef(Object))
					parameters += focusingStrategy.toParameter("target", _typeReferenceBuilder.typeRef(Object))
					parameters += focusingStrategy.toParameter("yLayout", _typeReferenceBuilder.typeRef(YStrategyLayout))
					body = [append('''
					YView yView = yLayout.getView();
					IViewContext context = ModelUtil.getViewContext(yView);
					IWidgetAssocationsService<Object, ? extends YElement> service = context.getService(IWidgetAssocationsService.ID);
					YEmbeddable yCurrentFocus = (YEmbeddable) service.getModelElement(target);
					
					if (yCurrentFocus == null) {
						findNextFocusableForCustomComponents(yView, target, service);
					} else {
						YEmbeddable yNextFocus = findElementToFocus(yCurrentFocus, service);
						yView.setCurrentFocus((YFocusable) yNextFocus);
					}
''')]
				])
		
			// create new findElementToFocus
			type.members += focusingStrategy.toMethod("findElementToFocus", _typeReferenceBuilder.typeRef(YEmbeddable),
				[
					visibility = JvmVisibility.PROTECTED
					parameters += focusingStrategy.toParameter("yElement", _typeReferenceBuilder.typeRef(YEmbeddable))
					parameters += focusingStrategy.toParameter("service", _typeReferenceBuilder.typeRef(IWidgetAssocationsService,_typeReferenceBuilder.typeRef(Object),_typeReferenceBuilder.wildcardExtends(_typeReferenceBuilder.typeRef(YElement))))
					body = [append(focusingStrategy.findElementToFocus)]
				])
				
			// create getKeyStrokeDefinition
			type.members += focusingStrategy.toMethod("getKeyStrokeDefinition", _typeReferenceBuilder.typeRef(KeyStrokeDefinition),
				[
					annotations += _annotationTypesBuilder.annotationRef(typeof(Override))
					visibility = JvmVisibility.PUBLIC
					body = [append(focusingStrategy.keyStrokeDefinitionBody)]
				])
				
			// create findNextFocusableColumnIdx
			type.members += focusingStrategy.toMethod("findNextFocusableColumnIdx", _typeReferenceBuilder.typeRef(int),
				[
					visibility = JvmVisibility.PRIVATE
					parameters += focusingStrategy.toParameter("focusable", _typeReferenceBuilder.typeRef(YFocusable))
					body = [append(focusingStrategy.findColumnIdxFocusable)]
				])
		
			// create findNextColumnIdx
			type.members += focusingStrategy.toMethod("findNextColumnIdx", _typeReferenceBuilder.typeRef(int),
				[
					visibility = JvmVisibility.PRIVATE
					parameters += focusingStrategy.toParameter("idx", _typeReferenceBuilder.typeRef(int))
					parameters += focusingStrategy.toParameter("columns", _typeReferenceBuilder.typeRef(int))
					body = [append(focusingStrategy.findColumnIdx)]
				])
		
				// create new findNextFocusableForCustomComponents
			type.members += focusingStrategy.toMethod("findNextFocusableForCustomComponents", _typeReferenceBuilder.typeRef(Void::TYPE),
				[
					visibility = JvmVisibility.PRIVATE
					parameters += focusingStrategy.toParameter("yView", _typeReferenceBuilder.typeRef(YView))
					parameters += focusingStrategy.toParameter("currentComponent", _typeReferenceBuilder.typeRef(Object))
					parameters += focusingStrategy.toParameter("service", _typeReferenceBuilder.typeRef(IWidgetAssocationsService,_typeReferenceBuilder.typeRef(Object),_typeReferenceBuilder.wildcardExtends(_typeReferenceBuilder.typeRef(YElement))))
					body = [append(focusingStrategy.findNextFocusableForCustomComponents)]
				])
				
	}
	
	def findNextFocusableForCustomComponents(FocusingStrategy strategy){
		'''
		Component currentCustomComponent = ((Component) currentComponent).getParent();
		while (currentCustomComponent != null && !(currentCustomComponent instanceof ICustomComponentFocusable) && currentCustomComponent instanceof Component) {
			currentCustomComponent = currentCustomComponent.getParent();
		}
		if(currentCustomComponent != null){
			
		
		«IF strategy.focus.literal.equals(FocusingEnum.FORWARD.literal)»
			if (((ICustomComponentFocusable)currentCustomComponent).isLastFocusable(currentComponent)) {
		«ELSEIF strategy.focus.literal.equals(FocusingEnum.BACKWARD.literal)»
			if (((ICustomComponentFocusable)currentCustomComponent).isFirstFocusable(currentComponent)) {
		«ENDIF»		
				YEmbeddable yCurrentFocus = (YEmbeddable) service.getModelElement(currentCustomComponent);
			
				YEmbeddable yNextFocus = findElementToFocus(yCurrentFocus, service);
				yView.setCurrentFocus((YFocusable) yNextFocus);
			}
			else {
				YEmbeddable yCurrentFocus = (YEmbeddable) service.getModelElement(currentCustomComponent);
				yView.setCurrentFocus((YFocusable) yCurrentFocus);
			}
		}
		'''
	}
	
	def findColumnIdxFocusable(FocusingStrategy focusingStrategy)'''
			return findNextColumnIdx(focusable.getLayoutIdx(), focusable.getLayoutColumns());
	'''
		
	
	def findColumnIdx(FocusingStrategy focusingStrategy)'''
		if (idx % columns > columns) {
			return findNextColumnIdx(idx % columns, columns);
		}
		return idx % columns;
	'''
		
	def getFindElementToFocus(FocusingStrategy focusingStrategy)'''
		if (yElement == null) {
			return null;
		}
		if (yElement instanceof YFocusable) {
			YEmbeddable nextFocusElement = null;
			int idx = ((YFocusable) yElement).getLayoutIdx();
			// desired focus strategy to the next element is 'down'
			if (down) {
				«IF focusingStrategy.focus.literal.equals(FocusingEnum.FORWARD.literal)»
				// next element below on forward focus is adding the number of layout columns to the current index 
				idx = idx + ((YFocusable) yElement).getLayoutColumns();
				nextFocusElement = (YEmbeddable) service.getModelElement(idx);
				if (nextFocusElement == null) {
					// if no element was found to focus search for elements in the next column
					nextFocusElement = (YEmbeddable) service.getModelElement(findNextFocusableColumnIdx(((YFocusable) yElement)) + 1);
				}
				«ELSEIF focusingStrategy.focus.literal.equals(FocusingEnum.BACKWARD.literal)»
				if (idx == 1) {
					// the current position is the first focusable element so the next focusable element backwards is
					// the last focusable element of the last layout column
					// finding the index of the last focusable element
					«focusingStrategy.findLastElementToFocus»
					// the last position of a focusable element in the last layout column
					// subtracting the modulo operation between the last element index and the number of layout columns from the last element index
					lastElementIdx = lastElementIdx - (lastElementIdx % ((YFocusable) yElement).getLayoutColumns());
					nextFocusElement = (YEmbeddable) service.getModelElement(lastElementIdx);
				} else {
					// next element above on backward focus is subtracting the number of layout columns to the current index
					int prevElementIdx = idx - ((YFocusable) yElement).getLayoutColumns();
					nextFocusElement = (YEmbeddable) service.getModelElement(prevElementIdx);
					if (nextFocusElement == null) {
						// if no element was found to focus the current index is the first element of the current column
						// so search for the last element in the previous column
						// go to the index of the first element of the previous column
						idx = idx - 1;
						// find the last focusable element in this column
						while ((YEmbeddable) service.getModelElement(idx) != null) {
							nextFocusElement = (YEmbeddable) service.getModelElement(idx);
							idx = idx + ((YFocusable) yElement).getLayoutColumns();
						}
					}
				}
				«ENDIF»
				// desired focus strategy to the next element is 'right'
			} else {
				«IF focusingStrategy.focus.literal.equals(FocusingEnum.FORWARD.literal)»
				nextFocusElement = (YEmbeddable) service.getModelElement(++idx);
				«ELSEIF focusingStrategy.focus.literal.equals(FocusingEnum.BACKWARD.literal)»
				nextFocusElement = (YEmbeddable) service.getModelElement(--idx);
				«ENDIF»
				if (nextFocusElement == null) {
					«IF focusingStrategy.focus.literal.equals(FocusingEnum.FORWARD.literal)»
					// if no element was found to focus go back to the first element
					nextFocusElement = (YEmbeddable) service.getModelElement(0);
					«ELSEIF focusingStrategy.focus.literal.equals(FocusingEnum.BACKWARD.literal)»
					// if no element was found to focus go back to the last focusable element
					«focusingStrategy.findLastElementToFocus»
					nextFocusElement = (YEmbeddable) service.getModelElement(lastElementIdx);
					«ENDIF»
				}
			}
			if (nextFocusElement instanceof YField) {
				YField field = ((YField) nextFocusElement);
				if (!field.isEditable() || !field.isEnabled() || !field.isVisible()) {
					nextFocusElement = findElementToFocus(nextFocusElement, service);
				}
			}
			return nextFocusElement;
		}
		return null;'''
	
	def getFindLastElementToFocus(FocusingStrategy focusingStrategy) '''
		// finding the index of the last focusable element
		int lastElementIdx = 0;
		for (YElement element : service.getModelElements()) {
			if (element instanceof YFocusable) {
				int layoutIdx = ((YFocusable) element).getLayoutIdx();
				lastElementIdx = lastElementIdx < layoutIdx ? layoutIdx : lastElementIdx;
			}
		}'''
	
	def String findNextElementToFocusInSingularLayout(FocusingStrategy focusingStrategy){
		return '''
    	int idx = getIndexToFocus(yParent, index);
    	return yParent.getElements().get(idx);'''
	}
	
	def String findNextElementToFocusInAComplexLayout(FocusingStrategy focusingStrategy){
		return '''
			int layoutElementListSize = layout.getElements().size();
			// in case of more than one element
			if (layoutElementListSize > 0){
				for (int i = 0; i < layoutElementListSize; i++) {
					YEmbeddable layoutElement = layout.getElement(i);
					// in case that the layout elements are again layouts
					if (layoutElement instanceof YLayout){
						// in case that the layout containing the focus event sending element is found
						if (yParent.equals(layoutElement)){
							«IF focusingStrategy.focus.literal.equals(FocusingEnum.FORWARD.literal)»
							if (i!=layoutElementListSize-1){
								i = i+1;
							} else {
								i = 0;
							}
							// find next layout
							YLayout yParentTemp = (YLayout)layout.getElement(i);
							// get the first element of the layout
							return yParentTemp.getElement(0);
							«ELSEIF focusingStrategy.focus.literal.equals(FocusingEnum.BACKWARD.literal)»
							if (i!=0){
								i = i-1;
							} else {
								i = layoutElementListSize - 1;
							}
							// find next layout
							YLayout yParentTemp = (YLayout)layout.getElement(i);
							// get the last element of the layout
							int idx = yParentTemp.getElements().size() - 1;
							return yParentTemp.getElement(idx);
							«ENDIF»
						} else {
							YEmbeddable yEmbeddable = findNextElementToFocusInAComplexLayout(yParent, (YLayout)layoutElement, index);
							// without this if statement the for loop will be broken.
							if (yEmbeddable!=null){
								return yEmbeddable;
							}
						}
					}
				}
			} else {
				YEmbeddable layoutElement = layout.getElement(0);
				// in case that the layout containing the focus event sending element is found
				if (yParent.equals(layoutElement)){
					return findNextElementToFocusInSingularLayout(yParent, index);
				} else {
					// in case that the layout elements are again layouts
					if (layoutElement instanceof YLayout){
						return findNextElementToFocusInAComplexLayout(yParent, (YLayout)layoutElement, index);
					}
				}
			}
			return null;'''
	}
	
	def String getIndexToFocus(FocusingStrategy focusingStrategy){
		var body = '''int index = idx;'''
		if (focusingStrategy.focus.literal.equals(FocusingEnum.FORWARD.literal)){
			body = '''«body»«forwardFocusBodyCode»'''
		} else if (focusingStrategy.focus.literal.equals(FocusingEnum.BACKWARD.literal)){
			body = '''«body»«backwardFocusBodyCode»'''
		}
		return '''«body»return index;'''
	}
	
	def String getKeyStrokeDefinitionBody(FocusingStrategy focusingStrategy){
		var body = ''''''
		var modifierKeysLength = 0
		if (focusingStrategy.modifierKeys!=null){
			modifierKeysLength = focusingStrategy.modifierKeys.length
		}
		body = '''«body»int[] modifierKeys = new int[«modifierKeysLength»];'''
		if (!focusingStrategy.modifierKeys.empty){
			var idx = 0
			for (modifierKey : focusingStrategy.modifierKeys){
				body = '''«body»
				modifierKeys[«idx»] = ModifierKey.«modifierKey»;'''
				idx++
			}
		}
		if (focusingStrategy.keyCode!=null && !focusingStrategy.keyCode.empty){
				body = '''«body»
				KeyStrokeDefinition def = new KeyStrokeDefinition("", KeyCode.«focusingStrategy.keyCode», modifierKeys);
				return def;'''
		}
		return body
	}
	
	def getForwardFocusBodyCode() '''
		if (index == yParent.getElements().size() - 1) {
			// element is the last -> Start again
			index = 0;
		} else {
			// use the next element
			index = index + 1;
		}
	'''
	
	def getBackwardFocusBodyCode() '''
		if (index == 0) {
			// element is the first -> Start again
			index = yParent.getElements().size() - 1;
		} else {
			// use the previous element
			index = index - 1;
		}
	'''
	
	// Provider Methods
	/**
	 * <p>build the class variables.</p> 
	 *
	 */
	def void toProviderFields(JvmGenericType type, FocusingStrategy focusingStrategy){
		var JvmField field = null

		// create logger
		field = focusingStrategy.toField("ID", _typeReferenceBuilder.typeRef(String))[
			setInitializer([append('''"«focusingStrategy.ecviewFocusingId»"''')])]
		field.final = true
		field.static = true
		type.members += field
		
	}
	
	def void toProviderOperations(JvmGenericType type, FocusingStrategy focusingStrategy){
					// create focus
			type.members += focusingStrategy.toMethod("getStrategy", _typeReferenceBuilder.typeRef(IFocusingStrategy),
				[
					annotations += _annotationTypesBuilder.annotationRef(typeof(Override))
					visibility = JvmVisibility.PUBLIC
					body = [append('''return new «focusingStrategy.strategyClassName»();''')]
				])
	}
	
	// Helper Methods
	def getStrategyClassName(FocusingStrategy focusingStrategy)'''«focusingStrategy.name»«focusingStrategy.focus.literal»«FOCUSING_STRATEGY_PREFIX»'''
	def getStrategyProviderClassName(FocusingStrategy focusingStrategy)'''«focusingStrategy.name»«focusingStrategy.focus.literal»«FOCUSING_STRATEGY_PROVIDER_PREFIX»'''
}
