/*******************************************************************************
 * Copyright (c) 2008, 2013 Angelo Zerr 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:
 *     Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
 *     IBM Corporation - ongoing development
 *     Red Hat Inc. (mistria) - Fixes suggested by FindBugs
 *     Red Hat Inc. (mistria) - Bug 413348: fix stream leak
 *******************************************************************************/
package org.eclipse.e4.ui.css.core.impl.engine;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.e4.ui.css.core.dom.CSSStylableElement;
import org.eclipse.e4.ui.css.core.dom.ExtendedCSSRule;
import org.eclipse.e4.ui.css.core.dom.ExtendedDocumentCSS;
import org.eclipse.e4.ui.css.core.dom.IElementProvider;
import org.eclipse.e4.ui.css.core.dom.parsers.CSSParser;
import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyCompositeHandler;
import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler;
import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler2;
import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler2Delegate;
import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandlerProvider;
import org.eclipse.e4.ui.css.core.dom.properties.converters.ICSSValueConverter;
import org.eclipse.e4.ui.css.core.engine.CSSElementContext;
import org.eclipse.e4.ui.css.core.engine.CSSEngine;
import org.eclipse.e4.ui.css.core.engine.CSSErrorHandler;
import org.eclipse.e4.ui.css.core.exceptions.UnsupportedPropertyException;
import org.eclipse.e4.ui.css.core.impl.dom.CSSRuleListImpl;
import org.eclipse.e4.ui.css.core.impl.dom.CSSStyleSheetImpl;
import org.eclipse.e4.ui.css.core.impl.dom.DocumentCSSImpl;
import org.eclipse.e4.ui.css.core.impl.dom.ViewCSSImpl;
import org.eclipse.e4.ui.css.core.impl.sac.ExtendedSelector;
import org.eclipse.e4.ui.css.core.resources.IResourcesRegistry;
import org.eclipse.e4.ui.css.core.resources.ResourceRegistryKeyFactory;
import org.eclipse.e4.ui.css.core.util.impl.resources.ResourcesLocatorManager;
import org.eclipse.e4.ui.css.core.util.resources.IResourcesLocatorManager;
import org.eclipse.e4.ui.css.core.utils.StringUtils;
import org.w3c.css.sac.AttributeCondition;
import org.w3c.css.sac.Condition;
import org.w3c.css.sac.ConditionalSelector;
import org.w3c.css.sac.InputSource;
import org.w3c.css.sac.Selector;
import org.w3c.css.sac.SelectorList;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.css.CSSImportRule;
import org.w3c.dom.css.CSSRule;
import org.w3c.dom.css.CSSRuleList;
import org.w3c.dom.css.CSSStyleDeclaration;
import org.w3c.dom.css.CSSStyleSheet;
import org.w3c.dom.css.CSSValue;
import org.w3c.dom.css.DocumentCSS;
import org.w3c.dom.css.ViewCSS;
import org.w3c.dom.stylesheets.StyleSheet;

/**
 * Abstract CSS Engine manage style sheet parsing and store the
 * {@link CSSStyleSheet} into {@link DocumentCSS}.
 *
 * To apply styles, call the {@link #applyStyles(Object, boolean, boolean)}
 * method. This method check if {@link ICSSPropertyHandler} is registered for
 * apply the CSS property.
 *
 * @version 1.0.0
 * @author <a href="mailto:angelo.zerr@gmail.com">Angelo ZERR</a>
 *
 */
public abstract class AbstractCSSEngine implements CSSEngine {

	/**
	 * Default {@link IResourcesLocatorManager} used to get InputStream, Reader
	 * resource like Image.
	 */
	private final static IResourcesLocatorManager defaultResourcesLocatorManager = ResourcesLocatorManager.INSTANCE;

	/**
	 * w3c {@link DocumentCSS}.
	 */
	private ExtendedDocumentCSS documentCSS;

	/**
	 * w3c {@link ViewCSS}.
	 */
	private ViewCSS viewCSS;

	/**
	 * {@link IElementProvider} used to retrieve w3c Element linked to the
	 * widget.
	 */
	private IElementProvider elementProvider;

	protected boolean computeDefaultStyle = false;

	private Map<Object, CSSElementContext> elementsContext = null;

	/**
	 * CSS Error Handler to intercept error while parsing, applying styles.
	 */
	private CSSErrorHandler errorHandler;

	private IResourcesLocatorManager resourcesLocatorManager;

	private IResourcesRegistry resourcesRegistry;

