/*******************************************************************************
 * Copyright (c) 2001, 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.css.core.internal.document;



import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import org.eclipse.wst.css.core.internal.event.ICSSStyleListener;
import org.eclipse.wst.css.core.internal.eventimpl.CSSEmbededStyleNotifyAdapter;
import org.eclipse.wst.css.core.internal.eventimpl.CSSStyleNotifyAdapter;
import org.eclipse.wst.css.core.internal.parser.CSSSourceParser;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSAttr;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSDocument;
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.provisional.document.ICSSSelector;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSSelectorList;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSStyleDeclaration;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSStyleRule;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSValue;
import org.eclipse.wst.css.core.internal.util.ImportRuleCollector;
import org.eclipse.wst.css.core.internal.util.ImportedCollector;
import org.eclipse.wst.css.core.internal.util.SelectorsCollector;
import org.eclipse.wst.sse.core.internal.ltk.parser.RegionParser;
import org.eclipse.wst.sse.core.internal.model.AbstractStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.sse.core.internal.provisional.events.IStructuredDocumentListener;
import org.eclipse.wst.sse.core.internal.provisional.events.NewDocumentEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.NoChangeEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.RegionChangedEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.RegionsReplacedEvent;
import org.eclipse.wst.sse.core.internal.provisional.events.StructuredDocumentRegionsReplacedEvent;
import org.eclipse.wst.sse.core.internal.provisional.exceptions.ResourceInUse;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegionList;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
import org.eclipse.wst.sse.core.internal.util.Assert;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.w3c.dom.Element;
import org.w3c.dom.Node;



public class CSSModelImpl extends AbstractStructuredModel implements ICSSModel, IStructuredDocumentListener {

	private CSSDocumentImpl document = null;
	private org.w3c.dom.Node ownerNode = null;
	private CSSStyleNotifyAdapter styleNotifier = null;
	private CSSModelParser fParser = null;
	private CSSModelUpdater fUpdater = null;
	private boolean fStructuredDocumentUpdate = false;
	private final static String ID_NON_EXTERNAL_CSS = "**_NON_EXTERNAL_CSS_***";//$NON-NLS-1$

	/**
	 * CSSModelImpl constructor comment.
	 * 
	 */
	public CSSModelImpl() {
		super();
	}

	/**
	 * @param listener
	 *            org.eclipse.wst.css.core.event.CSSStyleListener
	 */
	public void addStyleListener(ICSSStyleListener listener) {
		getStyleNotifier().addStyleListener(listener);
	}

	void attrReplaced(CSSNodeImpl parentNode, CSSNodeImpl newAttr, CSSNodeImpl oldAttr) {
		if (!fStructuredDocumentUpdate) {
			CSSModelUpdater updater = getUpdater();
			updater.attrReplaced(parentNode, newAttr, oldAttr);
		}

		ICSSSelector removed[] = null, added[] = null;
		if (oldAttr != null && oldAttr.getNodeType() == ICSSNode.ATTR_NODE && ((CSSAttrImpl) oldAttr).getName().equals(ICSSStyleRule.SELECTOR)) {
			CSSAttrImpl attr = (CSSAttrImpl) oldAttr;
			// collect changed selector
			ICSSSelectorList list = new CSSSelectorListImpl(attr.getValue());
			removed = new ICSSSelector[list.getLength()];
			for (int i = 0; i < list.getLength(); i++)
				removed[i] = list.getSelector(i);
		}
		if (newAttr != null && newAttr.getNodeType() == ICSSNode.ATTR_NODE && ((CSSAttrImpl) newAttr).getName().equals(ICSSStyleRule.SELECTOR)) {
			CSSAttrImpl attr = (CSSAttrImpl) newAttr;
			// collect changed selector
			ICSSSelectorList list = new CSSSelectorListImpl(attr.getValue());
			added = new ICSSSelector[list.getLength()];
			for (int i = 0; i < list.getLength(); i++)
				added[i] = list.getSelector(i);
		}
		if (removed != null || added != null || getDocument().getNodeType() == ICSSNode.STYLEDECLARATION_NODE) {
			getStyleNotifier().fire(removed, added, null);
		}
		// for href attribute
		if (getStyleListeners() != null && getStyleListeners().size() > 0) {
			boolean update = false;
			if (oldAttr != null && oldAttr.getNodeType() == ICSSNode.ATTR_NODE && ((CSSAttrImpl) oldAttr).getName().equals(ICSSImportRule.HREF)) {
				update = true;
			}
			if (newAttr != null && newAttr.getNodeType() == ICSSNode.ATTR_NODE && ((CSSAttrImpl) newAttr).getName().equals(ICSSImportRule.HREF)) {
				update = true;
			}
			if (update)
				((ICSSImportRule) parentNode).getStyleSheet();
		}
	}

	/**
	 * 
	 */
	public void beginRecording(Object requester, String label, String description) {
		getStyleNotifier().beginRecording();

		Node node = getOwnerDOMNode();
		if (node != null && node instanceof IDOMNode) {
			IStructuredModel model = ((IDOMNode) node).getModel();
			if (model != null) {
				model.beginRecording(requester, label, description);
				return;
			}
		}
		super.beginRecording(requester, label, description);
	}

	void childReplaced(CSSNodeImpl parentNode, CSSNodeImpl newChild, CSSNodeImpl oldChild) {
		if (!fStructuredDocumentUpdate) {
			CSSModelUpdater updater = getUpdater();
			updater.childReplaced(parentNode, newChild, oldChild);
		}

		// always check and send selector event
		ICSSSelector removed[] = null, added[] = null;
		if (parentNode.getNodeType() == ICSSNode.STYLESHEET_NODE || parentNode.getNodeType() == ICSSNode.MEDIARULE_NODE) {
			// collect old selectors
			SelectorsCollector selTrav = new SelectorsCollector();
			selTrav.apply(oldChild);
			int nSel = selTrav.getSelectors().size();
			if (nSel > 0) {
				removed = new ICSSSelector[nSel];
				for (int i = 0; i < nSel; i++)
					removed[i] = (ICSSSelector) selTrav.getSelectors().get(i);
			}
			// collect new selectors
			selTrav = new SelectorsCollector();
			selTrav.apply(newChild);
			nSel = selTrav.getSelectors().size();
			if (nSel > 0) {
				added = new ICSSSelector[nSel];
				for (int i = 0; i < nSel; i++)
					added[i] = (ICSSSelector) selTrav.getSelectors().get(i);
			}
		}
		else {
			// modification
			ICSSNode rule = parentNode;
			while (rule != null) {
				if (rule instanceof ICSSStyleRule)
					break;
				rule = rule.getParentNode();
			}
			if (rule != null) {
				ICSSSelectorList list = ((ICSSStyleRule) rule).getSelectors();
				added = new ICSSSelector[list.getLength()];
				for (int i = 0; i < list.getLength(); i++)
					added[i] = list.getSelector(i);
			}
		}
		if (removed != null || added != null || getDocument().getNodeType() == ICSSNode.STYLEDECLARATION_NODE) {
			// send selector changed event
			getStyleNotifier().fire(removed, added, null);
		}
		// close removed import-rule's external style sheets
		{
			ImportRuleCollector trav = new ImportRuleCollector();
			trav.apply(oldChild);
			Iterator it = trav.getRules().iterator();
			while (it.hasNext()) {
				((CSSImportRuleImpl) it.next()).closeStyleSheet();
			}
		}
		// send events to listener for new import-rules
		if (getStyleListeners() != null && getStyleListeners().size() > 0) {
			ImportedCollector trav = new ImportedCollector();
			trav.apply(newChild);
		}
	}

	/**
	 * 
	 */
	private void closeImported() {
		if (!isShared()) {
			// release listeners
			if (getStyleListeners() != null) {
				Vector toRemove = new Vector(getStyleListeners());
				Iterator it = toRemove.iterator();
				while (it.hasNext()) {
					removeStyleListener((ICSSStyleListener) it.next());
				}
			}
			// close import rules
			ImportRuleCollector trav = new ImportRuleCollector();
			trav.apply(getDocument());
			Iterator it2 = trav.getRules().iterator();
			while (it2.hasNext()) {
				((CSSImportRuleImpl) it2.next()).releaseRule();
			}
		}
	}

	private CSSDocumentImpl createDocument() {
		CSSDocumentImpl doc = null;
		int parserMode = CSSSourceParser.MODE_STYLESHEET;
		if (ownerNode == null) {
			// this case is external CSS file
			doc = (CSSStyleSheetImpl) DOMCSSImpl.createCSSStyleSheet(null, null); // parameters
			// are
			// for
			// STYLE-tag
			parserMode = CSSSourceParser.MODE_STYLESHEET;
		}
		else if (ownerNode instanceof org.w3c.dom.Element && ((Element) ownerNode).getTagName().toUpperCase().equals("STYLE")) {//$NON-NLS-1$
			// this case is STYLE-tag
			Element style = (Element) ownerNode;
			doc = (CSSStyleSheetImpl) DOMCSSImpl.createCSSStyleSheet(style.getAttribute("TITLE"), //$NON-NLS-1$
						style.getAttribute("MEDIA"));//$NON-NLS-1$
			parserMode = CSSSourceParser.MODE_STYLESHEET;
		}
		else if (ownerNode instanceof org.w3c.dom.Element || ownerNode instanceof org.w3c.dom.Attr) {
			// Inline attributes
			doc = (CSSStyleDeclarationImpl) DOMCSSImpl.createCSSStyleDeclaration();
			parserMode = CSSSourceParser.MODE_DECLARATION;
		}
		RegionParser regionParser = getStructuredDocument().getParser();
		if (regionParser instanceof CSSSourceParser) {
			((CSSSourceParser) regionParser).setParserMode(parserMode);
		}
		return doc;
	}

	/**
	 * 
	 */
	public void endRecording(Object requester) {
		Node node = getOwnerDOMNode();
		if (node != null && node instanceof IDOMNode) {
			IStructuredModel model = ((IDOMNode) node).getModel();
			if (model != null) {
				model.endRecording(requester);
				return;
			}
		}
		super.endRecording(requester);

		getStyleNotifier().endRecording();
	}

	public ICSSDocument getDocument() {
		if (document == null) {
			this.document = createDocument();
			this.document.setModel(this);
		}
		return this.document;
	}

	public IStructuredDocument getStructuredDocument() {
		IStructuredDocument structuredDocument = null;
		structuredDocument = super.getStructuredDocument();
		if (structuredDocument != null)
			return structuredDocument;

		// the first time
		Assert.isNotNull(getModelHandler());
		structuredDocument = (IStructuredDocument) getModelHandler().getDocumentLoader().createNewStructuredDocument();

		setStructuredDocument(structuredDocument);
		return structuredDocument;
	}

	/**
	 * getNode method comment.
	 */
	public IndexedRegion getIndexedRegion(int offset) {
		if (getDocument() == null)
			return null;
		return ((CSSStructuredDocumentRegionContainer) getDocument()).getContainerNode(offset);
	}

	/**
	 * @return org.w3c.dom.Node
	 */
	public Node getOwnerDOMNode() {
		return ownerNode;
	}

	/**
	 * @param ownerNode
	 *            org.w3c.dom.Node if the case of external CSS model, you
	 *            should set null, else if internal css, you should set
	 *            STYLE-tag node, else if inline css, you should set the
	 *            element that is the owner of style-attribute.
	 */
	public void setOwnerDOMNode(Node node) {
		// prohibit owner change
		Assert.isTrue(ownerNode == null);
		ownerNode = node;
		if (ownerNode != null) { // for internal/inline CSS context
			try {
				setId(ID_NON_EXTERNAL_CSS);
			}
			catch (ResourceInUse e) {
				// impossible
			}
		}
	}

	/**
	 * 
	 */
	private CSSModelParser getParser() {
		if (fParser == null) {
			if (getDocument() != null) {
				fParser = new CSSModelParser(document);
			}
		}
		return fParser;
	}

	/**
	 * @return java.util.List
	 */
	public List getStyleListeners() {
		return getStyleNotifier().getStyleListeners();
	}

	/**
	 * 
	 * @return java.lang.Object
	 */
	public java.lang.Object getStyleSheetType() {
		if (getDocument() instanceof ICSSStyleDeclaration)
			return INLINE;
		if (getOwnerDOMNode() != null)
			return EMBEDDED;
		else
			return EXTERNAL;
	}

	private CSSStyleNotifyAdapter getStyleNotifier() {
		if (styleNotifier == null) {
			styleNotifier = (ownerNode != null) ? new CSSEmbededStyleNotifyAdapter(this) : new CSSStyleNotifyAdapter(this);
		}
		return styleNotifier;
	}

	/**
	 * 
	 */
	private CSSModelUpdater getUpdater() {
		if (fUpdater == null) {
			fUpdater = new CSSModelUpdater(this);
			fUpdater.setParser(getParser());
		}
		return fUpdater;
	}

	/**
	 */
	public boolean isRecording() {
		return getStyleNotifier().isRecording();
	}

	/**
	 * This function returns true if there are other references to the
	 * underlying model.
	 */
	public boolean isShared() {
		return (getStyleSheetType() == EXTERNAL) && super.isShared();
	}

	public void newModel(NewDocumentEvent structuredDocumentEvent) {
		if (structuredDocumentEvent == null)
			return;
		IStructuredDocument structuredDocument = structuredDocumentEvent.getStructuredDocument();
		if (structuredDocument == null)
			return;
		// this should not happen, but for the case
		if (structuredDocument != getStructuredDocument())
			setStructuredDocument(structuredDocument);
		IStructuredDocumentRegionList flatNodes = structuredDocument.getRegionList();
		if (flatNodes == null)
			return;
		if (getDocument() == null)
			return;

		fStructuredDocumentUpdate = true;

		((CSSStructuredDocumentRegionContainer) getDocument()).removeChildNodes();

		CSSModelParser parser = getParser();
		parser.setStructuredDocumentEvent(structuredDocumentEvent);
		parser.replaceStructuredDocumentRegions(flatNodes, null);

		fStructuredDocumentUpdate = false;
	}

	/**
	 * noChange method comment.
	 */
	public void noChange(NoChangeEvent structuredDocumentEvent) {
		// nop
	}

	public void nodesReplaced(StructuredDocumentRegionsReplacedEvent structuredDocumentEvent) {
		if (structuredDocumentEvent == null) {
			return;
		}
		IStructuredDocumentRegionList oldStructuredDocumentRegions = structuredDocumentEvent.getOldStructuredDocumentRegions();
		IStructuredDocumentRegionList newStructuredDocumentRegions = structuredDocumentEvent.getNewStructuredDocumentRegions();
		if (oldStructuredDocumentRegions == null && newStructuredDocumentRegions == null) {
			return;
		}

		fStructuredDocumentUpdate = true;

		CSSModelParser parser = getParser();
		parser.setStructuredDocumentEvent(structuredDocumentEvent);
		parser.replaceStructuredDocumentRegions(newStructuredDocumentRegions, oldStructuredDocumentRegions);

		fStructuredDocumentUpdate = false;
	}

	/**
	 * cleanup -> rebuild CSS Nodes This is pre-beta fix for 178176.
	 */
	public void refreshNodes() {
		// cleanup old nodes
		fStructuredDocumentUpdate = true;
		((CSSStructuredDocumentRegionContainer) getDocument()).removeChildNodes();
		fStructuredDocumentUpdate = false;

		getParser().cleanupUpdateContext();

		IStructuredDocument structuredDocument = getStructuredDocument();
		String source = structuredDocument.getText();

		structuredDocument.replaceText(this, 0, source.length(), null);
		structuredDocument.replaceText(this, 0, 0, source);
	}

	public void regionChanged(RegionChangedEvent structuredDocumentEvent) {
		if (structuredDocumentEvent == null) {
			return;
		}
		IStructuredDocumentRegion flatNode = structuredDocumentEvent.getStructuredDocumentRegion();
		if (flatNode == null) {
			return;
		}
		ITextRegion region = structuredDocumentEvent.getRegion();
		if (region == null) {
			return;
		}

		fStructuredDocumentUpdate = true;

		CSSModelParser parser = getParser();
		parser.setStructuredDocumentEvent(structuredDocumentEvent);
		parser.changeRegion(flatNode, region);

		fStructuredDocumentUpdate = false;
	}

	public void regionsReplaced(RegionsReplacedEvent structuredDocumentEvent) {
		if (structuredDocumentEvent == null)
			return;
		IStructuredDocumentRegion flatNode = structuredDocumentEvent.getStructuredDocumentRegion();
		if (flatNode == null)
			return;
		ITextRegionList oldRegions = structuredDocumentEvent.getOldRegions();
		ITextRegionList newRegions = structuredDocumentEvent.getNewRegions();
		if (oldRegions == null && newRegions == null)
			return;

		fStructuredDocumentUpdate = true;

		CSSModelParser parser = getParser();
		parser.setStructuredDocumentEvent(structuredDocumentEvent);
		parser.replaceRegions(flatNode, newRegions, oldRegions);

		fStructuredDocumentUpdate = false;

	}

	/**
	 * 
	 */
	public void releaseFromEdit() {
		closeImported();
		if (getStyleSheetType() == EXTERNAL) {
			super.releaseFromEdit();
		}
	}

	/**
	 * 
	 */
	public void releaseFromRead() {
		closeImported();
		if (getStyleSheetType() == EXTERNAL) {
			super.releaseFromRead();
		}
	}

	/**
	 * @param listener
	 *            org.eclipse.wst.css.core.event.CSSStyleListener
	 */
	public void removeStyleListener(ICSSStyleListener listener) {
		getStyleNotifier().removeStyleListener(listener);
	}

	public void setStructuredDocument(IStructuredDocument newStructuredDocument) {
		IStructuredDocument oldStructuredDocument = super.getStructuredDocument();
		if (newStructuredDocument == oldStructuredDocument)
			return; // noting to do

		if (oldStructuredDocument != null)
			oldStructuredDocument.removeDocumentChangingListener(this);
		super.setStructuredDocument(newStructuredDocument);

		if (newStructuredDocument != null) {
			if (newStructuredDocument.getLength() > 0) {
				newModel(new NewDocumentEvent(newStructuredDocument, this));
			}
			newStructuredDocument.addDocumentChangingListener(this);
		}
	}

	/**
	 * @param srcModel
	 *            com.imb.sed.css.mode.intefaces.ICSSModel
	 * @param removed
	 *            org.eclipse.wst.css.core.model.interfaces.ICSSSelector[]
	 * @param added
	 *            org.eclipse.wst.css.core.model.interfaces.ICSSSelector[]
	 */
	public void styleChanged(ICSSModel srcModel, ICSSSelector[] removed, ICSSSelector[] added, String media) {
		getStyleNotifier().styleChanged(srcModel, removed, added, media);
	}

	/**
	 * @param srcModel
	 *            org.eclipse.wst.css.core.model.interfaces.ICSSModel
	 */
	public void styleUpdate(ICSSModel srcModel) {
		getStyleNotifier().styleUpdate(srcModel);
	}

	void valueChanged(CSSNodeImpl node, String oldValue) {
		if (!fStructuredDocumentUpdate) {
			CSSModelUpdater updater = getUpdater();
			updater.valueChanged(node, oldValue);
		}

		ICSSSelector removed[] = null, added[] = null;
		if (node != null) {
			if (node.getNodeType() == ICSSNode.ATTR_NODE && ((CSSAttrImpl) node).getName().equals(ICSSStyleRule.SELECTOR)) {
				CSSAttrImpl attr = (CSSAttrImpl) node;
				// collect changed selector
				ICSSSelectorList list = new CSSSelectorListImpl(attr.getValue());
				added = new ICSSSelector[list.getLength()];
				for (int i = 0; i < list.getLength(); i++)
					added[i] = list.getSelector(i);

				// get old value
				list = new CSSSelectorListImpl(oldValue);
				removed = new ICSSSelector[list.getLength()];
				for (int i = 0; i < list.getLength(); i++)
					removed[i] = list.getSelector(i);
			}
			else if (node instanceof ICSSValue) {
				ICSSNode rule = node;
				while (rule != null) {
					if (rule instanceof ICSSStyleRule)
						break;
					rule = rule.getParentNode();
				}
				if (rule != null) {
					ICSSSelectorList list = ((ICSSStyleRule) rule).getSelectors();
					added = new ICSSSelector[list.getLength()];
					for (int i = 0; i < list.getLength(); i++)
						added[i] = list.getSelector(i);
				}
			}
		}
		if (removed != null || added != null || getDocument().getNodeType() == ICSSNode.STYLEDECLARATION_NODE) {
			// send selector changed event
			getStyleNotifier().fire(removed, added, null);
		}
		// for href attribute
		if (getStyleListeners() != null && getStyleListeners().size() > 0) {
			if (node != null && node.getNodeType() == ICSSNode.ATTR_NODE && ((CSSAttrImpl) node).getName().equals(ICSSImportRule.HREF)) {
				((ICSSImportRule) ((ICSSAttr) node).getOwnerCSSNode()).getStyleSheet();
			}
		}
	}
}