/*******************************************************************************
 * Copyright (c) 2001, 2009 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
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.xml.core.internal.document;



import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


/**
 * NodeContainer class
 */
public abstract class NodeContainer extends NodeImpl implements Node, NodeList {

	/**
	 */
	private class ChildNodesCache implements NodeList {
		private Node curChild = null;
		private int curIndex = -1;
		private int length = 0;

		ChildNodesCache() {
			initializeCache();
		}

		public int getLength() {
			// atomic
			return this.length;
		}

		private void initializeCache() {
			// note we use the outter objects lockobject
			// (since we are using their "children".
			synchronized (lockObject) {
				for (Node child = firstChild; child != null; child = child.getNextSibling()) {
					this.length++;
				}
			}
		}

		public Node item(int index) {
			synchronized (lockObject) {
				if (this.length == 0)
					return null;
				if (index < 0)
					return null;
				if (index >= this.length)
					return null;

				if (this.curIndex < 0) { // first time
					if (index * 2 >= this.length) { // search from the last
						this.curIndex = this.length - 1;
						this.curChild = lastChild;
					} else { // search from the first
						this.curIndex = 0;
						this.curChild = firstChild;
					}
				}

				if (index == this.curIndex)
					return this.curChild;

				if (index > this.curIndex) {
					while (index > this.curIndex) {
						this.curIndex++;
						this.curChild = this.curChild.getNextSibling();
					}
				} else { // index < this.curIndex
					while (index < this.curIndex) {
						this.curIndex--;
						this.curChild = this.curChild.getPreviousSibling();
					}
				}

				return this.curChild;
			}
		}
	}

	private NodeList childNodesCache = null;

	private boolean fChildEditable = true;
	NodeImpl firstChild = null;
	NodeImpl lastChild = null;

	Object lockObject = new byte[0];

	/**
	 * NodeContainer constructor
	 */
	protected NodeContainer() {
		super();
	}

	/**
	 * NodeContainer constructor
	 * 
	 * @param that
	 *            NodeContainer
	 */
	protected NodeContainer(NodeContainer that) {
		super(that);
	}

	/**
	 * appendChild method
	 * 
	 * @return org.w3c.dom.Node
	 * @param newChild
	 *            org.w3c.dom.Node
	 */
	public Node appendChild(Node newChild) throws DOMException {
		return insertBefore(newChild, null);
	}

