/*******************************************************************************
 * Copyright (c) 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
 *******************************************************************************/
package org.eclipse.wst.html.core.internal.modelquery;


import java.util.List;
import java.util.Vector;

import org.eclipse.wst.html.core.internal.provisional.HTMLCMProperties;
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.CMNode;
import org.eclipse.wst.xml.core.internal.contentmodel.modelqueryimpl.ModelQueryImpl;
import org.eclipse.wst.xml.core.internal.contentmodel.util.CMDocumentCache;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
import org.eclipse.wst.xml.core.internal.ssemodelquery.MovableModelQuery;
import org.eclipse.wst.xml.uriresolver.internal.util.IdResolver;
import org.w3c.dom.Element;
import org.w3c.dom.Node;


public class HTMLModelQueryImpl extends ModelQueryImpl implements MovableModelQuery {

	protected CMDocumentCache fCache = null;

	public HTMLModelQueryImpl(CMDocumentCache cache, IdResolver idResolver) {
		super(new HTMLModelQueryAssociationProvider(cache, idResolver));
		fCache = cache;
	}

	public List getAvailableContent(Element element, CMElementDeclaration ed, int includeOptions) {
		List originalCandidates = super.getAvailableContent(element, ed, includeOptions);
		if ((includeOptions & INCLUDE_CHILD_NODES) == 0)
			return originalCandidates;
		// When the target document is XHTML, it is waste to find inclusions,
		// since inclusion is available in HTML only.
		if (!ed.supports(HTMLCMProperties.IS_XHTML))
			return originalCandidates;
		
		Boolean isXhtml = Boolean.FALSE;
		isXhtml = (Boolean) ed.getProperty(HTMLCMProperties.IS_XHTML);
		if (isXhtml != null && isXhtml.booleanValue())
			return originalCandidates;

		// OK, the target is surely a HTML element, so it may have inclusion.
		// Try to find it.
		Vector candidates = new Vector(originalCandidates);

		switch (ed.getContentType()) {
			case CMElementDeclaration.ANY :
			case CMElementDeclaration.ELEMENT :
			case CMElementDeclaration.MIXED :
				// do enumerate inclusions.
				candidates.addAll(HMQUtil.getInclusions(element));
				break;
			case CMElementDeclaration.EMPTY :
			case CMElementDeclaration.PCDATA :
			case CMElementDeclaration.CDATA :
			default :
				// should not add any inclusions.
				// so, nothing to do here.
				break;
		}
		// If the current element does not available, it is impossible
		// to filter out exclusion.
		if (element == null)
			return candidates;

		// Now, the time to check exclusion.
		Vector content = new Vector(candidates.size());
		for (int i = 0; i < candidates.size(); i++) {
			CMElementDeclaration candidate = (CMElementDeclaration) candidates.elementAt(i);
			if (candidate == null)
				continue;
			if (isExcluded(candidate, element))
				continue;
			content.add(candidate);
		}

		return content;
	}

	/**
	 * @see MovableModelQuery#setIdResolver(IdResolver)
	 */
	public void setIdResolver(IdResolver newIdResolver) {
		modelQueryAssociationProvider = new HTMLModelQueryAssociationProvider(fCache, newIdResolver);
	}

	// utilities
	private static boolean isExcluded(CMElementDeclaration candidate, Element target) {
		CMNamedNodeMap prohibited = getProhibitedAncestors(candidate);
		if (prohibited == null)
			return false;
		Element parent = target;
		while (parent != null) {
			CMNode pdec = prohibited.getNamedItem(parent.getNodeName());
			if (pdec != null)
				return true;
			parent = getExplicitParentElement(parent);
		}
		return false;
	}

	private static CMNamedNodeMap getProhibitedAncestors(CMElementDeclaration dec) {
		if (!dec.supports(HTMLCMProperties.PROHIBITED_ANCESTORS))
			return null;
		return (CMNamedNodeMap) dec.getProperty(HTMLCMProperties.PROHIBITED_ANCESTORS);
	}

	/* get an ancestor element ignoring implicit ones. */
	private static Element getExplicitParentElement(Node child) {
		if (child == null)
			return null;

		Node p = child.getParentNode();
		while (p != null) {
			if (p.getNodeType() == Node.ELEMENT_NODE) {
				if (p instanceof IDOMElement) {
					if (((IDOMElement) p).isImplicitTag()) {
						p = p.getParentNode();
						continue;
					}
				}
				return (Element) p;
			}
			p = p.getParentNode();
		}
		return null;
	}

}