/**
 *                                                                            
 * 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 
 */
package org.eclipse.osbp.xtext.basic.ui;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Region;
import org.eclipse.xtext.Keyword;
import org.eclipse.xtext.nodemodel.ILeafNode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.parser.IParseResult;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.ui.editor.hover.IEObjectHoverProvider;
import org.eclipse.xtext.ui.editor.hover.IEObjectHoverProvider.IInformationControlCreatorProvider;
import org.eclipse.xtext.util.ITextRegion;
import org.eclipse.xtext.util.Pair;
import org.eclipse.xtext.util.Tuples;
import org.eclipse.xtext.xbase.ui.hover.XbaseDispatchingEObjectTextHover;



/**
 * <b>For the complete to-do-list to support keyword information for DSL editors <code>org.eclipse.osbp.xtext.basic.ui.BasicDSLUiModuleHelper</code></b>
 * <hr>
 * support for DSL grammar keywords
 * <hr>
 * <ul>
 * <li>Generate <code>{your}DSLEObjectHover</code>:
 * <pre>
 * public class {your}DSLEObjectHover extends BasicDSLEObjectHover {
 * 
 *     @Override
 *     public IEObjectHoverProvider getHoverProvider() {
 *         return {your}DSLEObjectHoverProvider.instance();
 *     }
 * }
 * </pre>
 * </li>
 * </ul>
 */
@SuppressWarnings("restriction")
public abstract class BasicDSLEObjectHover extends XbaseDispatchingEObjectTextHover {

	/**
	 * @return the hover provider of the DSL-UI-Bundle
	 */
	public abstract IEObjectHoverProvider getHoverProvider();
	
	/**
	 * necessary to support keyword hover info
	 * @see XbaseDispatchingEObjectTextHover#getHoverInfo(EObject,ITextViewer,IRegion)
	 */
	@Override
	public final Object getHoverInfo(EObject first, ITextViewer textViewer,
			IRegion hoverRegion) {
		if (first instanceof Keyword) {
			return getKeywordHoverInfo(first, textViewer, hoverRegion);
		}
		else {
			return super.getHoverInfo(first, textViewer, hoverRegion);
		}
	}

	/**
	 * try to do the default to get the keyword hover info, otherwise special handling
	 * @param keyword
	 * @param textViewer
	 * @param hoverRegion
	 * @return the hover info for the keyword given
	 */
	protected Object getKeywordHoverInfo(EObject keyword, ITextViewer textViewer, IRegion hoverRegion) {
		Object result = super.getHoverInfo(keyword, textViewer, hoverRegion);
		// --- if no default keyword info was found ---
		if	(result == null) {
			// --- check if the DSL-UI-Bundle has defined a hover provider (service doesn't work here)
			if (getHoverProvider()==null)
				return null;
			// --- let this provider do the work ---
			IInformationControlCreatorProvider creatorProvider = getHoverProvider().getHoverInfo(keyword, textViewer, hoverRegion);
			if (creatorProvider==null)
				return null;
			this.lastCreatorProvider = creatorProvider;
			result = lastCreatorProvider.getInfo();
		}
		return result;
	}

	/**
	 * necessary to support keyword hover info
	 * @see XbaseDispatchingEObjectTextHover#getXtextElementAt(XtextResource,int)
	 */
	@Override
	protected final Pair<EObject, IRegion> getXtextElementAt(XtextResource resource, int offset) {
		Pair<EObject, IRegion> result = super.getXtextElementAt(resource, offset);
		// --- if the default doesn't return any information ---
		if	(result == null) {
			IParseResult parseResult = resource.getParseResult();
			if (parseResult != null) {
				ILeafNode leafNode = NodeModelUtils.findLeafNodeAtOffset(parseResult.getRootNode(), offset);
				// --- check if this leaf node is a keyword 
				if	((leafNode != null) && (leafNode.getGrammarElement() instanceof Keyword)) {
					ITextRegion leafRegion = leafNode.getTextRegion();
					Keyword keyword = ((Keyword)leafNode.getGrammarElement());
					result = Tuples.create((EObject)keyword, (IRegion) new Region(leafRegion.getOffset(), leafRegion.getLength()));
				}
			}
		}
		return result;
	}
}
