/*******************************************************************************
 * 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;
		
		List[] extendedContent = new List[1];
		while (child != null) {
			// perform actual validation
			validateNode(parent, child, ed, extendedContent);
			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;
	// }

	/*
	 * The implementation of the following method is practical but accurate.
	 * The accurate maximum occurrence should be retrieve 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 boolean containsName(String name, Object[] possible) {
//		if (name != null && possible != null) {
//			for (int i = 0; i < possible.length; i++) {
//				if(name.equals(possible[i]))
//				return true;
//			}
//		}
//		return false;
//	}

	private void validateNode(Element target, Node child, CMElementDeclaration edec, List[] extendedContent) {
		// 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)))
					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;
						}
						
						/*
						 * https://bugs.eclipse.org/bugs/show_bug.cgi?id=218143 - 
						 * ModelQuery use not pervasive enough
						 */
						if (extendedContent[0] == null) {
							extendedContent[0] = ModelQueryUtil.getModelQuery(target.getOwnerDocument()).getAvailableContent(target, edec, ModelQuery.INCLUDE_CHILD_NODES);
						}

						List availableChildElementDeclarations = extendedContent[0];
						/*
						 * Retrieve and set aside just the element names for faster checking
						 * later.
						 */
						int availableChildCount = availableChildElementDeclarations.size();
						String elementName = ced.getElementName().toLowerCase(Locale.US);
						for (int i = 0; i < availableChildCount; i++) {
							CMNode cmnode = (CMNode) availableChildElementDeclarations.get(i);
							if (cmnode.getNodeType() == CMNode.ELEMENT_DECLARATION && cmnode.getNodeName().toLowerCase(Locale.US).equals(elementName)) {
								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));
		}
	}
}
