/*******************************************************************************
 * Copyright (c) 2004 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.htmlcss;



import java.util.ArrayList;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.eclipse.wst.css.core.adapters.IStyleSheetAdapter;
import org.eclipse.wst.css.core.adapters.IStyleSheetListAdapter;
import org.eclipse.wst.css.core.document.ICSSImportRule;
import org.eclipse.wst.css.core.document.ICSSModel;
import org.eclipse.wst.css.core.document.ICSSNode;
import org.eclipse.wst.css.core.util.CSSClassTraverser;
import org.eclipse.wst.css.core.util.ImportRuleCollector;
import org.eclipse.wst.html.core.HTML40Namespace;
import org.eclipse.wst.html.core.contentmodel.JSP11Namespace;
import org.eclipse.wst.sse.core.INodeAdapter;
import org.eclipse.wst.sse.core.INodeNotifier;
import org.eclipse.wst.xml.core.document.XMLElement;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.css.CSSStyleDeclaration;
import org.w3c.dom.stylesheets.StyleSheet;
import org.w3c.dom.stylesheets.StyleSheetList;



/**
 */
public class HTMLDocumentAdapter implements IStyleSheetListAdapter, StyleSheetList {

	private Document document = null;
	private Vector styleAdapters = null;
	private Vector oldStyleAdapters = null;

	/**
	 */
	HTMLDocumentAdapter() {
		super();
	}

	/**
	 */
	private void addStyleSheet(Element node) {
		XMLElement element = (XMLElement) node;
		String tagName = element.getTagName();
		if (tagName == null)
			return;
		boolean isContainer = false;
		if (tagName.equalsIgnoreCase(HTML40Namespace.ElementName.HTML) || tagName.equalsIgnoreCase(HTML40Namespace.ElementName.HEAD) || tagName.equalsIgnoreCase(HTML40Namespace.ElementName.NOSCRIPT) || tagName.equalsIgnoreCase(HTML40Namespace.ElementName.BASE) || tagName.equalsIgnoreCase(JSP11Namespace.ElementName.ROOT) || (!element.isGlobalTag() && element.isContainer())) {
			isContainer = true;
		}
		else if (element.isCommentTag()) {
			Node parent = element.getParentNode();
			if (parent == element.getOwnerDocument()) {
				// This condition is too severe, actually do not work for JSF template.
				// But above (! globalTag() && isContainer()) cover JSF template + tpl template
				isContainer = true;
			}
			else if (parent.getNodeType() == Node.ELEMENT_NODE) {
				tagName = ((Element) parent).getTagName();
				if (tagName != null && tagName.equalsIgnoreCase(HTML40Namespace.ElementName.HEAD)) {
					isContainer = true;
				}
			}
		}

		else {
			String localName = element.getLocalName();
			if (localName != null && localName.equalsIgnoreCase(HTML40Namespace.ElementName.HTML)) {
				// taglib html tag
				isContainer = true;
			}
			else {
				INodeNotifier notifier = element;
				INodeAdapter adapter = notifier.getAdapterFor(IStyleSheetAdapter.class);
				if (adapter != null && adapter instanceof IStyleSheetAdapter) {
					this.styleAdapters.addElement(adapter);
				}
			}
		}
		if (isContainer) {
			INodeNotifier notifier = element;
			if (notifier.getExistingAdapter(IStyleSheetListAdapter.class) == null) {
				notifier.addAdapter(this);
			}
			for (Node child = element.getFirstChild(); child != null; child = child.getNextSibling()) {
				if (child.getNodeType() != Node.ELEMENT_NODE)
					continue;
				addStyleSheet((Element) child);
			}
		}
	}

	/**
	 */
	void childReplaced() {
		if (this.styleAdapters == null)
			return;

		// backup old adapters to be released on updating in getStyleSheets()
		this.oldStyleAdapters = this.styleAdapters;
		// invalidate the list
		this.styleAdapters = null;

		notifyStyleSheetsChanged(this.document);
	}

