/*******************************************************************************
 * Copyright (c) 2004, 2006 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 com.ibm.icu.util.StringTokenizer;

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;


/**
 * 
 */
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) {
		try {
			element = (Element) element.getParentNode();
		}
		catch (Exception ex) {
			// cast error or null pointer ...
			element = null;
		}
		return element;
	}

	/**
	 * @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;
			key = element.getAttribute("id");//$NON-NLS-1$
			if (key == null)
				return false;
			if (!selector.getID(0).equals(key))
				return false;
		}

		// check class
		i = selector.getNumOfClasses();
		if (i > 0) {
			key = element.getAttribute("class");//$NON-NLS-1$
			if (key == null)
				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 attrValue = element.getAttribute(tokenizer.nextToken());
				if (attrValue == null)
					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;
	}
}
