/*******************************************************************************
 * 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.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.IDOMContextResolver;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IStructuredDocumentContextResolverFactory;
import org.eclipse.jst.jsf.context.resolver.structureddocument.ITaglibContextResolver;
import org.eclipse.jst.jsf.context.resolver.structureddocument.internal.ITextRegionContextResolver;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContext;
import org.eclipse.jst.jsf.context.structureddocument.IStructuredDocumentContextFactory;
import org.eclipse.jst.jsf.metadataprocessors.MetaDataEnabledProcessingFactory;
import org.eclipse.jst.jsf.metadataprocessors.features.IPossibleValue;
import org.eclipse.jst.jsf.metadataprocessors.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"; //$NON-NLS-1$
	
	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("")){ //$NON-NLS-1$
			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;
	}

}