/*******************************************************************************
 * Copyright (c) 2001, 2004 IBM Corporation and others.
 * 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:
 *     IBM Corporation - initial API and implementation
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.xml.ui.internal.contentassist;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionContainer;
import org.eclipse.wst.sse.core.internal.util.ScriptLanguageKeys;
import org.eclipse.wst.sse.ui.internal.contentassist.ContentAssistUtils;
import org.eclipse.wst.sse.ui.internal.contentassist.CustomCompletionProposal;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
import org.eclipse.wst.xml.ui.internal.XMLUIMessages;
import org.eclipse.wst.xml.ui.internal.editor.XMLEditorPluginImageHelper;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;

/**
 * @author pavery
 */
public class XMLContentAssistUtilities extends ContentAssistUtils {

	/**
	 * ISSUE: this is a bit of hidden JSP knowledge that was implemented this
	 * way for expedency. Should be evolved in future to depend on
	 * "nestedContext".
	 */
	private class DOMJSPRegionContextsPrivateCopy {
		private static final String JSP_CLOSE = "JSP_CLOSE"; //$NON-NLS-1$
		private static final String JSP_DECLARATION_OPEN = "JSP_DECLARATION_OPEN"; //$NON-NLS-1$
		private static final String JSP_SCRIPTLET_OPEN = "JSP_SCRIPTLET_OPEN"; //$NON-NLS-1$
		private static final String JSP_EXPRESSION_OPEN = "JSP_EXPRESSION_OPEN"; //$NON-NLS-1$

	}


	public static final String CONTENT = "Content"; //$NON-NLS-1$
	public static final String CONTENT_SCRIPT_TYPE = "Content-Script-Type"; //$NON-NLS-1$
	public static final String HEAD = "HEAD"; //$NON-NLS-1$
	public static final String HTML = "HTML"; //$NON-NLS-1$
	public static final String HTTP_EQUIV = "HTTP-EQUIV"; //$NON-NLS-1$
	public static final String META = "META"; //$NON-NLS-1$

	/**
	 * A convenience method for getting the closing proposal given the
	 * contents (IndexedRegion) of a tag that is started, but possibly not
	 * ended
	 * 
	 * @param viewer
	 *            the text viewer
	 * @param documentPosition
	 *            the cursor position in the viewer
	 * @param indexedNode
	 *            the contents of the tag that is started but possibly not
	 *            ended
	 * @param parentTagName
	 *            the tag on which you are checkin for an ending tag
	 * @param imagePath
	 *            content assist image relative path
	 * @return ICompletionProposal
	 */
	public static ICompletionProposal computeJSPEndTagProposal(ITextViewer viewer, int documentPosition, IndexedRegion indexedNode, String parentTagName, String imagePath) {
		ICompletionProposal p = null;

		// check if tag is closed
		boolean hasEndTag = true;
		boolean isJSPTag = false;
		IDOMNode xnode = null;
		String tagName = ""; //$NON-NLS-1$
		if (indexedNode instanceof IDOMNode) {
			xnode = ((IDOMNode) indexedNode);
			// it's ended already...
			if (xnode.getEndStructuredDocumentRegion() != null) {
				return null;
			}
			IDOMNode openNode = null;
			if (!xnode.getNodeName().equalsIgnoreCase(parentTagName)) {
				openNode = (IDOMNode) xnode.getParentNode();
			}
			if (openNode != null) {
				if (openNode instanceof IDOMElement) {
					isJSPTag = ((IDOMElement) openNode).isJSPTag();
				}
				tagName = openNode.getNodeName();
				hasEndTag = (openNode.getEndStructuredDocumentRegion() != null);
			}
		}

		// it's closed, don't add close tag proposal
		if (!hasEndTag && !isJSPTag) {

			// create appropriate close tag text
			String proposedText = "</" + tagName; //$NON-NLS-1$
			String viewerText = viewer.getTextWidget().getText();
			if ((viewerText.length() >= documentPosition) && (viewerText.length() >= 2) && (documentPosition >= 2)) {
				String last2chars = viewerText.substring(documentPosition - 2, documentPosition);
				if (last2chars.endsWith("</")) {
					proposedText = tagName;
				}
				else if (last2chars.endsWith("<")) {
					proposedText = "/" + tagName; //$NON-NLS-1$
				}
			}

			// create proposal
			p = new CustomCompletionProposal(proposedText + ">", //$NON-NLS-1$
						documentPosition, 0, proposedText.length() + 1, XMLEditorPluginImageHelper.getInstance().getImage(imagePath), NLS.bind(XMLUIMessages.End_with_, (new Object[]{proposedText})), null, null, XMLRelevanceConstants.R_END_TAG);
		}
		else if (!hasEndTag && isJSPTag) {

			// create appropriate close tag text
			String proposedText = "%"; //$NON-NLS-1$
			String viewerText = viewer.getTextWidget().getText();

			// TODO (pa) make it smarter to add "%>" or just ">" if % is
			// already there...
			if ((viewerText.length() >= documentPosition) && (viewerText.length() >= 2)) {
				String last2chars = viewerText.substring(documentPosition - 2, documentPosition);
				String lastchar = viewerText.substring(documentPosition - 1, documentPosition);
				if (lastchar.equals("%")) //$NON-NLS-1$
				{
					if (last2chars.endsWith("<%")) {
						proposedText = "%"; //$NON-NLS-1$
					}
					else {
						proposedText = ""; //$NON-NLS-1$
					}
				}
			}

			// create proposal
			p = new CustomCompletionProposal(proposedText + ">", //$NON-NLS-1$
						documentPosition, 0, proposedText.length() + 1, XMLEditorPluginImageHelper.getInstance().getImage(imagePath), NLS.bind(XMLUIMessages.End_with_, (new Object[]{proposedText})), null, null, XMLRelevanceConstants.R_END_TAG);
		}

		return p;
	}


