/*******************************************************************************
 * 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.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.wst.sse.core.IndexedRegion;
import org.eclipse.wst.sse.core.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.text.ITextRegion;
import org.eclipse.wst.sse.core.text.ITextRegionContainer;
import org.eclipse.wst.sse.core.util.ScriptLanguageKeys;
import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;
import org.eclipse.wst.sse.ui.internal.contentassist.ContentAssistUtils;
import org.eclipse.wst.sse.ui.internal.contentassist.CustomCompletionProposal;
import org.eclipse.wst.xml.core.document.XMLElement;
import org.eclipse.wst.xml.core.document.XMLNode;
import org.eclipse.wst.xml.core.parser.XMLRegionContext;
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 XMLJSPRegionContexts {
		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 path in realation to com.ibm.sed.
	 *            structured. contentassist. xmlSourceEditorImageHelper
	 * @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;
		XMLNode xnode = null;
		String tagName = ""; //$NON-NLS-1$
		if (indexedNode instanceof XMLNode) {
			xnode = ((XMLNode) indexedNode);
			// it's ended already...
			if (xnode.getEndStructuredDocumentRegion() != null)
				return null;
			XMLNode openNode = null;
			if (!xnode.getNodeName().equalsIgnoreCase(parentTagName))
				openNode = (XMLNode) xnode.getParentNode();
			if (openNode != null) {
				if (openNode instanceof XMLElement) {
					isJSPTag = ((XMLElement) 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 = proposedText = "</" + tagName; // ResourceHandler
			// wants text
			// w/out
			// ending '>'
			// //$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("</")) //$NON-NLS-1$
					proposedText = tagName;
				else if (last2chars.endsWith("<")) //$NON-NLS-1$
					proposedText = "/" + tagName; //$NON-NLS-1$
			}

			// create proposal
			p = new CustomCompletionProposal(proposedText + ">", //$NON-NLS-1$
						documentPosition, 0, proposedText.length() + 1, XMLEditorPluginImageHelper.getInstance().getImage(imagePath), //$NON-NLS-1$
						SSEUIPlugin.getResourceString("%15concat", (new Object[]{proposedText})), //$NON-NLS-1$ = "End with '{0}>'"
						null, null, XMLRelevanceConstants.R_END_TAG);
		}
		else if (!hasEndTag && isJSPTag) {

			// create appropriate close tag text
			String proposedText = proposedText = "%"; // ResourceHandler
			// wants
			// text w/out ending '>'
			// //$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("<%")) //$NON-NLS-1$
						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), //$NON-NLS-1$
						SSEUIPlugin.getResourceString("%15concat", (new Object[]{proposedText})), //$NON-NLS-1$ = "End with '{0}>'"
						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 image path in realation to com.ibm.sed.
	 *            structured. contentassist. xmlSourceEditorImageHelper
	 * @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;
		XMLNode xnode = null;
		String tagName = ""; //$NON-NLS-1$
		if (indexedNode instanceof XMLNode) {
			xnode = ((XMLNode) indexedNode);
			// it's ended already...
			if (xnode.getEndStructuredDocumentRegion() != null)
				return null;
			XMLNode styleNode = null;
			if (!xnode.getNodeName().equalsIgnoreCase(parentTagName))
				styleNode = (XMLNode) 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 = proposedText = "</" + tagName; // ResourceHandler
			// wants text
			// w/out
			// ending '>'
			// //$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("</")) //$NON-NLS-1$
					proposedText = tagName;
				else if (last2chars.endsWith("<")) //$NON-NLS-1$
					proposedText = "/" + tagName; //$NON-NLS-1$
			}

			// create proposal
			p = new CustomCompletionProposal(proposedText + ">", //$NON-NLS-1$
						documentPosition, 0, proposedText.length() + 1, XMLEditorPluginImageHelper.getInstance().getImage(imagePath), //$NON-NLS-1$
						SSEUIPlugin.getResourceString("%15concat", (new Object[]{proposedText})), //$NON-NLS-1$ = "End with '{0}>'"
						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(XMLJSPRegionContexts.JSP_CLOSE) || type.equals(XMLRegionContext.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(XMLJSPRegionContexts.JSP_SCRIPTLET_OPEN) || type.equals(XMLJSPRegionContexts.JSP_DECLARATION_OPEN) || type.equals(XMLJSPRegionContexts.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() == XMLRegionContext.XML_TAG_NAME) {
					regionText = fn.getText(temp);
					if (regionText.equalsIgnoreCase("jsp:scriptlet") || regionText.equalsIgnoreCase("jsp:expression") || regionText.equalsIgnoreCase("jsp:declaration")) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
						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;
	}
}
