/*******************************************************************************
 * Copyright (c) 2004, 2008 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.validate;

import java.util.List;
import java.util.Locale;

import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNode;
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.provisional.document.IDOMNode;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

public class HTMLElementContentValidator extends PrimeValidator {

	/**
	 * HTMLElementContentValidator constructor comment.
	 */
	public HTMLElementContentValidator() {
		super();
	}

	/**
	 * Allowing the INodeAdapter to compare itself against the type allows it
	 * to return true in more than one case.
	 */
	public boolean isAdapterForType(Object type) {
		return ((type == HTMLElementContentValidator.class) || super.isAdapterForType(type));
	}

	/**
	 */
	public void validate(IndexedRegion node) {
		Element target = (Element) node;
		if (CMUtil.isForeign(target))
			return;

		validateContent(target, target.getFirstChild());
	}

	private void validateContent(Element parent, Node child) {
		if (child == null)
			return;

		CMElementDeclaration ed = CMUtil.getDeclaration(parent);
		if(ed == null || ed.getContentType() == CMElementDeclaration.ANY)
			return;
		
		/*
		 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=218143 - 
		 * ModelQuery use not pervasive enough
		 */
		List availableChildElementDeclarations = ModelQueryUtil.getModelQuery(parent.getOwnerDocument()).getAvailableContent(parent, ed, ModelQuery.INCLUDE_CHILD_NODES);

		while (child != null) {
			// perform actual validation
			validateNode(parent, child, ed, availableChildElementDeclarations);
			child = child.getNextSibling();
		}
	}

	// private int countExplicitSiblings(Element parent, String tagName) {
	// NodeList children = parent.getChildNodes();
	// int count = 0;
	// for (int i = 0; i < children.getLength(); i++) {
	// Node child = children.item(i);
	// if (child.getNodeType() != Node.ELEMENT_NODE)
	// continue;
	// if (tagName.equalsIgnoreCase(((Element) child).getTagName())) {
	// count++;
	// }
	// }
	// return count;
	// }

	private boolean containsDeclaration(CMElementDeclaration edec, List available) {
		if (edec != null && available != null) {
			
			for (int i = 0; i < available.size(); i++) {
				CMNode cmnode = (CMNode) available.get(i);
				if (cmnode.getNodeType() == CMNode.ELEMENT_DECLARATION && cmnode.getNodeName().toLowerCase(Locale.US).equals(edec.getElementName().toLowerCase(Locale.US)))
					return true;
			}
		}
		return false;
	}
	/*
	 * The implementation of the following method is practical but accurate.
	 * The accurate maximum occurence should be retreive from the content
	 * model. However, it is useful enough, since almost implicit elements are
	 * HTML, HEAD, or BODY.
	 */
	// private int getMaxOccur(Element parent, String childTag) {
	// return 1;
	// }
	private void validateNode(Element target, Node child, CMElementDeclaration edec, List availableChildElementDeclarations) {
		// NOTE: If the target element is 'UNKNOWN', that is, it has no
		// element declaration, the content type of the element should be
		// regarded as 'ANY'. -- 9/10/2001
		int contentType = CMElementDeclaration.ANY;
		if (edec != null)
			contentType = edec.getContentType();

		int error = ErrorState.NONE_ERROR;
		int segType = FMUtil.SEG_WHOLE_TAG;
		
		switch (child.getNodeType()) {
			case Node.ELEMENT_NODE :
				Element childElem = (Element) child;
				// Defect 200321:
				// This validator cares only HTML/XHTML elements. If a child
				// is
				// an element of foreign markup languages, just ignore it.
				if (CMUtil.isForeign(childElem))
					return;

				CMElementDeclaration ced = CMUtil.getDeclaration((Element) child);
				// Defect 186774: If a child is not one of HTML elements,
				// it should be regarded as a valid child regardless the
				// type of the parent content model. -- 10/12/2001
				if (ced == null || CMUtil.isSSI(ced) || (!CMUtil.isHTML(ced)) || containsDeclaration(ced, availableChildElementDeclarations))
					return;

				switch (contentType) {
					case CMElementDeclaration.ANY :
						// Keep going.
						return;
					case CMElementDeclaration.ELEMENT :
					case CMElementDeclaration.MIXED :
						if (ced == null)
							return;
						if (CMUtil.isValidChild(edec, ced))
							return;
						// Now, it is the time to check inclusion, unless the
						// target
						// document is not a XHTML.
						if (!CMUtil.isXHTML(edec)) {
							// pure HTML
							if (CMUtil.isValidInclusion(ced, target))
								return;
						}
						error = ErrorState.INVALID_CONTENT_ERROR;
						break;
					default :
						error = ErrorState.INVALID_CONTENT_ERROR;
						break;
				}
				// Mark the whole START tag as an error segment.
				segType = FMUtil.SEG_START_TAG;
				break;
			case Node.TEXT_NODE :
				switch (contentType) {
					case CMElementDeclaration.ANY :
					case CMElementDeclaration.MIXED :
					case CMElementDeclaration.PCDATA :
					case CMElementDeclaration.CDATA :
						// D184339
						// Keep going.
						return;
					case CMElementDeclaration.ELEMENT :
					case CMElementDeclaration.EMPTY :
						if (((IDOMText) child).isElementContentWhitespace())
							return;
						error = ErrorState.INVALID_CONTENT_ERROR;
						break;
					default :
						error = ErrorState.INVALID_CONTENT_ERROR;
						break;
				}
				// Mark the whole node as an error segment.
				segType = FMUtil.SEG_WHOLE_TAG;
				break;
			case Node.COMMENT_NODE :
			case Node.PROCESSING_INSTRUCTION_NODE :
				if (contentType != CMElementDeclaration.EMPTY)
					return;
				error = ErrorState.INVALID_CONTENT_ERROR;
				// Mark the whole node as an error segment.
				segType = FMUtil.SEG_WHOLE_TAG;
				break;
			default :
				error = ErrorState.INVALID_CONTENT_ERROR;
				// Mark the whole node as an error segment.
				segType = FMUtil.SEG_WHOLE_TAG;
				break;
		}
		if (error != ErrorState.NONE_ERROR) {
			Segment errorSeg = FMUtil.getSegment((IDOMNode) child, segType);
			if (errorSeg != null)
				reporter.report(new ErrorInfoImpl(error, errorSeg, child));
		}
	}
}