	/**
	 * A convenience method for getting the closing proposal given the
	 * contents (IndexedRegion) of a tag that is started, but possibly not
	 * ended
	 * 
	 * @param viewer
	 *            the text viewer
	 * @param documentPosition
	 *            the cursor position in the viewer
	 * @param indexedNode
	 *            the contents of the tag that is started but possibly not
	 *            ended
	 * @param parentTagName
	 *            the tag on which you are checkin for an ending tag
	 * @param imagePath
	 *            content assist relative image path
	 * @return ICompletionProposal
	 */
	public static ICompletionProposal computeXMLEndTagProposal(ITextViewer viewer, int documentPosition, IndexedRegion indexedNode, String parentTagName, String imagePath) {
		ICompletionProposal p = null;

		// check if tag is closed
		boolean hasEndTag = true;
		IDOMNode xnode = null;
		String tagName = ""; //$NON-NLS-1$
		if (indexedNode instanceof IDOMNode) {
			xnode = ((IDOMNode) indexedNode);
			// it's ended already...
			if (xnode.getEndStructuredDocumentRegion() != null) {
				return null;
			}
			IDOMNode styleNode = null;
			if (!xnode.getNodeName().equalsIgnoreCase(parentTagName)) {
				styleNode = (IDOMNode) xnode.getParentNode();
			}
			if (styleNode != null) {
				tagName = styleNode.getNodeName();
				hasEndTag = (styleNode.getEndStructuredDocumentRegion() != null);
			}
		}

		// it's closed, don't add close tag proposal
		if (!hasEndTag) {

			// create appropriate close tag text
			String proposedText = "</" + tagName; //$NON-NLS-1$
			String viewerText = viewer.getTextWidget().getText();
			if ((viewerText.length() >= documentPosition) && (viewerText.length() >= 2) && (documentPosition >= 2)) {
				String last2chars = viewerText.substring(documentPosition - 2, documentPosition);
				if (last2chars.endsWith("</")) {
					proposedText = tagName;
				}
				else if (last2chars.endsWith("<")) {
					proposedText = "/" + tagName; //$NON-NLS-1$
				}
			}

			// create proposal
			p = new CustomCompletionProposal(proposedText + ">", //$NON-NLS-1$
						documentPosition, 0, proposedText.length() + 1, XMLEditorPluginImageHelper.getInstance().getImage(imagePath), NLS.bind(XMLUIMessages.End_with_, (new Object[]{proposedText})), null, null, XMLRelevanceConstants.R_END_TAG);
		}
		return p;
	}

