/*******************************************************************************
 * 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.Iterator;

import org.eclipse.wst.css.core.internal.formatter.CSSSourceFormatterFactory;
import org.eclipse.wst.css.core.internal.formatter.CSSSourceGenerator;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSDocument;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSModel;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSNamedNodeMap;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSNode;
import org.eclipse.wst.css.core.internal.provisional.document.ICSSNodeList;
import org.eclipse.wst.css.core.internal.util.ImportRuleCollector;
import org.eclipse.wst.sse.core.internal.model.FactoryRegistry;
import org.eclipse.wst.sse.core.internal.provisional.AbstractNotifier;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.w3c.dom.DOMException;


/**
 * 
 */
public abstract class CSSNodeImpl extends AbstractNotifier implements ICSSNode, IndexedRegion {

	private CSSDocumentImpl fOwnerDocument = null;
	private CSSNodeImpl fParentNode = null;
	private CSSNodeImpl fNextSibling = null;
	private CSSNodeImpl fPreviousSibling = null;
	private CSSNodeImpl fFirstChild = null;
	private CSSNodeImpl fLastChild = null;
	protected CSSNamedNodeMapImpl fAttrs = null;

	/**
	 * CSSNodeImpl constructor comment.
	 */
	CSSNodeImpl() {
		super();
	}

	CSSNodeImpl(CSSNodeImpl that) {
		if (that != null) {
			this.fOwnerDocument = that.fOwnerDocument;
			if (that.fAttrs != null) {
				int nAttrs = that.fAttrs.getLength();
				for (int i = 0; i < nAttrs; i++) {
					CSSAttrImpl attr = (CSSAttrImpl) that.fAttrs.item(i);
					setAttribute(attr.getName(), attr.getValue());
				}
			}
		}
	}
	/**
	 * currently public but may be made default access protected in future.
	 */
	public CSSNodeImpl appendChild(CSSNodeImpl newChild) throws org.w3c.dom.DOMException {
		return insertBefore(newChild, null);
	}
	/**
	 * currently public but may be made default access protected in future.
	 */
	protected void cloneChildNodes(ICSSNode newParent, boolean deep) {
		if (newParent == null || newParent == this)
			return;

		CSSNodeImpl container = (CSSNodeImpl) newParent;
		container.removeChildNodes();

		for (ICSSNode child = getFirstChild(); child != null; child = child.getNextSibling()) {
			CSSNodeImpl cloned = (CSSNodeImpl) child.cloneNode(deep);
			if (cloned != null)
				container.appendChild(cloned);
		}
	}

	/**
	 * @return boolean
	 * @param offset
	 *            int
	 */
	public boolean contains(int offset) {
		return (getStartOffset() <= offset && offset < getEndOffset());
	}

	/**
	 *
	 * currently public but may be made default access protected in future.
	 *
	 * @return java.lang.String
	 */
	protected String generateSource() {
		CSSSourceGenerator formatter = CSSSourceFormatterFactory.getInstance().getSourceFormatter(this);
		return formatter.format(this).toString();
	}

	/**
	 *
	 * currently public but may be made default access protected in future.
	 *
	 * @return java.lang.String
	 * @param name
	 *            java.lang.String
	 */
	protected String getAttribute(String name) {
		CSSAttrImpl attr = getAttributeNode(name);
		if (attr != null)
			return attr.getValue();
		return null;
	}

	protected CSSAttrImpl getAttributeNode(String name) {
		if (fAttrs == null)
			return null;

		int nAttrs = fAttrs.getLength();
		for (int i = 0; i < nAttrs; i++) {
			CSSAttrImpl attr = (CSSAttrImpl) fAttrs.item(i);
			if (attr.matchName(name))
				return attr;
		}
		return null;
	}

	/**
	 * @return org.eclipse.wst.css.core.model.interfaces.ICSSNamedNodeMap
	 */
	public ICSSNamedNodeMap getAttributes() {
		if (fAttrs == null)
			fAttrs = new CSSNamedNodeMapImpl();
		return fAttrs;
	}

	public ICSSNodeList getChildNodes() {
		CSSNodeListImpl list = new CSSNodeListImpl();
		for (ICSSNode node = getFirstChild(); node != null; node = node.getNextSibling()) {
			list.appendNode(node);
		}
		return list;
	}