	/**
	 */
	public Enumeration getClasses() {
		StyleSheetList sheetList = getStyleSheets();
		int nSheets = sheetList.getLength();

		final ArrayList classes = new ArrayList();

		CSSClassTraverser traverser = new CSSClassTraverser();
		traverser.setTraverseImported(true);

		for (int i = 0; i < nSheets; i++) {
			org.w3c.dom.stylesheets.StyleSheet sheet = sheetList.item(i);
			if (sheet instanceof ICSSNode) {
				traverser.apply((ICSSNode) sheet);
			}
		}
		classes.addAll(traverser.getClassNames());

		return new Enumeration() {
			int i = 0;

			public boolean hasMoreElements() {
				return i < classes.size();
			}

			public Object nextElement() {
				return classes.get(i++);
			}
		};
	}

	/**
	 */
	private List getValidAdapters() {
		Vector validAdapters = new Vector();
		if (this.styleAdapters != null) {
			Iterator i = this.styleAdapters.iterator();
			while (i.hasNext()) {
				Object obj = i.next();
				if (obj instanceof AbstractStyleSheetAdapter && ((AbstractStyleSheetAdapter) obj).isValidAttribute()) {
					validAdapters.add(obj);
				}
			}
		}
		return validAdapters;
	}

	/**
	 */
	public int getLength() {
		return getValidAdapters().size();
	}

	/**
	 */
	public CSSStyleDeclaration getOverrideStyle(Element element, String pseudoName) {
		StyleSheetList ssl = getStyleSheets();
		int numStyles = ssl.getLength();

		CSSQueryTraverser query = new CSSQueryTraverser();
		query.setTraverseImported(true);
		query.setTraverseImportFirst(true);
		query.setElement(element, pseudoName);

		for (int i = 0; i < numStyles; i++) {
			// loop for styles (<style> and <link>)
			org.w3c.dom.stylesheets.StyleSheet ss = ssl.item(i);

			try {
				query.apply((ICSSNode) ss);
			}
			catch (ClassCastException ex) {
				// I can handle only CSS style
			}
		}

		return query.getDeclaration();
	}

	/**
	 */
	public StyleSheetList getStyleSheets() {
		if (this.styleAdapters == null) {
			if (this.document == null)
				return null;

			this.styleAdapters = new Vector();
			for (Node child = this.document.getFirstChild(); child != null; child = child.getNextSibling()) {
				if (child.getNodeType() != Node.ELEMENT_NODE)
					continue;
				addStyleSheet((Element) child);
			}

			removeOldStyleSheets();
		}
		return this;
	}

	/**
	 * 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 == IStyleSheetListAdapter.class);
	}

	/**
	 */
	public StyleSheet item(int index) {
		if (this.styleAdapters == null)
			return null;

		List validAdapters = getValidAdapters();

		if (index < 0 || index >= validAdapters.size())
			return null;
		org.w3c.dom.stylesheets.StyleSheet sheet = ((IStyleSheetAdapter) validAdapters.get(index)).getSheet();
		if (sheet == null) {// for LINK element whose link is broken
			ICSSModel model = ((AbstractStyleSheetAdapter) this.styleAdapters.elementAt(index)).createModel();
			sheet = ((model != null) ? (StyleSheet) model.getDocument() : null);
		}
		return sheet;
	}