	private static String getMetaScriptType(Document doc) {
		// Can not just do a Document.getElementsByTagName(String) as this
		// needs
		// to be relatively fast.
		List metas = new ArrayList();
		// check for META tags under the Document
		Node html = null;
		Node head = null;
		Node child = null;
		// ----------------------------------------------------------------------
		// (pa) 20021217
		// cmvc defect 235554
		// performance enhancement: using child.getNextSibling() rather than
		// nodeList(item) for O(n) vs. O(n*n)
		// ----------------------------------------------------------------------

		for (child = doc.getFirstChild(); child != null; child = child.getNextSibling()) {
			if (child.getNodeType() != Node.ELEMENT_NODE) {
				continue;
			}
			if (child.getNodeName().equalsIgnoreCase(META)) {
				metas.add(child);
			}
			else if (child.getNodeName().equalsIgnoreCase(HTML)) {
				html = child;
			}
		}
		// NodeList children = doc.getChildNodes();
		// for(int i = 0; i < children.getLength(); i++) {
		// child = children.item(i);
		// if(child.getNodeType() != Node.ELEMENT_NODE)
		// continue;
		// if(child.getNodeName().equalsIgnoreCase(META))
		// metas.add(child);
		// else if(child.getNodeName().equalsIgnoreCase(HTML))
		// html = child;
		// }

		// check for META tags under HEAD
		if (html != null) {
			for (child = html.getFirstChild(); (child != null) && (head == null); child = child.getNextSibling()) {
				if (child.getNodeType() != Node.ELEMENT_NODE) {
					continue;
				}
				if (child.getNodeName().equalsIgnoreCase(HEAD)) {
					head = child;
				}
			}
			// children = html.getChildNodes();
			// for(int i = 0; i < children.getLength() && head == null; i++) {
			// child = children.item(i);
			// if(child.getNodeType() != Node.ELEMENT_NODE)
			// continue;
			// if(child.getNodeName().equalsIgnoreCase(HEAD))
			// head = child;
			// }
		}

		if (head != null) {
			for (head.getFirstChild(); child != null; child = child.getNextSibling()) {
				if (child.getNodeType() != Node.ELEMENT_NODE) {
					continue;
				}
				if (child.getNodeName().equalsIgnoreCase(META)) {
					metas.add(child);
				}
			}
			// children = head.getChildNodes();
			// for(int i = 0 ; i < children.getLength(); i++) {
			// child = children.item(i);
			// if(child.getNodeType() != Node.ELEMENT_NODE)
			// continue;
			// if(child.getNodeName().equalsIgnoreCase(META))
			// metas.add(child);
			// }
		}

		return getMetaScriptType(metas);
	}

	private static String getMetaScriptType(List metaNodeList) {
		Node meta = null;
		NamedNodeMap attributes = null;
		boolean httpEquiv = false;
		String contentScriptType = null;

		for (int i = metaNodeList.size() - 1; i >= 0; i--) {
			meta = (Node) metaNodeList.get(i);
			attributes = meta.getAttributes();
			httpEquiv = false;
			contentScriptType = null;
			for (int j = 0; j < attributes.getLength(); j++) {
				if (attributes.item(j).getNodeName().equalsIgnoreCase(HTTP_EQUIV)) {
					httpEquiv = attributes.item(j).getNodeValue().equalsIgnoreCase(CONTENT_SCRIPT_TYPE);
				}
				else if (attributes.item(j).getNodeName().equalsIgnoreCase(CONTENT)) {
					contentScriptType = attributes.item(j).getNodeValue();
				}
			}
			if (httpEquiv && (contentScriptType != null)) {
				return contentScriptType;
			}
		}
		return null;
	}

	/**
	 * Returns the scripting language the scriptNode is in Currently returns
	 * javascript unless some unknown type or language is specified. Then the
	 * unknown type/language is returned
	 * 
	 * @param scriptNode
	 */
	public static String getScriptLanguage(Node scriptNode) {
		Node attr = null;

		boolean specified = false;
		// try to find a scripting adapter for 'type'
		if ((scriptNode == null) || (scriptNode.getAttributes() == null)) {
			return null;
		}

		attr = scriptNode.getAttributes().getNamedItem("type");//$NON-NLS-1$
		if (attr != null) {
			specified = true;
			String type = attr.getNodeValue();
			return lookupScriptType(type);
		}
		// now try to find a scripting adapter for 'language' (deprecated by
		// HTML specifications)
		attr = scriptNode.getAttributes().getNamedItem("language");//$NON-NLS-1$
		if (attr != null) {
			specified = true;
			String language = attr.getNodeValue();
			return lookupScriptLanguage(language);
		}
		// check if one is specified by a META tag at the root level or inside
		// of HEAD
		String type = null;
		if (!specified) {
			type = getMetaScriptType(scriptNode.getOwnerDocument());
		}
		if (type != null) {
			specified = true;
			return lookupScriptType(type);
		}
		// return default
		if (!specified) {
			return ScriptLanguageKeys.JAVASCRIPT;
		}
		return null;
	}

	/**
	 * Tells you if the flatnode is the %> delimiter
	 * 
	 * ISSUE: this is a bit of hidden JSP knowledge that was implemented this
	 * way for expedency. Should be evolved in future to depend on
	 * "nestedContext".
	 */
	public static boolean isJSPCloseDelimiter(IStructuredDocumentRegion fn) {
		if (fn == null) {
			return false;
		}
		return isJSPCloseDelimiter(fn.getType());
	}

	/**
	 * ISSUE: this is a bit of hidden JSP knowledge that was implemented this
	 * way for expedency. Should be evolved in future to depend on
	 * "nestedContext".
	 */
	public static boolean isJSPCloseDelimiter(String type) {
		if (type == null) {
			return false;
		}
		return (type.equals(DOMJSPRegionContextsPrivateCopy.JSP_CLOSE) || type.equals(DOMRegionContext.XML_TAG_CLOSE));
	}

