/*******************************************************************************
 * Copyright (c) 2006 Oracle Corporation.
 * 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:
 *    Gerry Kessler/Oracle - initial API and implementation
 *    
 ********************************************************************************/

package org.eclipse.jst.jsf.ui.internal.contentassist;

import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.jface.text.contentassist.IContentAssistProcessor;
import org.eclipse.jface.text.contentassist.IContextInformation;
import org.eclipse.jface.text.contentassist.IContextInformationValidator;
import org.eclipse.jst.jsf.context.resolver.structureddocument.internal.ITextRegionContextResolver;
import org.eclipse.jst.jsf.context.resolver.structureddocument.internal.provisional.IDOMContextResolver;
import org.eclipse.jst.jsf.context.resolver.structureddocument.internal.provisional.IStructuredDocumentContextResolverFactory;
import org.eclipse.jst.jsf.context.resolver.structureddocument.internal.provisional.ITaglibContextResolver;
import org.eclipse.jst.jsf.context.structureddocument.internal.provisional.IStructuredDocumentContext;
import org.eclipse.jst.jsf.context.structureddocument.internal.provisional.IStructuredDocumentContextFactory;
import org.eclipse.jst.jsf.metadataprocessors.internal.provisional.MetaDataEnabledProcessingFactory;
import org.eclipse.jst.jsf.metadataprocessors.internal.provisional.features.IPossibleValue;
import org.eclipse.jst.jsf.metadataprocessors.internal.provisional.features.IPossibleValues;
import org.eclipse.jst.jsf.ui.internal.JSFUiPlugin;
import org.eclipse.swt.graphics.Image;
import org.eclipse.wst.sse.ui.internal.contentassist.CustomCompletionProposal;
import org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap;
import org.eclipse.wst.xml.core.internal.contentmodel.modelquery.ModelQuery;
import org.eclipse.wst.xml.core.internal.modelquery.ModelQueryUtil;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
import org.eclipse.wst.xml.ui.internal.contentassist.XMLRelevanceConstants;
import org.eclipse.wst.xml.ui.internal.taginfo.MarkupTagInfoProvider;
import org.osgi.framework.Bundle;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

/**
 * The content assist processor for non-EL attribute values.
 * 
 * @author Gerry Kessler - Oracle
 * 
 */
public class JSFContentAssistProcessor implements IContentAssistProcessor {
	private ITextRegionContextResolver resolver;
	private ITaglibContextResolver tlResolver;
	private String defaultAdditionalInfo;

	private String defaultIconPath = "/icons/attr_val.gif";
	
	private ImageDescriptor defaultAttrValImgDesc;
	
	private MarkupTagInfoProvider fInfoProvider;

