/*******************************************************************************
 * Copyright (c) 2004, 2010 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.css.core.internal.document;



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

import org.eclipse.wst.css.core.internal.provisional.adapters.IStyleSelectorAdapter;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSSelector;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSSelectorCombinator;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSSelectorItem;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSSimpleSelector;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.eclipse.wst.xml.core.internal.provisional.NameValidator;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import com.ibm.icu.util.StringTokenizer;


/**
 * 
 */
class CSSSelector implements ICSSSelector {

	private int fSpecificity = -1;
	private String fCachedString = null;
	private List fTokens = null;
	private List fItems = null;
	private List fParseErrors = null;
	private List fNameErrors = null;

	CSSSelector(List tokens) {
		fTokens = new ArrayList(tokens);
	}

	/**
	 * @return boolean
	 * @param obj
	 *            java.lang.Object
	 */
	public boolean equals(Object obj) {
		if (this == obj)
			return true;

		if (obj == null || this.getClass() != obj.getClass())
			return false;

		CSSSelector foreign = (CSSSelector) obj;

		// if (fSpecificity != foreign.fSpecificity) return false;

		if (getLength() != foreign.getLength())
			return false;

		for (int i = 0; i < getLength(); i++) {
			if (!getItem(i).equals(foreign.getItem(i)))
				return false;
		}

		return true;
	}

	public ICSSSelectorItem getItem(int index) {
		if (fItems == null) {
			fItems = parseSelector(fTokens);
		}
		if (fItems != null && 0 <= index && index < fItems.size()) {
			return (ICSSSelectorItem) fItems.get(index);
		}
		else {
			return null;
		}
	}

	/**
	 * @return java.util.Iterator
	 */
	public Iterator getIterator() {
		if (fItems == null) {
			fItems = parseSelector(fTokens);
		}
		return (fItems != null) ? fItems.iterator() : null;
	}

	/**
	 * @return int
	 */
	public int getLength() {
		if (fItems == null) {
			fItems = parseSelector(fTokens);
		}
		return (fItems != null) ? fItems.size() : 0;
	}

	/**
	 * @return org.w3c.dom.Element
	 */
	private Element getParentElement(Element element) {
		Node node = element.getParentNode();
		if (node != null && node.getNodeType() == Node.ELEMENT_NODE) {
			return (Element) node;
		}
		return null;

	}

	/**
	 * @return org.w3c.dom.Element
	 */
	private Element getPreviousElement(Element element) {
		Element p = null;
		for (Node node = element.getPreviousSibling(); node != null; node = node.getPreviousSibling()) {
			if (node.getNodeType() == Node.ELEMENT_NODE) {
				p = (Element) node;
				break;
			}
		}
		return p;
	}

	/**
	 * Calculate a selector's specificity a = the number of ID attributes in
	 * the selector b = the number of other attributes and pseudo-classes in
	 * the selector c = the number of element names in the selector (ignore
	 * pseudo-elements) Concatenating the three numbers a-b-c (in a number
	 * system with a large base) gives the specificity.
	 * 
	 * @return int
	 */
	public int getSpecificity() {
		if (fSpecificity < 0) {
			int nIDs = 0;
			int nAttributes = 0;
			int nElements = 0;
			Iterator i = getIterator();
			while (i.hasNext()) {
				ICSSSelectorItem item = (ICSSSelectorItem) i.next();
				if (item instanceof CSSSimpleSelector) {
					CSSSimpleSelector selector = (CSSSimpleSelector) item;
					nIDs += selector.getNumOfIDs();
					nAttributes += selector.getNumOfAttributes();
					nAttributes += selector.getNumOfClasses();
					nAttributes += selector.getNumOfPseudoNames();
					if (!selector.isUniversal()) {
						nElements++;
					}
				}
			}
			fSpecificity = nIDs * 10000 + nAttributes * 100 + nElements;
		}

		return fSpecificity;
	}