	/**
	 * cloneChildNodes method
	 * 
	 * @param container
	 *            org.w3c.dom.Node
	 * @param deep
	 *            boolean
	 */
	protected void cloneChildNodes(Node newParent, boolean deep) {
		if (newParent == null || newParent == this)
			return;
		if (!(newParent instanceof NodeContainer))
			return;

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

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

	/**
	 * getChildNodes method
	 * 
	 * @return org.w3c.dom.NodeList
	 */
	public NodeList getChildNodes() {
		return this;
	}

	/**
	 * getFirstChild method
	 * 
	 * @return org.w3c.dom.Node
	 */
	public Node getFirstChild() {
		return this.firstChild;
	}

	/**
	 * getLastChild method
	 * 
	 * @return org.w3c.dom.Node
	 */
	public Node getLastChild() {
		return this.lastChild;
	}

	/**
	 * getLength method
	 * 
	 * @return int
	 */
	public int getLength() {
		if (this.firstChild == null)
			return 0;
		synchronized (lockObject) {
			if (this.childNodesCache == null)
				this.childNodesCache = new ChildNodesCache();
			return this.childNodesCache.getLength();
		}
	}

	/**
	 */
	public String getSource() {
		StringBuffer buffer = new StringBuffer();

		IStructuredDocumentRegion startStructuredDocumentRegion = getStartStructuredDocumentRegion();
		if (startStructuredDocumentRegion != null) {
			String source = startStructuredDocumentRegion.getText();
			if (source != null)
				buffer.append(source);
		}

		for (NodeImpl child = firstChild; child != null; child = (NodeImpl) child.getNextSibling()) {
			String source = child.getSource();
			if (source != null)
				buffer.append(source);
		}

		IStructuredDocumentRegion endStructuredDocumentRegion = getEndStructuredDocumentRegion();
		if (endStructuredDocumentRegion != null) {
			String source = endStructuredDocumentRegion.getText();
			if (source != null)
				buffer.append(source);
		}

		return buffer.toString();
	}

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

	/**
	 * insertBefore method
	 * 
	 * @return org.w3c.dom.Node
	 * @param newChild
	 *            org.w3c.dom.Node
	 * @param refChild
	 *            org.w3c.dom.Node
	 */
	public Node insertBefore(Node newChild, Node refChild) throws DOMException {
		if (newChild == null)
			return null; // nothing to do
		if (refChild != null && refChild.getParentNode() != this) {
			throw new DOMException(DOMException.NOT_FOUND_ERR, new String());
		}
		if (!isChildEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}
		if (newChild == refChild)
			return newChild; // nothing to do
		//new child can not be a parent of this, would cause cycle
		if(isParent(newChild)) {
			throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, new String());
		}

		if (newChild.getNodeType() == DOCUMENT_FRAGMENT_NODE) {
			// insert child nodes instead
			for (Node child = newChild.getFirstChild(); child != null; child = newChild.getFirstChild()) {
				newChild.removeChild(child);
				insertBefore(child, refChild);
			}
			return newChild;
		}
		// synchronized in case another thread is getting item, or length
		synchronized (lockObject) {
			this.childNodesCache = null; // invalidate child nodes cache
		}

		NodeImpl child = (NodeImpl) newChild;
		NodeImpl next = (NodeImpl) refChild;
		NodeImpl prev = null;
		Node oldParent = child.getParentNode();
		if (oldParent != null)
			oldParent.removeChild(child);
		if (next == null) {
			prev = this.lastChild;
			this.lastChild = child;
		} else {
			prev = (NodeImpl) next.getPreviousSibling();
			next.setPreviousSibling(child);
		}
		if (prev == null)
			this.firstChild = child;
		else
			prev.setNextSibling(child);
		child.setPreviousSibling(prev);
		child.setNextSibling(next);
		child.setParentNode(this);
		// make sure having the same owner document
		if (child.getOwnerDocument() == null) {
			if (getNodeType() == DOCUMENT_NODE) {
				child.setOwnerDocument((Document) this);
			} else {
				child.setOwnerDocument(getOwnerDocument());
			}
		}

		notifyChildReplaced(child, null);

		return child;
	}

	public boolean isChildEditable() {
		if (!fChildEditable) {
			DOMModelImpl model = (DOMModelImpl) getModel();
			if (model != null && model.isReparsing()) {
				return true;
			}
		}
		return fChildEditable;
	}

	/**
	 * isContainer method
	 * 
	 * @return boolean
	 */
	public boolean isContainer() {
		return true;
	}

	/**
	 * item method
	 * 
	 * @return org.w3c.dom.Node
	 * @param index
	 *            int
	 */
	public Node item(int index) {
		if (this.firstChild == null)
			return null;
		synchronized (lockObject) {
			if (this.childNodesCache == null)
				this.childNodesCache = new ChildNodesCache();
			return this.childNodesCache.item(index);
		}
	}

	/**
	 * notifyChildReplaced method
	 * 
	 * @param newChild
	 *            org.w3c.dom.Node
	 * @param oldChild
	 *            org.w3c.dom.Node
	 */
	protected void notifyChildReplaced(Node newChild, Node oldChild) {
		DocumentImpl document = (DocumentImpl) getContainerDocument();
		if (document == null)
			return;

		syncChildEditableState(newChild);

		DOMModelImpl model = (DOMModelImpl) document.getModel();
		if (model == null)
			return;
		model.childReplaced(this, newChild, oldChild);
	}

