/*******************************************************************************
 * Copyright (c) 2004, 2011 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;
	}
}