	/**
	 * @return java.lang.String
	 */
	public String getString() {
		if (fCachedString == null) {
			StringBuffer buf = new StringBuffer();
			Iterator i = getIterator();
			while (i.hasNext()) {
				ICSSSelectorItem item = (ICSSSelectorItem) i.next();
				if (item instanceof CSSSelectorCombinator) {
					// If item is DESCENDANT combinator, it is just single
					// space.
					// Then, you dont have to append string..
					if (((CSSSelectorCombinator) item).getCombinatorType() != ICSSSelectorCombinator.DESCENDANT) {
						buf.append(" ");//$NON-NLS-1$
						buf.append(item.getString());
					}
					buf.append(" ");//$NON-NLS-1$
				}
				else {
					buf.append(item.getString());
				}
			}
			fCachedString = buf.toString();
		}

		return fCachedString;
	}

	/**
	 * @return boolean
	 * @param element
	 *            org.w3c.dom.Element
	 */
	public boolean match(org.w3c.dom.Element element, java.lang.String pseudoName) {
		Element target = element;
		char combinatorType = ICSSSelectorCombinator.UNKNOWN;
		Element chunkStartElement = null; // for CHILD and ADJACENT
											// combinator
		int chunkStartItem = -1; // for CHILD and ADJACENT combinator
		int numItems = getLength();
		for (int iItem = numItems - 1; iItem >= 0; iItem--) {
			// Check Selector Items
			ICSSSelectorItem item = getItem(iItem);
			if (item instanceof ICSSSimpleSelector) {
				// Simple Selector
				if (target == null)
					return false;
				if (!matchExactly((ICSSSimpleSelector) item, target, pseudoName)) {
					switch (combinatorType) {
						case ICSSSelectorCombinator.DESCENDANT :
							do {
								target = getParentElement(target);
								if (target == null)
									return false;
							}
							while (!matchExactly((ICSSSimpleSelector) item, target, pseudoName));
							break;
						case ICSSSelectorCombinator.CHILD :
						case ICSSSelectorCombinator.ADJACENT :
							if (chunkStartElement != null && chunkStartElement != element) {
								// previous conbinator must be DESCENDENT.
								// goto parent
								target = getParentElement(chunkStartElement);
								iItem = chunkStartItem + 1;
								chunkStartElement = null;
								chunkStartItem = -1;
								break;
							}
						default :
							// other combinators are not supported yet.
							return false;
					}
				}
			}
			else if (item instanceof ICSSSelectorCombinator) {
				// Combinator ( "+", ">", " ", ...)
				if (iItem == numItems - 1)
					return false; // last item is combinator

				ICSSSelectorCombinator sc = (ICSSSelectorCombinator) item;
				combinatorType = sc.getCombinatorType();
				switch (combinatorType) {
					case ICSSSelectorCombinator.DESCENDANT :
						target = getParentElement(target);
						break;
					case ICSSSelectorCombinator.CHILD :
					case ICSSSelectorCombinator.ADJACENT :
						if (chunkStartElement == null) {
							chunkStartElement = target;
							chunkStartItem = iItem + 1; // safe because this
														// is not a last item.
						}
						if (combinatorType == ICSSSelectorCombinator.CHILD) {
							target = getParentElement(target);
						}
						else {
							target = getPreviousElement(target);
						}
						break;
				}
			}
			else {
				// what is this item ???
				return false;
			}
		}
		// OK this selector maches the element.
		return true;

	}