	/**
	 * removeChild method
	 * 
	 * @return org.w3c.dom.Node
	 * @param oldChild
	 *            org.w3c.dom.Node
	 */
	public Node removeChild(Node oldChild) throws DOMException {
		if (oldChild == null)
			return null;
		if (oldChild.getParentNode() != this) {
			throw new DOMException(DOMException.NOT_FOUND_ERR, new String());
		}

		if (!isChildEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}

		// synchronized in case another thread is getting item, or length
		synchronized (lockObject) {
			this.childNodesCache = null; // invalidate child nodes cache
		}

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

		child.setEditable(true, true); // clear ReadOnly flags

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

		notifyChildReplaced(null, child);

		return child;
	}

	/**
	 * removeChildNodes method
	 */
	public void removeChildNodes() {
		if (!isChildEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}

		Node nextChild = null;
		for (Node child = getFirstChild(); child != null; child = nextChild) {
			nextChild = child.getNextSibling();
			removeChild(child);
		}
	}

	/**
	 * removeChildNodes method
	 * 
	 * @return org.w3c.dom.DocumentFragment
	 * @param firstChild
	 *            org.w3c.dom.Node
	 * @param lastChild
	 *            org.w3c.dom.Node
	 */
	public DocumentFragment removeChildNodes(Node firstChild, Node lastChild) {
		if (!hasChildNodes())
			return null;
		if (!isChildEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}

		Document document = null;
		if (getNodeType() == DOCUMENT_NODE)
			document = (Document) this;
		else
			document = getOwnerDocument();
		if (document == null)
			return null;
		DocumentFragment fragment = document.createDocumentFragment();
		if (fragment == null)
			return null;

		if (firstChild == null)
			firstChild = getFirstChild();
		if (lastChild == null)
			lastChild = getLastChild();
		Node nextChild = null;
		for (Node child = firstChild; child != null; child = nextChild) {
			nextChild = child.getNextSibling();
			removeChild(child);
			fragment.appendChild(child);
			if (child == lastChild)
				break;
		}

		return fragment;
	}

	/**
	 * replaceChild method
	 * 
	 * @return org.w3c.dom.Node
	 * @param newChild
	 *            org.w3c.dom.Node
	 * @param oldChild
	 *            org.w3c.dom.Node
	 */
	public Node replaceChild(Node newChild, Node oldChild) throws DOMException {
		if (!isChildEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}

		if (oldChild == null)
			return newChild;
		if (newChild != null)
			insertBefore(newChild, oldChild);
		return removeChild(oldChild);
	}

	public void setChildEditable(boolean editable) {
		if (fChildEditable == editable) {
			return;
		}

		ReadOnlyController roc = ReadOnlyController.getInstance();
		Node node;
		if (editable) {
			for (node = getFirstChild(); node != null; node = node.getNextSibling()) {
				roc.unlockNode((IDOMNode) node);
			}
		} else {
			for (node = getFirstChild(); node != null; node = node.getNextSibling()) {
				roc.lockNode((IDOMNode) node);
			}
		}

		fChildEditable = editable;
		notifyEditableChanged();
	}

	protected void syncChildEditableState(Node child) {
		ReadOnlyController roc = ReadOnlyController.getInstance();
		if (fChildEditable) {
			roc.unlockNode((NodeImpl) child);
		} else {
			roc.lockNode((NodeImpl) child);
		}
	}

	/**
	 * <p>Checks to see if the given <code>Node</code> is a parent of <code>this</code> node</p>
	 * 
	 * @param possibleParent the possible parent <code>Node</code> of <code>this</code> node
	 * @return <code>true</code> if <code>possibleParent</code> is the parent of <code>this</code>,
	 * <code>false</code> otherwise.
	 */
	private boolean isParent(Node possibleParent) {
		Node parent = this.getParentNode();
		while(parent != null && parent != possibleParent) {
			parent = parent.getParentNode();
		}

		return parent == possibleParent;
	}
}