	ICSSNode getCommonAncestor(ICSSNode node) {
		if (node == null)
			return null;

		for (ICSSNode na = node; na != null; na = na.getParentNode()) {
			for (ICSSNode ta = this; ta != null; ta = ta.getParentNode()) {
				if (ta == na)
					return ta;
			}
		}

		return null; // not found
	}

	CSSDocumentImpl getContainerDocument() {
		for (ICSSNode node = this; node != null; node = node.getParentNode()) {
			if (node instanceof CSSDocumentImpl) {
				CSSDocumentImpl doc = (CSSDocumentImpl) node;
				if (doc.isDocument())
					return doc;
			}
		}
		return null;
	}

	CSSNodeImpl getContainerNode(int offset) {
		if (!contains(offset))
			return null;

		for (ICSSNode child = getFirstChild(); child != null; child = child.getNextSibling()) {
			ICSSNode found = ((CSSNodeImpl) child).getContainerNode(offset);
			if (found != null)
				return (CSSNodeImpl) found;
		}

		return this;
	}

	/**
	 */
	public FactoryRegistry getFactoryRegistry() {
		ICSSModel model = getOwnerDocument().getModel();
		if (model != null) {
			FactoryRegistry reg = model.getFactoryRegistry();
			if (reg != null)
				return reg;
		}
		return null;
	}

	public ICSSNode getFirstChild() {
		return this.fFirstChild;
	}

	public ICSSNode getLastChild() {
		return this.fLastChild;
	}

	public ICSSNode getNextSibling() {
		return this.fNextSibling;
	}

	ICSSNode getNodeAt(int offset) {
		// the same as getContainerNode()
		return getContainerNode(offset);
	}

	public ICSSDocument getOwnerDocument() {
		return this.fOwnerDocument;
	}

	public ICSSNode getParentNode() {
		return this.fParentNode;
	}

	public ICSSNode getPreviousSibling() {
		return this.fPreviousSibling;
	}

	ICSSNode getRootNode() {
		CSSNodeImpl parent = (CSSNodeImpl) getParentNode();
		if (parent == null)
			return this;
		return parent.getRootNode();
	}

	/**
	 * @return boolean
	 */
	public boolean hasChildNodes() {
		return (this.fFirstChild != null);
	}

	/**
	 * @return boolean
	 */
	public boolean hasProperties() {
		return false;
	}
	/**
	 * currently public but may be made default access protected in future.
	 */
	public CSSNodeImpl insertBefore(CSSNodeImpl newChild, CSSNodeImpl refChild) throws org.w3c.dom.DOMException {
		if (newChild == null)
			return null;

		CSSNodeImpl child = newChild;
		CSSNodeImpl next = refChild;
		CSSNodeImpl prev = null;
		if (next == null) {
			prev = this.fLastChild;
			this.fLastChild = child;
		}
		else {
			prev = (CSSNodeImpl) next.getPreviousSibling();
			next.setPreviousSibling(child);
		}

		if (prev == null)
			this.fFirstChild = child;
		else
			prev.setNextSibling(child);
		child.setPreviousSibling(prev);
		child.setNextSibling(next);
		child.setParentNode(this);

		notifyChildReplaced(child, null);

		return newChild;
	}

	protected void notifyAttrReplaced(CSSNodeImpl newAttr, CSSNodeImpl oldAttr) {
		// for model
		ICSSDocument doc = getContainerDocument();
		if (doc == null)
			return;
		CSSModelImpl model = (CSSModelImpl) doc.getModel();
		if (model == null)
			return;
		model.attrReplaced(this, newAttr, oldAttr);

		// for adapters
		int type = CHANGE;
		if (newAttr == null)
			type = REMOVE;
		else if (oldAttr == null)
			type = ADD;
		notify(type, oldAttr, oldAttr, newAttr, getStartOffset());
	}

	protected void notifyChildReplaced(CSSNodeImpl newChild, CSSNodeImpl oldChild) {
		// for model
		ICSSDocument doc = getContainerDocument();
		if (doc == null)
			return;
		CSSModelImpl model = (CSSModelImpl) doc.getModel();
		if (model == null)
			return;
		model.childReplaced(this, newChild, oldChild);

		// for adapters
		int type = CHANGE;
		if (newChild == null)
			type = REMOVE;
		else if (oldChild == null)
			type = ADD;
		notify(type, oldChild, oldChild, newChild, getStartOffset());
	}