	/**
	 * An ordered list of ICSSPropertyHandlerProvider
	 */
	protected List<ICSSPropertyHandlerProvider> propertyHandlerProviders = new ArrayList<ICSSPropertyHandlerProvider>();

	private Map<String, String> currentCSSPropertiesApplyed;

	private boolean throwError;

	private Map<Object, ICSSValueConverter> valueConverters = null;

	protected HashMap widgetsMap = new HashMap();

	private boolean parseImport;

	private ResourceRegistryKeyFactory keyFactory;

	public AbstractCSSEngine() {
		this(new DocumentCSSImpl());
	}

	public AbstractCSSEngine(ExtendedDocumentCSS documentCSS) {
		this.documentCSS = documentCSS;
		this.viewCSS = new ViewCSSImpl(documentCSS);
		keyFactory = new ResourceRegistryKeyFactory();
	}

	/*--------------- Parse style sheet -----------------*/

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.e4.ui.core.css.engine.CSSEngine#parseStyleSheet(java.io.Reader)
	 */
	public StyleSheet parseStyleSheet(Reader reader) throws IOException {
		InputSource source = new InputSource();
		source.setCharacterStream(reader);
		return parseStyleSheet(source);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.e4.ui.core.css.engine.CSSEngine#parseStyleSheet(java.io.InputStream)
	 */
	public StyleSheet parseStyleSheet(InputStream stream) throws IOException {
		InputSource source = new InputSource();
		source.setByteStream(stream);
		return parseStyleSheet(source);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.e4.ui.core.css.engine.CSSEngine#parseStyleSheet(org.w3c.css.sac.InputSource)
	 */
	public StyleSheet parseStyleSheet(InputSource source) throws IOException {
		// Check that CharacterStream or ByteStream is not null
		checkInputSource(source);
		CSSParser parser = makeCSSParser();
		CSSStyleSheet styleSheet = parser.parseStyleSheet(source);

		CSSRuleList rules = styleSheet.getCssRules();
		int length = rules.getLength();
		CSSRuleListImpl masterList = new CSSRuleListImpl();
		int counter;
		for (counter = 0; counter < length; counter++) {
			CSSRule rule = rules.item(counter);
			if (rule.getType() !=  CSSRule.IMPORT_RULE) {
				break;
			}
			Path p = new Path(source.getURI());
			IPath trim = p.removeLastSegments(1);

			URL url = FileLocator.resolve(new URL(trim.addTrailingSeparator().toString() + ((CSSImportRule) rule).getHref()));
			File testFile = new File(url.getFile());
			if (!testFile.exists()) {
				//look in platform default
				String path = getResourcesLocatorManager().resolve(((CSSImportRule) rule).getHref());
				testFile = new File(new URL(path).getFile());
				if (testFile.exists()) {
					url = new URL(path);
				}
			}
			InputStream stream = null;
			try {
				stream = url.openStream();
				InputSource tempStream = new InputSource();
				tempStream.setURI(url.toString());
				tempStream.setByteStream(stream);
				parseImport = true;
				styleSheet = (CSSStyleSheet) this.parseStyleSheet(tempStream);
				parseImport = false;
				CSSRuleList tempRules = styleSheet.getCssRules();
				for (int j = 0; j < tempRules.getLength(); j++) {
					masterList.add(tempRules.item(j));
				}
			} finally {
				if (stream != null) {
					stream.close();
				}
			}
		}

		//add remaining non import rules
		for (int i = counter; i < length; i++) {
			masterList.add(rules.item(i));
		}

		//final stylesheet
		CSSStyleSheetImpl s = new CSSStyleSheetImpl();
		s.setRuleList(masterList);
		if (!parseImport) {
			documentCSS.addStyleSheet(s);
		}
		return s;
	}

	/**
	 * Return true if <code>source</code> is valid and false otherwise.
	 *
	 * @param source
	 * @throws IOException
	 */
	private void checkInputSource(InputSource source) throws IOException {
		Reader reader = source.getCharacterStream();
		InputStream stream = source.getByteStream();
		if (reader == null && stream == null) {
			throw new IOException(
					"CharacterStream or ByteStream cannot be null for the InputSource.");
		}
	}

	/*--------------- Parse style declaration -----------------*/

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.e4.ui.core.css.engine.CSSEngine#parseStyleDeclaration(java.lang.String)
	 */
	public CSSStyleDeclaration parseStyleDeclaration(String style)
			throws IOException {
		Reader reader = new StringReader(style);
		return parseStyleDeclaration(reader);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.e4.ui.core.css.engine.CSSEngine#parseStyleDeclaration(java.io.Reader)
	 */
	public CSSStyleDeclaration parseStyleDeclaration(Reader reader)
			throws IOException {
		InputSource source = new InputSource();
		source.setCharacterStream(reader);
		return parseStyleDeclaration(source);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.e4.ui.core.css.engine.CSSEngine#parseStyleDeclaration(java.io.InputStream)
	 */
	public CSSStyleDeclaration parseStyleDeclaration(InputStream stream)
			throws IOException {
		InputSource source = new InputSource();
		source.setByteStream(stream);
		return parseStyleDeclaration(source);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.e4.ui.core.css.engine.CSSEngine#parseStyleDeclaration(org.w3c.css.sac.InputSource)
	 */
	public CSSStyleDeclaration parseStyleDeclaration(InputSource source)
			throws IOException {
		checkInputSource(source);
		CSSParser parser = makeCSSParser();
		CSSStyleDeclaration styleDeclaration = parser
				.parseStyleDeclaration(source);
		return styleDeclaration;
	}

	/*--------------- Parse CSS Selector -----------------*/

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.eclipse.e4.ui.core.css.engine.CSSEngine#parseSelectors(java.lang.
	 * String)
	 */
	public SelectorList parseSelectors(String selector) throws IOException {
		Reader reader = new StringReader(selector);
		return parseSelectors(reader);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.eclipse.e4.ui.core.css.engine.CSSEngine#parseSelectors(java.io.Reader
	 * )
	 */
	public SelectorList parseSelectors(Reader reader) throws IOException {
		InputSource source = new InputSource();
		source.setCharacterStream(reader);
		return parseSelectors(source);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.e4.ui.core.css.engine.CSSEngine#parseSelectors(java.io.
	 * InputStream)
	 */
	public SelectorList parseSelectors(InputStream stream) throws IOException {
		InputSource source = new InputSource();
		source.setByteStream(stream);
		return parseSelectors(source);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.eclipse.e4.ui.core.css.engine.CSSEngine#parseSelectors(org.w3c.css
	 * .sac.InputSource)
	 */
	public SelectorList parseSelectors(InputSource source) throws IOException {
		checkInputSource(source);
		CSSParser parser = makeCSSParser();
		SelectorList list = parser.parseSelectors(source);
		return list;
	}

	/*--------------- Parse CSS Property Value-----------------*/

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.e4.ui.core.css.engine.CSSEngine#parsePropertyValue(java.io.Reader)
	 */
	public CSSValue parsePropertyValue(Reader reader) throws IOException {
		InputSource source = new InputSource();
		source.setCharacterStream(reader);
		return parsePropertyValue(source);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.e4.ui.core.css.engine.CSSEngine#parsePropertyValue(java.io.InputStream)
	 */
	public CSSValue parsePropertyValue(InputStream stream) throws IOException {
		InputSource source = new InputSource();
		source.setByteStream(stream);
		return parsePropertyValue(source);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.e4.ui.core.css.engine.CSSEngine#parsePropertyValue(java.lang.String)
	 */
	public CSSValue parsePropertyValue(String value) throws IOException {
		Reader reader = new StringReader(value);
		return parsePropertyValue(reader);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.e4.ui.core.css.engine.CSSEngine#parsePropertyValue(org.w3c.css.sac.InputSource)
	 */
	public CSSValue parsePropertyValue(InputSource source) throws IOException {
		checkInputSource(source);
		CSSParser parser = makeCSSParser();
		return parser.parsePropertyValue(source);
	}

	/*--------------- Apply styles -----------------*/

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.e4.ui.css.core.engine.CSSEngine#applyStyles(java.lang.Object,
	 *      boolean)
	 */
	public void applyStyles(Object element, boolean applyStylesToChildNodes) {
		applyStyles(element, applyStylesToChildNodes, computeDefaultStyle);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.e4.ui.css.core.engine.CSSEngine#applyStyles(java.lang.Object,
	 *      boolean, boolean)
	 */
	public void applyStyles(Object element, boolean applyStylesToChildNodes,
			boolean computeDefaultStyle) {
		Element elt = getElement(element);
		if (elt != null) {
			/*
			 * Compute new Style to apply.
			 */
			CSSStyleDeclaration style = viewCSS.getComputedStyle(elt, null);
			if (computeDefaultStyle) {
				if (applyStylesToChildNodes) {
					this.computeDefaultStyle = computeDefaultStyle;
				}
				/*
				 * Apply default style.
				 */
				applyDefaultStyleDeclaration(element, false, style, null);
			}

			/*
			 * Manage static pseudo instances
			 */
			String[] pseudoInstances = getStaticPseudoInstances(elt);
			if (pseudoInstances != null) {
				// there are static pseudo instances definied, loop for it and
				// apply styles for each pseudo instance.
				for (String pseudoInstance : pseudoInstances) {
					CSSStyleDeclaration styleWithPseudoInstance = viewCSS
							.getComputedStyle(elt, pseudoInstance);
					if (computeDefaultStyle) {
						/*
						 * Apply default style for the current pseudo instance.
						 */
						applyDefaultStyleDeclaration(element, false,
								styleWithPseudoInstance, pseudoInstance);
					}

					if (styleWithPseudoInstance != null) {
						CSSRule parentRule = styleWithPseudoInstance.getParentRule();
						if (parentRule instanceof ExtendedCSSRule) {
							applyConditionalPseudoStyle((ExtendedCSSRule) parentRule, pseudoInstance, element, styleWithPseudoInstance);
						} else {
							//							applyStyleDeclaration(element, styleWithPseudoInstance,
							//									pseudoInstance);
							applyStyleDeclaration(elt, styleWithPseudoInstance, pseudoInstance);
						}
					}
				}
			}

			if (style != null) {
				//applyStyleDeclaration(element, style, null);
				applyStyleDeclaration(elt, style, null);
			}
			try {
				// Apply inline style
				applyInlineStyle(elt, false);
			} catch (Exception e) {
				handleExceptions(e);
			}

			if (applyStylesToChildNodes) {
				/*
				 * Style all children recursive.
				 */
				NodeList nodes = elt.getChildNodes();
				if (nodes != null) {
					for (int k = 0; k < nodes.getLength(); k++) {
						applyStyles(nodes.item(k), applyStylesToChildNodes);
					}
					onStylesAppliedToChildNodes(elt, nodes);
				}
			}
		}

	}

	private void applyConditionalPseudoStyle(ExtendedCSSRule parentRule, String pseudoInstance, Object element, CSSStyleDeclaration styleWithPseudoInstance) {
		SelectorList selectorList = parentRule.getSelectorList();
		for (int j = 0; j < selectorList.getLength(); j++) {
			Selector item = selectorList.item(j);
			// search for conditional selectors
			if (item instanceof ConditionalSelector) {
				Condition condition = ((ConditionalSelector) item).getCondition();
				// we're only interested in attribute selector conditions
				if (condition instanceof AttributeCondition) {
					String value = ((AttributeCondition) condition).getValue();
					if (value.equals(pseudoInstance)) {
						// if we match the pseudo, apply the style
						applyStyleDeclaration(element, styleWithPseudoInstance,
								pseudoInstance);
						return;
					}
				}
			}
		}
	}

	protected String[] getStaticPseudoInstances(Element element) {
		if (element instanceof CSSStylableElement) {
			CSSStylableElement stylableElement = (CSSStylableElement) element;
			return stylableElement.getStaticPseudoInstances();
		}
		return null;
	}

	/**
	 * Callback method called when styles applied of <code>nodes</code>
	 * children of the <code>element</code>.
	 *
	 * @param element
	 * @param nodes
	 */
	protected void onStylesAppliedToChildNodes(Element element, NodeList nodes) {
		if (element instanceof CSSStylableElement) {
			((CSSStylableElement) element).onStylesApplied(nodes);
		}
	}

	/*--------------- Apply style declaration -----------------*/

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.e4.ui.core.css.engine.CSSEngine#applyStyleDeclaration(java.lang.Object,
	 *      org.w3c.dom.css.CSSStyleDeclaration, java.lang.String)
	 */
	public void applyStyleDeclaration(Object element,
			CSSStyleDeclaration style, String pseudo) {
		// Apply style
		boolean avoidanceCacheInstalled = currentCSSPropertiesApplyed == null;
		if (avoidanceCacheInstalled) {
			currentCSSPropertiesApplyed = new HashMap<String, String>();
		}
		List<ICSSPropertyHandler2> handlers2 = null;
		for (int i = 0; i < style.getLength(); i++) {
			String property = style.item(i);
			CSSValue value = style.getPropertyCSSValue(property);
			try {
				ICSSPropertyHandler handler = this.applyCSSProperty(element,
						property, value, pseudo);
				ICSSPropertyHandler2 propertyHandler2 = null;
				if (handler instanceof ICSSPropertyHandler2) {
					propertyHandler2 = (ICSSPropertyHandler2) handler;
				} else {
					if (handler instanceof ICSSPropertyHandler2Delegate) {
						propertyHandler2 = ((ICSSPropertyHandler2Delegate) handler)
								.getCSSPropertyHandler2();
					}
				}
				if (propertyHandler2 != null) {
					if (handlers2 == null) {
						handlers2 = new ArrayList<ICSSPropertyHandler2>();
					}
					if (!handlers2.contains(propertyHandler2)) {
						handlers2.add(propertyHandler2);
					}
				}
			} catch (Exception e) {
				if (throwError
						|| (!throwError && !(e instanceof UnsupportedPropertyException))) {
					handleExceptions(e);
				}
			}
		}
		if (handlers2 != null) {
			for (ICSSPropertyHandler2 handler2 : handlers2) {
				try {
					handler2.onAllCSSPropertiesApplyed(element, this);
				} catch (Exception e) {
					handleExceptions(e);
				}
			}
		}
		if (avoidanceCacheInstalled) {
			currentCSSPropertiesApplyed = null;
		}

	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.e4.ui.core.css.engine.CSSEngine#parseAndApplyStyleDeclaration(java.io.Reader,
	 *      java.lang.Object)
	 */
	public CSSStyleDeclaration parseAndApplyStyleDeclaration(Object node,
			Reader reader) throws IOException {
		CSSStyleDeclaration style = parseStyleDeclaration(reader);
		this.applyStyleDeclaration(node, style, null);
		return style;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.e4.ui.core.css.engine.CSSEngine#parseAndApplyStyleDeclaration(java.io.InputStream,
	 *      java.lang.Object)
	 */
	public CSSStyleDeclaration parseAndApplyStyleDeclaration(Object node,
			InputStream stream) throws IOException {
		CSSStyleDeclaration style = parseStyleDeclaration(stream);
		this.applyStyleDeclaration(node, style, null);
		return style;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.e4.ui.core.css.engine.CSSEngine#parseAndApplyStyleDeclaration(org.w3c.css.sac.InputSource,
	 *      java.lang.Object)
	 */
	public CSSStyleDeclaration parseAndApplyStyleDeclaration(Object node,
			InputSource source) throws IOException {
		CSSStyleDeclaration style = parseStyleDeclaration(source);
		this.applyStyleDeclaration(node, style, null);
		return style;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.e4.ui.core.css.engine.CSSEngine#parseAndApplyStyleDeclaration(java.lang.Object,
	 *      java.lang.String)
	 */
	public CSSStyleDeclaration parseAndApplyStyleDeclaration(Object node,
			String style) throws IOException {
		CSSStyleDeclaration styleDeclaration = parseStyleDeclaration(style);
		this.applyStyleDeclaration(node, styleDeclaration, null);
		return styleDeclaration;
	}

	/*--------------- Apply inline style -----------------*/

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.e4.ui.core.css.engine.CSSEngine#applyInlineStyle(java.lang.Object,
	 *      boolean)
	 */
	public void applyInlineStyle(Object node, boolean applyStylesToChildNodes)
			throws IOException {
		Element elt = getElement(node);
		if (elt != null) {
			if (elt instanceof CSSStylableElement) {
				CSSStylableElement stylableElement = (CSSStylableElement) elt;
				String style = stylableElement.getCSSStyle();
				if (style != null && style.length() > 0) {
					parseAndApplyStyleDeclaration(stylableElement
							.getNativeWidget(), style);
				}
			}
			if (applyStylesToChildNodes) {
				/*
				 * Style all children recursive.
				 */
				NodeList nodes = elt.getChildNodes();
				if (nodes != null) {
					for (int k = 0; k < nodes.getLength(); k++) {
						applyInlineStyle(nodes.item(k), applyStylesToChildNodes);
					}
				}
			}
		}
	}

	/*--------------- Initial Style -----------------*/

	public CSSStyleDeclaration getDefaultStyleDeclaration(Object element,
			String pseudoE) {
		return getDefaultStyleDeclaration(element, null, pseudoE);
	}

	public CSSStyleDeclaration getDefaultStyleDeclaration(Object widget,
			CSSStyleDeclaration newStyle, String pseudoE) {
		CSSStyleDeclaration style = null;
		for (ICSSPropertyHandlerProvider provider : propertyHandlerProviders) {
			try {
				style = provider.getDefaultCSSStyleDeclaration(this, widget,
						newStyle, pseudoE);
			} catch (Exception e) {
				handleExceptions(e);
			}
		}
		return style;
	}

	public void applyDefaultStyleDeclaration(Object element,
			boolean applyStylesToChildNodes) {
		applyDefaultStyleDeclaration(element, applyStylesToChildNodes, null,
				null);
	}

	public void applyDefaultStyleDeclaration(Object element,
			boolean applyStylesToChildNodes, CSSStyleDeclaration newStyle,
			String pseudoE) {
		// Initial styles must be computed or applied
		Element elt = getElement(element);
		if (elt != null) {
			if (elt instanceof CSSStylableElement) {
				CSSStylableElement stylableElement = (CSSStylableElement) elt;
				CSSStyleDeclaration oldDefaultStyleDeclaration = stylableElement
						.getDefaultStyleDeclaration(pseudoE);
				// CSSStyleDeclaration defaultStyleDeclaration =
				// computeDefaultStyleDeclaration(
				// stylableElement, newStyle);
				CSSStyleDeclaration defaultStyleDeclaration = getDefaultStyleDeclaration(
						element, newStyle, pseudoE);
				if (oldDefaultStyleDeclaration != null) {
					// Second apply styles, apply the initial style
					// before apply the new style
					try {
						throwError = false;
						applyStyleDeclaration(element, defaultStyleDeclaration,
								pseudoE);
					} finally {
						throwError = true;
					}
				}
			}
			if (applyStylesToChildNodes) {
				/*
				 * Style all children recursive.
				 */
				NodeList nodes = elt.getChildNodes();
				if (nodes != null) {
					for (int k = 0; k < nodes.getLength(); k++) {
						applyDefaultStyleDeclaration(nodes.item(k),
								applyStylesToChildNodes);
					}
					onStylesAppliedToChildNodes(elt, nodes);
				}
			}
		}
	}

	/**
	 * Delegates the handle method.
	 *
	 * @param element
	 *            may be a widget or a node or some object
	 * @param property
	 * @param value
	 * @param pseudo
	 */
	public ICSSPropertyHandler applyCSSProperty(Object element,
			String property,
			CSSValue value, String pseudo) throws Exception {
		if (currentCSSPropertiesApplyed != null
				&& currentCSSPropertiesApplyed.containsKey(property)) {
			// CSS Property was already applied, ignore it.
			return null;
		}

		element = getElement(element); // in case we're passed a node
		for (ICSSPropertyHandlerProvider provider : propertyHandlerProviders) {
			Collection<ICSSPropertyHandler> handlers = provider
					.getCSSPropertyHandlers(element, property);
			if (handlers == null) {
				continue;
			}
			for (ICSSPropertyHandler handler : handlers) {
				try {
					boolean result = handler.applyCSSProperty(element,
							property,
							value, pseudo, this);
					if (result) {
						// Add CSS Property to flag that this CSS Property was
						// applied.
						if (currentCSSPropertiesApplyed != null) {
							currentCSSPropertiesApplyed.put(property, property);
						}
						return handler;
					}
				} catch (Exception e) {
					if (throwError
							|| (!throwError && !(e instanceof UnsupportedPropertyException))) {
						handleExceptions(e);
					}
				}
			}
		}

		return null;
	}

	public String retrieveCSSProperty(Object element, String property,
			String pseudo) {
		try {
			element = getElement(element); // in case we're passed a node
			for (ICSSPropertyHandlerProvider provider : propertyHandlerProviders) {
				Collection<ICSSPropertyHandler> handlers = provider
						.getCSSPropertyHandlers(element, property);
				if (handlers == null) {
					continue;
				}
				for (ICSSPropertyHandler handler : handlers) {
					String value = handler.retrieveCSSProperty(element,
							property, pseudo, this);
					if (!StringUtils.isEmpty(value)) {
						return value;
					}
				}
			}
		} catch (Exception e) {
			handleExceptions(e);
		}
		return null;
	}

	public String[] getCSSCompositePropertiesNames(String property) {
		try {
			Collection<ICSSPropertyHandler> handlers = getCSSPropertyHandlers(property);
			if (handlers == null) {
				return null;
			}
			for (ICSSPropertyHandler handler : handlers) {
				if (handler instanceof ICSSPropertyCompositeHandler) {
					ICSSPropertyCompositeHandler compositeHandler = (ICSSPropertyCompositeHandler) handler;
					if (compositeHandler.isCSSPropertyComposite(property)) {
						return compositeHandler.getCSSPropertiesNames(property);
					}
				}
			}
		} catch (Exception e) {
			handleExceptions(e);
		}
		return null;
	}

	protected Collection<ICSSPropertyHandler> getCSSPropertyHandlers(
			String property) throws Exception {
		Collection<ICSSPropertyHandler> handlers = new ArrayList<ICSSPropertyHandler>();
		for (ICSSPropertyHandlerProvider provider : propertyHandlerProviders) {
			Collection<ICSSPropertyHandler> h = provider
					.getCSSPropertyHandlers(property);
			if (handlers == null) {
				handlers = h;
			} else {
				handlers = new ArrayList<ICSSPropertyHandler>(handlers);
				handlers.addAll(h);
			}
		}
		return handlers;
	}

	/**
	 * Return the set of property names and handlers for the provided node.
	 *
	 * @param node
	 * @return the property names and handlers
	 */
	public Collection<String> getCSSProperties(Object element) {
		Set<String> properties = new HashSet<String>();
		for (ICSSPropertyHandlerProvider provider : propertyHandlerProviders) {
			properties.addAll(provider.getCSSProperties(element));
		}
		return properties;
	}

	/*--------------- Dynamic pseudo classes -----------------*/

	public IElementProvider getElementProvider() {
		return elementProvider;
	}

	public void setElementProvider(IElementProvider elementProvider) {
		this.elementProvider = elementProvider;
		// this.elementsContext = null;
	}

	/**
	 * Return the w3c Element linked to the Object element.
	 *
	 * @param element
	 * @return
	 */
	public Element getElement(Object element) {
		Element elt = null;
		CSSElementContext elementContext = getCSSElementContext(element);
		if (elementContext != null) {
			if (!elementContext.elementMustBeRefreshed(elementProvider)) {
				return elementContext.getElement();
			}
		}
		if (element instanceof Element) {
			elt = (Element) element;
		} else if (elementProvider != null) {
			elt = elementProvider.getElement(element, this);
		} else if (elementProvider == null) {
			Object tmp = widgetsMap.get(element.getClass().getName());
			Class parent = element.getClass();
			while (tmp == null && parent != Object.class) {
				parent = parent.getSuperclass();
				tmp = widgetsMap.get(parent.getName());
			}
			if(tmp != null && tmp instanceof IElementProvider) {
				elt = ((IElementProvider)tmp).getElement(element, this);
			}
		}
		if (elt != null) {
			if (elementContext == null) {
				elementContext = new CSSElementContextImpl();
				Object nativeWidget = getNativeWidget(element);
				hookNativeWidget(nativeWidget);
				getElementsContext().put(nativeWidget,
						elementContext);
			}
			elementContext.setElementProvider(elementProvider);
			elementContext.setElement(elt);
			if (elt instanceof CSSStylableElement) {
				// Initialize CSS stylable element
				((CSSStylableElement)elt).initialize();
			}

		}
		return elt;
	}

	/**
	 * Called when an element context is created for a native widget and
	 * registered with this engine. Subclasses should override and install
	 * a listener on the widget that will call {@link #handleWidgetDisposed(Object)}
	 * when the widget is disposed.
	 * <p>
	 * The default implementation of this method does nothing.
	 * </p>
	 *
	 * @param widget the native widget to hook
	 */
	protected void hookNativeWidget(Object widget) {
	}

	/**
	 * Called when a widget is disposed. Removes the element context
	 * from the element contexts map and the widgets map. Overriding
	 * classes must call the super implementation.
	 */
	protected void handleWidgetDisposed(Object widget) {
		if (widgetsMap != null) {
			widgetsMap.remove(widget);
		}
		if (elementsContext != null) {
			elementsContext.remove(widget);
		}
	}

	public Object getDocument() {
		return null;
	}

	public CSSElementContext getCSSElementContext(Object element) {
		Object o = getNativeWidget(element);
		return getElementsContext().get(o);
	}

	public Object getNativeWidget(Object element) {
		Object o = element;
		if (element instanceof CSSStylableElement) {
			o = ((CSSStylableElement) o).getNativeWidget();
		}
		return o;
	}

	protected Map<Object, CSSElementContext> getElementsContext() {
		if (elementsContext == null) {
			elementsContext = new HashMap<Object, CSSElementContext>();
		}
		return elementsContext;
	}

	public boolean matches(Selector selector, Object element, String pseudoElt) {
		Element elt = getElement(element);
		if (elt == null) {
			return false;
		}
		if (selector instanceof ExtendedSelector) {
			ExtendedSelector extendedSelector = (ExtendedSelector) selector;
			return extendedSelector.match(elt, pseudoElt);
		} else {
			// TODO : selector is not batik ExtendedSelector,
			// Manage this case...
		}
		return false;
	}

	/*--------------- Error Handler -----------------*/

	/**
	 * Handle exceptions thrown while parsing, applying styles. By default this
	 * method call CSS Error Handler if it is initialized.
	 *
	 */
	public void handleExceptions(Exception e) {
		if (errorHandler != null) {
			errorHandler.error(e);
		}
	}

	public CSSErrorHandler getErrorHandler() {
		return errorHandler;
	}

	/**
	 * Set the CSS Error Handler to manage exception.
	 */
	public void setErrorHandler(CSSErrorHandler errorHandler) {
		this.errorHandler = errorHandler;
	}

	/*--------------- Resources Locator Manager -----------------*/

	public IResourcesLocatorManager getResourcesLocatorManager() {
		if (resourcesLocatorManager == null) {
			return defaultResourcesLocatorManager;
		}
		return resourcesLocatorManager;
	}

	public void setResourcesLocatorManager(
			IResourcesLocatorManager resourcesLocatorManager) {
		this.resourcesLocatorManager = resourcesLocatorManager;
	}

	/*--------------- Document/View CSS -----------------*/

	public DocumentCSS getDocumentCSS() {
		return documentCSS;
	}

	public ViewCSS getViewCSS() {
		return viewCSS;
	}

	public void dispose() {
		reset();
		// Call dispose for each CSSStylableElement which was registered
		Collection<CSSElementContext> contexts = elementsContext.values();
		for (CSSElementContext context : contexts) {
			Element element = context.getElement();
			if (element instanceof CSSStylableElement) {
				((CSSStylableElement) element).dispose();
			}
		}
		elementsContext = null;
		widgetsMap = null;
		if (resourcesRegistry != null) {
			resourcesRegistry.dispose();
		}
	}

	public void reset() {
		// Remove All Style Sheets
		documentCSS.removeAllStyleSheets();
	}

	/*--------------- Resources Registry -----------------*/

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.e4.ui.css.core.engine.CSSEngine#getResourcesRegistry()
	 */
	public IResourcesRegistry getResourcesRegistry() {
		return resourcesRegistry;
	}

	public void setResourcesRegistry(IResourcesRegistry resourcesRegistry) {
		this.resourcesRegistry = resourcesRegistry;
	}

	public void registerCSSPropertyHandlerProvider(
			ICSSPropertyHandlerProvider handlerProvider) {
		propertyHandlerProviders.add(handlerProvider);
	}

	public void unregisterCSSPropertyHandlerProvider(
			ICSSPropertyHandlerProvider handlerProvider) {
		propertyHandlerProviders.remove(handlerProvider);
	}

	/*--------------- CSS Value Converter -----------------*/

	public void registerCSSValueConverter(ICSSValueConverter converter) {
		if (valueConverters == null) {
			valueConverters = new HashMap<Object, ICSSValueConverter>();
		}
		valueConverters.put(converter.getToType(), converter);
	}

	public void unregisterCSSValueConverter(ICSSValueConverter converter) {
		if (valueConverters == null) {
			return;
		}
		valueConverters.remove(converter);
	}

	public ICSSValueConverter getCSSValueConverter(Object toType) {
		if (valueConverters != null) {
			return valueConverters.get(toType);
		}
		return null;
	}

	public Object convert(CSSValue value, Object toType, Object context)
			throws Exception {
		Object key = keyFactory.createKey(value);
		Object newValue = getResource(toType, key);

		if (newValue == null) {
			ICSSValueConverter converter = getCSSValueConverter(toType);
			if (converter != null) {
				newValue = converter.convert(value, this, context);
				// cache it
				registerResource(toType, key, newValue);
			}
		}
		return newValue;
	}

	private Object getResource(Object toType, Object key) {
		if (key != null && getResourcesRegistry() != null) {
			return getResourcesRegistry().getResource(toType, key);
		}
		return null;
	}

	private void registerResource(Object toType, Object key, Object resource) {
		if (key != null && resource != null && getResourcesRegistry() != null) {
			getResourcesRegistry().registerResource(toType, key, resource);
		}
	}

	public String convert(Object value, Object toType, Object context)
			throws Exception {
		if (value == null) {
			return null;
		}
		ICSSValueConverter converter = getCSSValueConverter(toType);
		if (converter != null) {
			return converter.convert(value, this, context);
		}
		return null;
	}

	/*--------------- Abstract methods -----------------*/

	/**
	 * Return instance of CSS Parser.
	 */
	public abstract CSSParser makeCSSParser();

	protected void setResourceRegistryKeyFactory(
			ResourceRegistryKeyFactory keyFactory) {
		this.keyFactory = keyFactory;
	}
}
