/*******************************************************************************
 * 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.internal.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.internal.provisional.adapters.IStyleSheetAdapter;
import org.eclipse.wst.css.core.internal.provisional.adapters.IStyleSheetListAdapter;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSImportRule;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSModel;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSNode;
import org.eclipse.wst.css.core.internal.util.CSSClassTraverser;
import org.eclipse.wst.css.core.internal.util.ImportRuleCollector;
import org.eclipse.wst.html.core.internal.contentmodel.JSP11Namespace;
import org.eclipse.wst.html.core.internal.provisional.HTML40Namespace;
import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
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) {
		IDOMElement element = (IDOMElement) 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;
		IDOMElement element = (IDOMElement) 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;
	}
}