	void removeAttributeNode(CSSNodeImpl attr) {
		// find
		int nAttrs = fAttrs.getLength();
		for (int i = 0; i < nAttrs; i++) {
			if (fAttrs.item(i) == attr) {
				fAttrs.removeNode(i);
				notifyAttrReplaced(null, attr);
				return;
			}
		}
	}

	protected CSSNodeImpl removeChild(CSSNodeImpl oldChild) throws org.w3c.dom.DOMException {
		if (oldChild == null)
			return null;
		if (oldChild.getParentNode() != this)
			return null;

		// close import rules
		ImportRuleCollector trav = new ImportRuleCollector();
		trav.apply(oldChild);
		Iterator it = trav.getRules().iterator();
		while (it.hasNext()) {
			((CSSImportRuleImpl) it.next()).closeStyleSheet();
		}

		CSSNodeImpl child = oldChild;
		CSSNodeImpl prev = (CSSNodeImpl) child.getPreviousSibling();
		CSSNodeImpl next = (CSSNodeImpl) child.getNextSibling();

		if (prev == null)
			this.fFirstChild = next;
		else
			prev.setNextSibling(next);

		if (next == null)
			this.fLastChild = prev;
		else
			next.setPreviousSibling(prev);

		child.setPreviousSibling(null);
		child.setNextSibling(null);
		child.setParentNode(null);

		notifyChildReplaced(null, child);

		return child;
	}

	/**
	 * 
	 */
	void removeChildNodes() {
		ICSSNode nextChild = null;
		for (ICSSNode child = getFirstChild(); child != null; child = nextChild) {
			nextChild = child.getNextSibling();
			removeChild((CSSNodeImpl) child);
		}
	}

	protected CSSNodeImpl replaceChild(CSSNodeImpl newChild, CSSNodeImpl oldChild) throws org.w3c.dom.DOMException {
		if (oldChild == null)
			return newChild;
		if (newChild != null)
			insertBefore(newChild, oldChild);
		return removeChild(oldChild);
	}

	/**
	 *
	 * currently public but may be made default access protected in future.
	 *
	 * @param name
	 *            java.lang.String
	 * @param value
	 *            java.lang.String
	 */
	public void setAttribute(String name, String value) {
		if (name == null)
			return;

		CSSAttrImpl attr = getAttributeNode(name);
		if (attr != null) {
			String oldValue = attr.getValue();
			if (value != null && value.equals(oldValue))
				return;
			if (value == null) {
				if (oldValue != null) {
					removeAttributeNode(attr);
				}
				return;
			}
		}
		else {
			if (value == null)
				return;
			if (fAttrs == null)
				fAttrs = new CSSNamedNodeMapImpl();
			CSSDocumentImpl doc = (CSSDocumentImpl) getOwnerDocument();
			if (doc == null)
				return;
			attr = (CSSAttrImpl) doc.createCSSAttr(name);
			attr.setOwnerCSSNode(this);
			fAttrs.appendNode(attr);
			notifyAttrReplaced(attr, null);
		}
		attr.setValue(value);
	}

	/**
	 * @param cssText
	 *            java.lang.String
	 */
	public void setCssText(String cssText) {
		// TODO : call flat model parser and replace myself with new three!!
		throw new DOMException(DOMException.INVALID_MODIFICATION_ERR, "");//$NON-NLS-1$
	}

	private void setNextSibling(ICSSNode nextSibling) {
		this.fNextSibling = (CSSNodeImpl) nextSibling;
	}
	/**
	 * currently public but may be made default access protected in future.
	 */
	public void setOwnerDocument(ICSSDocument ownerDocument) {
		this.fOwnerDocument = (CSSDocumentImpl) ownerDocument;
	}

	private void setParentNode(ICSSNode parentNode) {
		this.fParentNode = (CSSNodeImpl) parentNode;
	}

	private void setPreviousSibling(ICSSNode previousSibling) {
		this.fPreviousSibling = (CSSNodeImpl) previousSibling;
	}

	public int getLength() {
		int result = -1;
		int start = getStartOffset();
		if (start >= 0) {
			int end = getEndOffset();
			if (end >= 0) {
				result = end - start;
				if (result < -1) {
					result = -1;
				}
			}
		}
		return result;
	}
}