	/**
	 * @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer,
	 *      int)
	 */
	public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer,
			int documentPosition) {
		List proposals = new ArrayList();
		IStructuredDocumentContext context = IStructuredDocumentContextFactory.INSTANCE
				.getContext(viewer, documentPosition);

		if (context != null) {
			resolver = IStructuredDocumentContextResolverFactory.INSTANCE
					.getTextRegionResolver(context);

			if (resolver != null) {
				final String regionType = resolver.getRegionType();

				if (regionType != null
						&& regionType.equals(DOMRegionContext.XML_TAG_ATTRIBUTE_VALUE)) {
					
					tlResolver = IStructuredDocumentContextResolverFactory.INSTANCE
							.getTaglibContextResolver(context);

					if (tlResolver != null) {
						
						Attr attr = getAttribute(context);
						if (attr != null) {
							Node tagElement = attr.getOwnerElement();
							if (tagElement != null) {
								String uri = tlResolver.getTagURIForNodeName(tagElement);
								if (uri != null) {									
									proposals = createProposals(context, uri, tagElement, attr);
								}
							}
						}
					}
				}
			}
		}

		return (ICompletionProposal[]) proposals
				.toArray(new ICompletionProposal[0]);
	}

	private String getDefaultAdditionalInfo(Node tagElement, Attr attr) {
		if (defaultAdditionalInfo == null){
			CMElementDeclaration elementNode = getCMElementDeclaration(tagElement);
			if (elementNode != null){
				CMAttributeDeclaration attrNode = getCMAttributeDeclaration(elementNode, attr);
				if (attrNode != null)
					defaultAdditionalInfo = getInfoProvider().getInfo(attrNode);
			}
		}
		return defaultAdditionalInfo;
	}
	
	private CMElementDeclaration getCMElementDeclaration(Node node) {
		CMElementDeclaration result = null;
		if (node.getNodeType() == Node.ELEMENT_NODE) {
			ModelQuery modelQuery = ModelQueryUtil.getModelQuery(node.getOwnerDocument());
			if (modelQuery != null)
				result = modelQuery.getCMElementDeclaration((Element) node);
		}
		return result;
	}

	private CMAttributeDeclaration getCMAttributeDeclaration(CMElementDeclaration tagElement, Attr attr) {
		CMNamedNodeMap attrs = tagElement.getAttributes();
		for (Iterator it = attrs.iterator();it.hasNext();){
			CMAttributeDeclaration CMAttr = (CMAttributeDeclaration)it.next();
			if (CMAttr.getAttrName().equals(attr.getName()))
				return CMAttr;
		}
		return null;
	}
	
	private MarkupTagInfoProvider getInfoProvider() {
		if (fInfoProvider == null) {
			fInfoProvider = new MarkupTagInfoProvider();
		}
		return fInfoProvider;
	}
	
	private List createProposals(IStructuredDocumentContext context, String uri, Node tagElement, Attr attr) {
		List ret = new ArrayList();
		List processors = MetaDataEnabledProcessingFactory.getInstance()
						.getAttributeValueRuntimeTypeFeatureProcessors(
								IPossibleValues.class, context, uri,
								tagElement.getLocalName(), attr.getLocalName());
		
		if (processors != null) {
			for (int i = 0; i < processors.size(); i++) {
				IPossibleValues p = (IPossibleValues) processors.get(i);
				ret.addAll(createProposals(p, tagElement, attr));
			}
		}
		return ret;
	}

	private List createProposals(IPossibleValues p, Node tagElement, Attr attr) {
		List ret = new ArrayList();
		defaultAdditionalInfo = null;
		Iterator it = p.getPossibleValues().iterator();
		while (it.hasNext()) {
			IPossibleValue val = (IPossibleValue) it.next();
			if (val != null){ //just in case...
				ICompletionProposal proposal = new CustomCompletionProposal(
						val.getValue(), 		//replacement text
						getReplacementOffset(), //replacementOffset
						getReplacementLength(), //replacementLength
						getCursorPosition(val), //cursor pos
						getImage(val), 			//image
						val.getDisplayValue(), 	//display value
						null, 					//IContextInformation
						getAdditionalInfo(val,tagElement,attr), //addditional info
						XMLRelevanceConstants.R_JSP_ATTRIBUTE_VALUE,	//relevance
						true);					//updateReplace
	
				ret.add(proposal);
			}
		}
		return ret;
	}


	private String getAdditionalInfo(IPossibleValue val, Node tagElement, Attr attr) {
		if (val.getAdditionalInformation() != null)
			return val.getAdditionalInformation();
		
		return 	getDefaultAdditionalInfo(tagElement, attr);
	}

	private int getReplacementLength() {
		return resolver.getRegionText().length() - 2;
	}

	private int getCursorPosition(IPossibleValue val) {
		//Something changed in 1.5RC2 CustomCompletionProposal 
		//it appears that the cursor position is now relative to where it is currently
		//rather than relative to document
		
		//return getReplacementOffset() + val.getValue().length();
		return val.getValue().length();
	}

	private int getReplacementOffset() {
		return resolver.getStartOffset() + 1;
	}

	private Image getImage(IPossibleValue val) {
		ImageDescriptor icon = val.getIcon();		
		if (icon == null || icon.equals("")){
			return getDefaultAttributeValueImage();
		}
		
		return getOrCreateImage(icon);		
	}

	private Image getOrCreateImage(ImageDescriptor icon) {
		if (icon == null)
			return null;
			
		Image img = JSFUiPlugin.getDefault().getImageRegistry().get(icon.toString());
		if (img == null){
			try {
				img = icon.createImage();
				JSFUiPlugin.getDefault().getImageRegistry().put(icon.toString(), img);
			} catch (RuntimeException e) {
                // empty block; C.B: handle exception?
			}
		}
		return img;
	}

	private Image getDefaultAttributeValueImage() {
		if (defaultAttrValImgDesc == null){
			Bundle bundle = Platform.getBundle(JSFUiPlugin.PLUGIN_ID);
			URL url= FileLocator.find(bundle,new Path(defaultIconPath ), null);
			defaultAttrValImgDesc = ImageDescriptor.createFromURL(url);
		}
		return getOrCreateImage(defaultAttrValImgDesc);
	}

	private Attr getAttribute(IStructuredDocumentContext context) {
		final IDOMContextResolver domResolver = IStructuredDocumentContextResolverFactory.INSTANCE
				.getDOMContextResolver(context);

		if (domResolver != null) {
			final Node curNode = domResolver.getNode();

			if (curNode instanceof Attr) {
				return (Attr) curNode;
			}
		}
		return null;

	}

	public IContextInformation[] computeContextInformation(ITextViewer viewer,
			int offset) {
		// no context info
		return null;
	}

	public char[] getCompletionProposalAutoActivationCharacters() {
		// auto activate when user hits a '.'
		return new char[] { '.' };
	}

	public char[] getContextInformationAutoActivationCharacters() {
		// no auto-activation for context info
		return null;
	}

	public String getErrorMessage() {
		// don't flag errors
		return null;
	}

	public IContextInformationValidator getContextInformationValidator() {
		// don't validate context information
		return null;
	}

}