	/**
	 * @return boolean
	 */
	private boolean matchExactly(ICSSSimpleSelector selector, Element element, String pseudoName) {
		IStyleSelectorAdapter adapter = (IStyleSelectorAdapter) ((INodeNotifier) element).getAdapterFor(IStyleSelectorAdapter.class);
		if (adapter != null) {
			return adapter.match(selector, element, pseudoName);
		}

		if (element == null)
			return false;
		int i;
		String key;

		// TODO: PseudoName

		// check tag name
		if (!selector.isUniversal() && !element.getNodeName().equals(selector.getName()))
			return false;

		// check id
		i = selector.getNumOfIDs();
		if (i > 0) {
			if (i > 1)
				return false;
			if (!element.hasAttribute("id") || (key = element.getAttribute("id")).length() == 0)//$NON-NLS-1$ //$NON-NLS-2$
				return false;
			if (!selector.getID(0).equals(key))
				return false;
		}

		// check class
		i = selector.getNumOfClasses();
		if (i > 0) {
			if (!element.hasAttribute("class") || (key = element.getAttribute("class")).length() == 0) //$NON-NLS-1$  //$NON-NLS-2$
				return false;
			StringTokenizer tokenizer = new StringTokenizer(key);
			for (i = i - 1; i >= 0; i--) {
				boolean ok = false;
				while (tokenizer.hasMoreTokens()) {
					if (selector.getClass(i).equals(tokenizer.nextToken())) {
						ok = true;
						break;
					}
				}
				if (!ok)
					return false;
			}
		}

		// check attributes
		for (i = selector.getNumOfAttributes() - 1; i >= 0; i--) {
			StringTokenizer tokenizer = new StringTokenizer(selector.getAttribute(i), "=~| \t\r\n\f");//$NON-NLS-1$
			int countTokens = tokenizer.countTokens();
			if (countTokens > 0) {
				String attrName = tokenizer.nextToken();
				String attrValue = null;
				if (!element.hasAttribute(attrName) || (attrValue = element.getAttribute(attrName)).length() == 0)
					return false;
				if (countTokens > 1) {
					String token = tokenizer.nextToken("= \t\r\n\f");//$NON-NLS-1$
					StringTokenizer attrValueTokenizer = null;
					if (token.equals("~")) {//$NON-NLS-1$
						attrValueTokenizer = new StringTokenizer(attrValue);
					}
					else if (token.equals("|")) {//$NON-NLS-1$
						attrValueTokenizer = new StringTokenizer(attrValue, "-");//$NON-NLS-1$
					}
					if (attrValueTokenizer != null) {
						if (tokenizer.hasMoreTokens()) {
							token = tokenizer.nextToken();
							boolean ok = false;
							while (attrValueTokenizer.hasMoreTokens()) {
								if (token.equals(attrValueTokenizer.nextToken())) {
									ok = true;
									break;
								}
							}
							if (!ok)
								return false;
						}
					}
					else {
						if (!attrValue.equals(token))
							return false;
					}
				}
			}
		}

		return true;
	}

	private List parseSelector(List tokens) {
		CSSSelectorParser parser = new CSSSelectorParser(tokens);
		List selector = parser.getSelector();
		Iterator i = parser.getErrors();
		fParseErrors = new ArrayList();
		while (i.hasNext()) {
			fParseErrors.add(i.next());
		}
		return selector;
	}

	public Iterator getErrors() {
		if (fNameErrors == null) {
			fNameErrors = new ArrayList();
			Iterator iItem = getIterator();
			while (iItem.hasNext()) {
				ICSSSelectorItem item = (ICSSSelectorItem) iItem.next();
				if (item instanceof ICSSSimpleSelector) {
					if (!((ICSSSimpleSelector) item).isUniversal()) {
						String name = ((ICSSSimpleSelector) item).getName();
						if (!NameValidator.isValid(name)) {
							fNameErrors.add(item);
						}
					}
				}
			}
		}
		List errors = new ArrayList(fParseErrors);
		errors.addAll(fNameErrors);
		return errors.iterator();
	}

	public String toString() {
		return getString();
	}

	/**
	 * @see ICSSSelector#getErrorCount()
	 */
	public int getErrorCount() {
		int nErrors = 0;
		Iterator i = getErrors();
		while (i.hasNext()) {
			nErrors++;
			i.next();
		}
		return nErrors;
	}
}