	/**
	 * Tells you if the flatnode is the JSP region <%%>, <%=%>, <%!%>
	 * 
	 * ISSUE: this is a bit of hidden JSP knowledge that was implemented this
	 * way for expedency. Should be evolved in future to depend on
	 * "nestedContext".
	 */
	public static boolean isJSPDelimiter(IStructuredDocumentRegion fn) {
		boolean isDelimiter = false;
		String type = fn.getType();
		if (type != null) {
			isDelimiter = isJSPDelimiter(type);
		}
		return isDelimiter;
	}

	/**
	 * ISSUE: this is a bit of hidden JSP knowledge that was implemented this
	 * way for expedency. Should be evolved in future to depend on
	 * "nestedContext".
	 */
	public static boolean isJSPDelimiter(String type) {
		if (type == null) {
			return false;
		}
		return (isJSPOpenDelimiter(type) || isJSPCloseDelimiter(type));
	}

	/**
	 * Tells you if the flatnode is <%, <%=, or <%! ISSUE: this is a bit of
	 * hidden JSP knowledge that was implemented this way for expedency.
	 * Should be evolved in future to depend on "nestedContext".
	 */
	public static boolean isJSPOpenDelimiter(IStructuredDocumentRegion fn) {
		if (fn == null) {
			return false;
		}
		return isJSPOpenDelimiter(fn.getType());
	}

	/**
	 * ISSUE: this is a bit of hidden JSP knowledge that was implemented this
	 * way for expedency. Should be evolved in future to depend on
	 * "nestedContext".
	 */
	public static boolean isJSPOpenDelimiter(String type) {
		if (type == null) {
			return false;
		}
		return (type.equals(DOMJSPRegionContextsPrivateCopy.JSP_SCRIPTLET_OPEN) || type.equals(DOMJSPRegionContextsPrivateCopy.JSP_DECLARATION_OPEN) || type.equals(DOMJSPRegionContextsPrivateCopy.JSP_EXPRESSION_OPEN));
	}

	/**
	 * Tells you if the flatnode is the <jsp:scriptlet>, <jsp:expression>, or
	 * <jsp:declaration>tag
	 * 
	 * ISSUE: this is a bit of hidden JSP knowledge that was implemented this
	 * way for expedency. Should be evolved in future to depend on
	 * "nestedContext".
	 */
	public static boolean isXMLJSPDelimiter(IStructuredDocumentRegion fn) {
		boolean isDelimiter = false;
		if ((fn != null) && (fn instanceof ITextRegionContainer)) {
			Object[] regions = ((ITextRegionContainer) fn).getRegions().toArray();
			ITextRegion temp = null;
			String regionText = ""; //$NON-NLS-1$
			for (int i = 0; i < regions.length; i++) {
				temp = (ITextRegion) regions[i];
				if (temp.getType() == DOMRegionContext.XML_TAG_NAME) {
					regionText = fn.getText(temp);
					if (regionText.equalsIgnoreCase("jsp:scriptlet") || regionText.equalsIgnoreCase("jsp:expression") || regionText.equalsIgnoreCase("jsp:declaration")) {
						isDelimiter = true;
					}
				}
			}
		}
		return isDelimiter;
	}

	/**
	 * Returns "javascript" if language attribute is some form of javascript,
	 * "java" if language attribute is some form of java. Otherwise, just
	 * returns type.
	 * 
	 * @param language
	 */
	public static String lookupScriptLanguage(String language) {
		for (int i = 0; i < ScriptLanguageKeys.JAVASCRIPT_LANGUAGE_KEYS.length; i++) {
			if (ScriptLanguageKeys.JAVASCRIPT_LANGUAGE_KEYS[i].equalsIgnoreCase(language)) {
				return ScriptLanguageKeys.JAVASCRIPT;
			}
		}
		for (int i = 0; i < ScriptLanguageKeys.JAVA_LANGUAGE_KEYS.length; i++) {
			if (ScriptLanguageKeys.JAVA_LANGUAGE_KEYS[i].equalsIgnoreCase(language)) {
				return ScriptLanguageKeys.JAVA;
			}
		}
		return language;
	}

	/**
	 * Returns "javascript" if type (used in <script type="xxx"> is actually
	 * javascript type. Otherwise, just returns type
	 * 
	 * @param type
	 */
	public static String lookupScriptType(String type) {
		for (int i = 0; i < ScriptLanguageKeys.JAVASCRIPT_MIME_TYPE_KEYS.length; i++) {
			if (ScriptLanguageKeys.JAVASCRIPT_MIME_TYPE_KEYS[i].equalsIgnoreCase(type)) {
				return ScriptLanguageKeys.JAVASCRIPT;
			}
		}
		return type;
	}
}