	/**
	 */
	public void notifyChanged(INodeNotifier notifier, int eventType, Object changedFeature, Object oldValue, Object newValue, int pos) {
		Node node = null;
		switch (eventType) {
			case INodeNotifier.ADD :
				node = (Node) newValue;
				break;
			case INodeNotifier.REMOVE :
				node = (Node) oldValue;
				break;
			case INodeNotifier.CHANGE :
				node = (Node) notifier;
				break;
			default :
				break;
		}
		if (node == null || node.getNodeType() != Node.ELEMENT_NODE)
			return;
		XMLElement element = (XMLElement) node;
		String tagName = element.getTagName();
		if (tagName == null)
			return;

		if (eventType == INodeNotifier.CHANGE) {
			if (tagName.equalsIgnoreCase(HTML40Namespace.ElementName.BASE)) {
				refreshAdapters();
			}
		}
		else {
			if (tagName.equalsIgnoreCase(HTML40Namespace.ElementName.HTML) || tagName.equalsIgnoreCase(HTML40Namespace.ElementName.HEAD) || tagName.equalsIgnoreCase(HTML40Namespace.ElementName.STYLE) || tagName.equalsIgnoreCase(HTML40Namespace.ElementName.LINK) || tagName.equalsIgnoreCase(HTML40Namespace.ElementName.NOSCRIPT) || tagName.equalsIgnoreCase(JSP11Namespace.ElementName.ROOT) || element.isCommentTag() || (!element.isGlobalTag() && element.isContainer())) {
				childReplaced();
			}
			else if (tagName.equalsIgnoreCase(HTML40Namespace.ElementName.BASE)) {
				refreshAdapters();
			}
			else {
				String localName = element.getLocalName();
				if (localName != null && localName.equalsIgnoreCase(HTML40Namespace.ElementName.HTML)) {
					// taglib html tag
					childReplaced();
				}
			}
		}
	}

	/**
	 * reload LINK / @import if BASE changed
	 */
	private void refreshAdapters() {
		Iterator iAdapter = this.styleAdapters.iterator();
		while (iAdapter.hasNext()) {
			Object adapter = iAdapter.next();
			if (adapter instanceof LinkElementAdapter) {
				((LinkElementAdapter) adapter).refreshSheet();
			}
			else if (adapter instanceof StyleElementAdapter) {
				ICSSModel model = ((StyleElementAdapter) adapter).getModel();
				ImportRuleCollector trav = new ImportRuleCollector();
				trav.apply(model);
				Iterator iRule = trav.getRules().iterator();
				while (iRule.hasNext()) {
					ICSSImportRule rule = (ICSSImportRule) iRule.next();
					rule.refreshStyleSheet();
				}
			}
		}
	}

	/**
	 */
	private void notifyStyleSheetsChanged(Document target) {
		INodeNotifier notifier = (INodeNotifier) target;
		if (notifier == null)
			return;
		Collection adapters = notifier.getAdapters();
		if (adapters == null)
			return;
		Iterator it = adapters.iterator();
		if (it == null)
			return;
		while (it.hasNext()) {
			INodeAdapter adapter = (INodeAdapter) it.next();
			if (adapter instanceof StyleListener) {
				StyleListener listener = (StyleListener) adapter;
				listener.styleChanged();
			}
		}
	}

	/**
	 */
	private void releaseOldStyleSheets() {
		if (this.oldStyleAdapters == null)
			return;
		Iterator it = this.oldStyleAdapters.iterator();
		while (it.hasNext()) {
			IStyleSheetAdapter adapter = (IStyleSheetAdapter) it.next();
			if (adapter == null)
				continue;
			// if the same adapter is in the current list,
			// do not release
			if (this.styleAdapters != null && this.styleAdapters.contains(adapter))
				continue;
			adapter.released();
		}
		this.oldStyleAdapters = null;
	}

	/**
	 */
	public void releaseStyleSheets() {
		releaseOldStyleSheets();

		if (this.styleAdapters == null)
			return;
		Iterator it = this.styleAdapters.iterator();
		while (it.hasNext()) {
			IStyleSheetAdapter adapter = (IStyleSheetAdapter) it.next();
			if (adapter != null)
				adapter.released();
		}
		this.styleAdapters = null;
	}

	/**
	 */
	private void removeOldStyleSheets() {
		if (this.oldStyleAdapters == null)
			return;
		Iterator it = this.oldStyleAdapters.iterator();
		while (it.hasNext()) {
			IStyleSheetAdapter adapter = (IStyleSheetAdapter) it.next();
			if (adapter == null)
				continue;
			// if the same adapter is in the current list,
			// do not release
			if (this.styleAdapters != null && this.styleAdapters.contains(adapter))
				continue;
			adapter.removed();
		}
		this.oldStyleAdapters = null;
	}

	/**
	 */
	void setDocument(Document document) {
		this.document = document;
	}
}