/*******************************************************************************
 * 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
 *     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.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMModel;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMText;
import org.eclipse.wst.xml.core.internal.provisional.document.ISourceGenerator;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.Text;


/**
 * TextImpl class
 */
public class TextImpl extends CharacterDataImpl implements IDOMText {

	/**
	 */
	private class StringPair {
		private String fFirst = null;
		private String fSecond = null;

		StringPair(String first, String second) {
			this.fFirst = first;
			this.fSecond = second;
		}

		String getFirst() {
			return this.fFirst;
		}

		String getSecond() {
			return this.fSecond;
		}
	}

	private String fSource = null;

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

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

		if (that != null) {
			this.fSource = that.getSource();
		}
	}

	/**
	 * appendData method
	 * 
	 * @param arg
	 *            java.lang.String
	 */
	public void appendData(String arg) throws DOMException {
		if (arg == null || arg.length() == 0)
			return;

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

		String newSource = getSource(arg);
		if (newSource == null)
			return;
		String source = getSource();
		if (source != null)
			setTextSource(source + newSource);
		else
			setTextSource(newSource);
	}

	/**
	 */
	IStructuredDocumentRegion appendStructuredDocumentRegion(IStructuredDocumentRegion newStructuredDocumentRegion) {
		if (newStructuredDocumentRegion == null)
			return null;

		IStructuredDocumentRegion flatNode = getStructuredDocumentRegion();
		if (flatNode == null) {
			setStructuredDocumentRegion(newStructuredDocumentRegion);
			return newStructuredDocumentRegion;
		}

		if (flatNode instanceof StructuredDocumentRegionContainer) {
			StructuredDocumentRegionContainer container = (StructuredDocumentRegionContainer) flatNode;
			container.appendStructuredDocumentRegion(newStructuredDocumentRegion);
		}
		else {
			StructuredDocumentRegionContainer container = new StructuredDocumentRegionContainer();
			container.appendStructuredDocumentRegion(flatNode);
			container.appendStructuredDocumentRegion(newStructuredDocumentRegion);
			setStructuredDocumentRegion(container);
		}

		return newStructuredDocumentRegion;
	}

	/**
	 * appendText method
	 * 
	 * @param text
	 *            org.w3c.dom.Text
	 */
	public void appendText(Text newText) {
		if (newText == null)
			return;

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

		TextImpl text = (TextImpl) newText;
		String newSource = text.getSource();
		if (newSource == null && newSource.length() == 0)
			return;
		String source = getSource();
		if (source != null)
			setTextSource(source + newSource);
		else
			setTextSource(newSource);
	}

	/**
	 * cloneNode method
	 * 
	 * @return org.w3c.dom.Node
	 * @param deep
	 *            boolean
	 */
	public Node cloneNode(boolean deep) {
		TextImpl cloned = new TextImpl(this);
		return cloned;
	}

	/**
	 * deleteData method
	 * 
	 * @param offset
	 *            int
	 * @param count
	 *            int
	 */
	public void deleteData(int offset, int count) throws DOMException {
		if (count == 0)
			return;
		if (!isDataEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}
		if (count < 0 || offset < 0) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}

		String source = getSource();
		if (source == null || source.length() == 0) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}
		StringPair pair = substringSourceExcluded(source, offset, count);
		if (pair == null)
			return;
		source = null;
		String first = pair.getFirst();
		if (first != null)
			source = first;
		String second = pair.getSecond();
		if (second != null) {
			if (source != null)
				source += second;
			else
				source = second;
		}
		if (source == null)
			source = new String(); // delete all
		setTextSource(source);
	}

	/**
	 * getData method
	 * 
	 * @return java.lang.String
	 */
	public String getData() throws DOMException {
		if (this.fSource != null)
			return getData(this.fSource);
		String data = super.getData();
		if (data != null)
			return data;
		return getData(getStructuredDocumentRegion());
	}

	/**
	 */
	private String getData(IStructuredDocumentRegion flatNode) {
		if (flatNode == null)
			return new String();

		if (flatNode instanceof StructuredDocumentRegionContainer) {
			StructuredDocumentRegionContainer container = (StructuredDocumentRegionContainer) flatNode;
			int length = container.getLength();
			if (length < 16)
				length = 16; // default
			StringBuffer buffer = new StringBuffer(length);
			int count = container.getStructuredDocumentRegionCount();
			for (int i = 0; i < count; i++) {
				IStructuredDocumentRegion content = container.getStructuredDocumentRegion(i);
				String data = getData(content);
				if (data == null)
					continue;
				buffer.append(data);
			}
			return buffer.toString();
		}

		if (flatNode instanceof StructuredDocumentRegionProxy) {
			return flatNode.getText();
		}

		ITextRegion region = StructuredDocumentRegionUtil.getFirstRegion(flatNode);
		if (region != null) {
			String regionType = region.getType();
			if (regionType == DOMRegionContext.XML_ENTITY_REFERENCE || regionType == DOMRegionContext.XML_CHAR_REFERENCE) {
				String name = StructuredDocumentRegionUtil.getEntityRefName(flatNode, region);
				if (name != null) {
					DocumentImpl document = (DocumentImpl) getOwnerDocument();
					if (document != null) {
						String value = document.getCharValue(name);
						if (value != null)
							return value;
					}
				}
			}
		}

		return flatNode.getText();
	}

	/**
	 * Returns data for the source
	 */
	private String getData(String source) {
		if (source == null)
			return null;
		StringBuffer buffer = null;
		int offset = 0;
		int length = source.length();
		int ref = source.indexOf('&');
		while (ref >= 0) {
			int end = source.indexOf(';', ref + 1);
			if (end > ref + 1) {
				String name = source.substring(ref + 1, end);
				String value = getCharValue(name);
				if (value != null) {
					if (buffer == null)
						buffer = new StringBuffer(length);
					if (ref > offset)
						buffer.append(source.substring(offset, ref));
					buffer.append(value);
					offset = end + 1;
					ref = end;
				}
			}
			ref = source.indexOf('&', ref + 1);
		}
		if (buffer == null)
			return source;
		if (length > offset)
			buffer.append(source.substring(offset));
		return buffer.toString();
	}

	/**
	 * getFirstStructuredDocumentRegion method
	 * 
	 */
	public IStructuredDocumentRegion getFirstStructuredDocumentRegion() {
		return StructuredDocumentRegionUtil.getFirstStructuredDocumentRegion(getStructuredDocumentRegion());
	}

	/**
	 * getLastStructuredDocumentRegion method
	 * 
	 */
	public IStructuredDocumentRegion getLastStructuredDocumentRegion() {
		return StructuredDocumentRegionUtil.getLastStructuredDocumentRegion(getStructuredDocumentRegion());
	}

	/**
	 * getNodeName method
	 * 
	 * @return java.lang.String
	 */
	public String getNodeName() {
		return "#text";//$NON-NLS-1$
	}

	/**
	 * getNodeType method
	 * 
	 * @return short
	 */
	public short getNodeType() {
		return TEXT_NODE;
	}

	/**
	 */
	public String getSource() {
		if (this.fSource != null)
			return this.fSource;
		String data = super.getData();
		if (data != null && data.length() > 0) {
			String source = getSource(data);
			if (source != null)
				return source;
		}
		return super.getSource();
	}

	/**
	 * Returns source for the data
	 */
	private String getSource(String data) {
		if (data == null)
			return null;
		IDOMModel model = getModel();
		if (model == null)
			return null; // error
		ISourceGenerator generator = model.getGenerator();
		if (generator == null)
			return null; // error
		return generator.generateTextData(this, data);
	}

	/**
	 */
	String getTextSource() {
		return this.fSource;
	}

	/**
	 */
	public String getValueSource() {
		return getSource();
	}

	/**
	 */
	boolean hasStructuredDocumentRegion(IStructuredDocumentRegion askedStructuredDocumentRegion) {
		if (askedStructuredDocumentRegion == null)
			return false;

		IStructuredDocumentRegion flatNode = getStructuredDocumentRegion();
		if (flatNode == null)
			return false;

		if (flatNode == askedStructuredDocumentRegion)
			return true;

		if (flatNode instanceof StructuredDocumentRegionProxy) {
			StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) flatNode;
			if (proxy.getStructuredDocumentRegion() == askedStructuredDocumentRegion)
				return true;
			return false;
		}

		if (flatNode instanceof StructuredDocumentRegionContainer) {
			StructuredDocumentRegionContainer container = (StructuredDocumentRegionContainer) flatNode;
			int count = container.getStructuredDocumentRegionCount();
			for (int i = 0; i < count; i++) {
				IStructuredDocumentRegion content = container.getStructuredDocumentRegion(i);
				if (content == null)
					continue;
				if (content == askedStructuredDocumentRegion)
					return true;
				if (content instanceof StructuredDocumentRegionProxy) {
					StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) content;
					if (proxy.getStructuredDocumentRegion() == askedStructuredDocumentRegion)
						return true;
				}
			}
			return false;
		}

		return false;
	}

	/**
	 * insertData method
	 * 
	 * @param offset
	 *            int
	 * @param arg
	 *            java.lang.String
	 */
	public void insertData(int offset, String arg) throws DOMException {
		if (arg == null || arg.length() == 0)
			return;
		if (!isDataEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}
		if (offset < 0) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}

		String source = getSource();
		if (source == null || source.length() == 0) {
			if (offset > 0) {
				throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
			}
			source = getSource(arg);
			if (source != null)
				setTextSource(source);
			return;
		}

		StringPair pair = substringSourceExcluded(source, offset, 0);
		if (pair == null)
			return; // error
		StringBuffer buffer = new StringBuffer(source.length() + arg.length());
		String first = pair.getFirst();
		if (first != null)
			buffer.append(first);
		source = getSource(arg);
		if (source != null)
			buffer.append(source);
		String second = pair.getSecond();
		if (second != null)
			buffer.append(second);
		setTextSource(buffer.toString());
	}

	/**
	 */
	IStructuredDocumentRegion insertStructuredDocumentRegion(IStructuredDocumentRegion newStructuredDocumentRegion, IStructuredDocumentRegion nextStructuredDocumentRegion) {
		if (newStructuredDocumentRegion == null)
			return null;
		if (nextStructuredDocumentRegion == null)
			return appendStructuredDocumentRegion(newStructuredDocumentRegion);

		IStructuredDocumentRegion flatNode = getStructuredDocumentRegion();
		if (flatNode == null)
			return null; // error

		if (flatNode == nextStructuredDocumentRegion) {
			StructuredDocumentRegionContainer container = new StructuredDocumentRegionContainer();
			container.appendStructuredDocumentRegion(newStructuredDocumentRegion);
			container.appendStructuredDocumentRegion(flatNode);
			setStructuredDocumentRegion(container);
			return newStructuredDocumentRegion;
		}

		if (flatNode instanceof StructuredDocumentRegionContainer) {
			StructuredDocumentRegionContainer container = (StructuredDocumentRegionContainer) flatNode;
			int count = container.getStructuredDocumentRegionCount();
			for (int i = 0; i < count; i++) {
				IStructuredDocumentRegion content = container.getStructuredDocumentRegion(i);
				if (content == nextStructuredDocumentRegion) {
					container.insertStructuredDocumentRegion(newStructuredDocumentRegion, i);
					return newStructuredDocumentRegion;
				}
			}
			return null; // error
		}

		return null; // error
	}

	/**
	 * insertText method
	 * 
	 * @param text
	 *            org.w3c.dom.Text
	 * @param offset
	 *            int
	 */
	public void insertText(Text newText, int offset) throws DOMException {
		if (newText == null)
			return;
		if (!isDataEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}
		TextImpl text = (TextImpl) newText;
		String newSource = text.getSource();
		if (newSource == null && newSource.length() == 0)
			return;
		if (offset < 0) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}

		String source = getSource();
		if (source == null || source.length() == 0) {
			if (offset > 0) {
				throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
			}
			setTextSource(newSource);
			return;
		}

		StringPair pair = substringSourceExcluded(source, offset, 0);
		if (pair == null)
			return; // error
		StringBuffer buffer = new StringBuffer(source.length() + newSource.length());
		String first = pair.getFirst();
		if (first != null)
			buffer.append(first);
		buffer.append(newSource);
		String second = pair.getSecond();
		if (second != null)
			buffer.append(second);
		setTextSource(buffer.toString());
	}

	/**
	 * isCDATAContent method
	 * 
	 * @return boolean
	 */
	public boolean isCDATAContent() {
		Node parent = getParentNode();
		if (parent == null || parent.getNodeType() != Node.ELEMENT_NODE)
			return false;
		ElementImpl element = (ElementImpl) parent;
		return element.isCDATAContainer();
	}

	/**
	 */
	public boolean isInvalid() {
		return isInvalid(getStructuredDocumentRegion());
	}

	/**
	 */
	private boolean isInvalid(IStructuredDocumentRegion flatNode) {
		if (flatNode == null)
			return false;

		if (flatNode instanceof StructuredDocumentRegionContainer) {
			StructuredDocumentRegionContainer container = (StructuredDocumentRegionContainer) flatNode;
			int count = container.getStructuredDocumentRegionCount();
			for (int i = 0; i < count; i++) {
				IStructuredDocumentRegion content = container.getStructuredDocumentRegion(i);
				if (isInvalid(content))
					return true;
			}
			return false;
		}

		if (flatNode instanceof StructuredDocumentRegionProxy) {
			StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) flatNode;
			return isInvalid(proxy.getStructuredDocumentRegion());
		}

		String regionType = StructuredDocumentRegionUtil.getFirstRegionType(flatNode);
		if (regionType != DOMRegionContext.XML_CONTENT && isNotNestedContent(regionType) && regionType != DOMRegionContext.XML_ENTITY_REFERENCE && regionType != DOMRegionContext.XML_CHAR_REFERENCE && regionType != DOMRegionContext.BLOCK_TEXT && regionType != DOMRegionContext.WHITE_SPACE) {
			return true;
		}

		return false;
	}

	protected boolean isNotNestedContent(String regionType) {
		boolean result = true;
		return result;
	}

	/**
	 */
	boolean isSharingStructuredDocumentRegion(IStructuredDocumentRegion sharedStructuredDocumentRegion) {
		if (sharedStructuredDocumentRegion == null)
			return false;

		IStructuredDocumentRegion flatNode = getStructuredDocumentRegion();
		if (flatNode == null)
			return false;

		if (flatNode == sharedStructuredDocumentRegion)
			return false;

		if (flatNode instanceof StructuredDocumentRegionProxy) {
			StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) flatNode;
			if (proxy.getStructuredDocumentRegion() == sharedStructuredDocumentRegion)
				return true;
			return false;
		}

		if (flatNode instanceof StructuredDocumentRegionContainer) {
			StructuredDocumentRegionContainer container = (StructuredDocumentRegionContainer) flatNode;
			int count = container.getStructuredDocumentRegionCount();
			for (int i = 0; i < count; i++) {
				IStructuredDocumentRegion content = container.getStructuredDocumentRegion(i);
				if (content == null)
					continue;
				if (content == sharedStructuredDocumentRegion)
					return false;
				if (content instanceof StructuredDocumentRegionProxy) {
					StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) content;
					if (proxy.getStructuredDocumentRegion() == sharedStructuredDocumentRegion)
						return true;
				}
			}
			return false;
		}

		return false;
	}

	/**
	 * Returns whether this text node contains <a
	 * href='http://www.w3.org/TR/2004/REC-xml-infoset-20040204#infoitem.character'>
	 * element content whitespace</a>, often abusively called "ignorable
	 * whitespace". The text node is determined to contain whitespace in
	 * element content during the load of the document or if validation occurs
	 * while using <code>Document.normalizeDocument()</code>.
	 * 
	 * @since DOM Level 3
	 */
	public boolean isElementContentWhitespace() {
		return isWhitespace();
	}

	/**
	 */
	public boolean isWhitespace() {
		String data = getData();
		if (data == null)
			return true;
		int length = data.length();
		for (int i = 0; i < length; i++) {
			if (!Character.isWhitespace(data.charAt(i)))
				return false;
		}
		return true;
	}

	/**
	 */
	IStructuredDocumentRegion removeStructuredDocumentRegion(IStructuredDocumentRegion oldStructuredDocumentRegion) {
		if (oldStructuredDocumentRegion == null)
			return null;

		IStructuredDocumentRegion flatNode = getStructuredDocumentRegion();
		if (flatNode == null)
			return null; // error

		if (flatNode == oldStructuredDocumentRegion) {
			setStructuredDocumentRegion(null);
			return oldStructuredDocumentRegion;
		}

		if (flatNode instanceof StructuredDocumentRegionProxy) {
			StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) flatNode;
			if (proxy.getStructuredDocumentRegion() == oldStructuredDocumentRegion) {
				// removed with proxy
				setStructuredDocumentRegion(null);
				return oldStructuredDocumentRegion;
			}
			return null; // error
		}

		if (flatNode instanceof StructuredDocumentRegionContainer) {
			StructuredDocumentRegionContainer container = (StructuredDocumentRegionContainer) flatNode;
			int count = container.getStructuredDocumentRegionCount();
			for (int i = 0; i < count; i++) {
				IStructuredDocumentRegion content = container.getStructuredDocumentRegion(i);
				if (content == oldStructuredDocumentRegion) {
					container.removeStructuredDocumentRegion(i);
					if (container.getStructuredDocumentRegionCount() == 1) {
						// get back to single IStructuredDocumentRegion
						setStructuredDocumentRegion(container.getStructuredDocumentRegion(0));
					}
					return oldStructuredDocumentRegion;
				}

				if (content instanceof StructuredDocumentRegionProxy) {
					StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) content;
					if (proxy.getStructuredDocumentRegion() == oldStructuredDocumentRegion) {
						// removed with proxy
						container.removeStructuredDocumentRegion(i);
						if (container.getStructuredDocumentRegionCount() == 1) {
							// get back to single IStructuredDocumentRegion
							setStructuredDocumentRegion(container.getStructuredDocumentRegion(0));
						}
						return oldStructuredDocumentRegion;
					}
				}
			}
			return null; // error
		}

		return null; // error
	}

	/**
	 * replaceData method
	 * 
	 * @param offset
	 *            int
	 * @param count
	 *            int
	 * @param arg
	 *            java.lang.String
	 */
	public void replaceData(int offset, int count, String arg) throws DOMException {
		if (!isDataEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}
		if (arg == null || arg.length() == 0) {
			deleteData(offset, count);
			return;
		}
		if (count == 0) {
			insertData(offset, arg);
			return;
		}
		if (offset < 0 || count < 0) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}

		String source = getSource();
		if (source == null || source.length() == 0) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}

		StringPair pair = substringSourceExcluded(source, offset, count);
		if (pair == null)
			return; // error
		StringBuffer buffer = new StringBuffer(source.length() + arg.length());
		String first = pair.getFirst();
		if (first != null)
			buffer.append(first);
		source = getSource(arg);
		if (source != null)
			buffer.append(source);
		String second = pair.getSecond();
		if (second != null)
			buffer.append(second);
		setTextSource(buffer.toString());
	}

	/**
	 */
	IStructuredDocumentRegion replaceStructuredDocumentRegion(IStructuredDocumentRegion newStructuredDocumentRegion, IStructuredDocumentRegion oldStructuredDocumentRegion) {
		if (oldStructuredDocumentRegion == null)
			return null;
		if (newStructuredDocumentRegion == null)
			return removeStructuredDocumentRegion(oldStructuredDocumentRegion);

		IStructuredDocumentRegion flatNode = getStructuredDocumentRegion();
		if (flatNode == null)
			return null; // error

		if (flatNode == oldStructuredDocumentRegion) {
			setStructuredDocumentRegion(newStructuredDocumentRegion);
			return oldStructuredDocumentRegion;
		}

		if (flatNode instanceof StructuredDocumentRegionProxy) {
			StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) flatNode;
			if (proxy.getStructuredDocumentRegion() == oldStructuredDocumentRegion) {
				if (newStructuredDocumentRegion instanceof StructuredDocumentRegionProxy) {
					// proxy must not be nested
					setStructuredDocumentRegion(newStructuredDocumentRegion);
				}
				else {
					proxy.setStructuredDocumentRegion(newStructuredDocumentRegion);
				}
				return oldStructuredDocumentRegion;
			}
			return null; // error
		}

		if (flatNode instanceof StructuredDocumentRegionContainer) {
			StructuredDocumentRegionContainer container = (StructuredDocumentRegionContainer) flatNode;
			int count = container.getStructuredDocumentRegionCount();
			for (int i = 0; i < count; i++) {
				IStructuredDocumentRegion content = container.getStructuredDocumentRegion(i);
				if (content == null)
					continue; // error
				if (content == oldStructuredDocumentRegion) {
					container.replaceStructuredDocumentRegion(newStructuredDocumentRegion, i);
					return oldStructuredDocumentRegion;
				}

				if (content instanceof StructuredDocumentRegionProxy) {
					StructuredDocumentRegionProxy proxy = (StructuredDocumentRegionProxy) content;
					if (proxy.getStructuredDocumentRegion() == oldStructuredDocumentRegion) {
						if (newStructuredDocumentRegion instanceof StructuredDocumentRegionProxy) {
							// proxy must not be nested
							container.replaceStructuredDocumentRegion(newStructuredDocumentRegion, i);
						}
						else {
							proxy.setStructuredDocumentRegion(newStructuredDocumentRegion);
						}
						return oldStructuredDocumentRegion;
					}
				}
			}
			return null; // error
		}

		return null; // error
	}

	/**
	 */
	void resetStructuredDocumentRegions() {
		String source = getSource();
		if (source != null && source.length() > 0)
			this.fSource = source;
		super.resetStructuredDocumentRegions();
	}

	/**
	 * getData method
	 * 
	 * @return java.lang.String
	 */
	public void setData(String data) throws DOMException {
		if (!isDataEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}

		this.fSource = null;
		super.setData(data);
	}

	/**
	 */
	public void setSource(String source) throws InvalidCharacterException {
		if (!isDataEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}

		SourceValidator validator = new SourceValidator(this);
		if (validator.validateSource(source))
			setTextSource(source);
	}

	/**
	 */
	void setStructuredDocumentRegion(IStructuredDocumentRegion flatNode) {
		super.setStructuredDocumentRegion(flatNode);
		if (flatNode != null)
			this.fSource = null;
	}

	/**
	 */
	public void setTextSource(String source) {
		if (!isDataEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}

		this.fSource = source;

		notifyValueChanged();
	}

	/**
	 */
	public void setValueSource(String source) {
		if (!isDataEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}

		SourceValidator validator = new SourceValidator(this);
		setTextSource(validator.convertSource(source));
	}

	/**
	 * splitText method
	 * 
	 * @return org.w3c.dom.Text
	 * @param offset
	 *            int
	 */
	public Text splitText(int offset) throws DOMException {
		if (!isDataEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}
		if (offset < 0) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}
		int length = getLength();
		if (offset > length) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}
		Document document = getOwnerDocument();
		if (document == null)
			return null;

		String source = null;
		if (offset < length) {
			int count = length - offset;
			source = substringSource(offset, count);
			deleteData(offset, count);
		}
		TextImpl text = (TextImpl) document.createTextNode(null);
		if (source != null)
			text.setTextSource(source);

		Node parent = getParentNode();
		if (parent != null)
			parent.insertBefore(text, getNextSibling());

		return text;
	}

	/**
	 */
	Text splitText(IStructuredDocumentRegion nextStructuredDocumentRegion) {
		if (nextStructuredDocumentRegion == null)
			return null;

		IStructuredDocumentRegion flatNode = getStructuredDocumentRegion();
		if (flatNode == null || !(flatNode instanceof StructuredDocumentRegionContainer))
			return null; // error

		StructuredDocumentRegionContainer container = (StructuredDocumentRegionContainer) flatNode;
		int count = container.getStructuredDocumentRegionCount();
		int index = 0;
		for (; index < count; index++) {
			if (container.getStructuredDocumentRegion(index) == nextStructuredDocumentRegion)
				break;
		}
		if (index >= count) {
			// this is the case nextStructuredDocumentRegion is a new
			// IStructuredDocumentRegion
			// search gap by offset
			int offset = nextStructuredDocumentRegion.getStart();
			for (index = 0; index < count; index++) {
				IStructuredDocumentRegion content = container.getStructuredDocumentRegion(index);
				if (content == null)
					continue; // error
				if (content.getStart() >= offset)
					break;
			}
			if (index >= count)
				return null; // error
		}
		if (index == 0)
			return this; // nothing to do

		Document document = getOwnerDocument();
		if (document == null)
			return null; // error
		Node parent = getParentNode();
		if (parent == null)
			return null; // error
		TextImpl nextText = (TextImpl) document.createTextNode(null);
		if (nextText == null)
			return null; // error

		for (; index < count; count--) {
			nextText.appendStructuredDocumentRegion(container.removeStructuredDocumentRegion(index));
		}

		// normalize IStructuredDocumentRegion
		if (index == 1) {
			setStructuredDocumentRegion(container.getStructuredDocumentRegion(0));
		}

		parent.insertBefore(nextText, getNextSibling());
		return nextText;
	}

	/**
	 * Retruns data for the range
	 */
	private String substringData(String data, int offset, int count) throws DOMException {
		// sure offset and count are non-negative
		if (count == 0)
			return new String();
		if (data == null) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}
		int length = data.length();
		if (offset > length) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}
		int end = offset + count;
		if (end > length) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}
		return data.substring(offset, end);
	}

	/**
	 * Returns source for the range specified by: offset: data offset count:
	 * data count
	 */
	private String substringSource(int offset, int count) throws DOMException {
		// sure offset and count are non-negative
		if (this.fSource != null)
			return substringSource(this.fSource, offset, count);

		String data = super.getData();
		if (data != null && data.length() > 0) {
			data = substringData(data, offset, count);
			if (data == null)
				return new String();
			String source = getSource(data);
			if (source != null)
				return source;
		}

		return substringSource(getSource(), offset, count);
	}

	/**
	 * Returns source for the range specified by: offset: data offset count:
	 * data count
	 */
	private String substringSource(String source, int offset, int count) throws DOMException {
		// sure offset and count are non-negative
		if (count == 0)
			return new String();
		if (source == null) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}

		int length = source.length();
		int end = offset + count;

		// find character reference
		int ref = source.indexOf('&');
		while (ref >= 0) {
			if (ref >= end)
				break;
			int refEnd = source.indexOf(';', ref + 1);
			if (refEnd > ref + 1) {
				String name = source.substring(ref + 1, refEnd);
				if (getCharValue(name) != null) {
					// found, shift for source offsets
					int refCount = refEnd - ref;
					if (ref < offset)
						offset += refCount;
					if (ref < end)
						end += refCount;
					ref = refEnd;
				}
			}
			ref = source.indexOf('&', ref + 1);
		}

		if (offset > length || end > length) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}

		return source.substring(offset, end);
	}

	/**
	 * Returns sources before and after the range specified by: offset: data
	 * offset count: data count
	 */
	private StringPair substringSourceExcluded(String source, int offset, int count) throws DOMException {
		// sure offset and count are non-negative
		if (source == null) {
			if (offset == 0 && count == 0)
				return new StringPair(null, null);
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}

		int length = source.length();
		int end = offset + count;

		// find character reference
		int ref = source.indexOf('&');
		while (ref >= 0) {
			if (ref >= end)
				break;
			int refEnd = source.indexOf(';', ref + 1);
			if (refEnd > ref + 1) {
				String name = source.substring(ref + 1, refEnd);
				if (getCharValue(name) != null) {
					// found, shift for source offsets
					int refCount = refEnd - ref;
					if (ref < offset)
						offset += refCount;
					if (ref < end)
						end += refCount;
					ref = refEnd;
				}
			}
			ref = source.indexOf('&', ref + 1);
		}

		if (offset > length || end > length) {
			throw new DOMException(DOMException.INDEX_SIZE_ERR, new String());
		}

		String first = (offset > 0 ? source.substring(0, offset) : null);
		String second = (end < length ? source.substring(end, length) : null);
		return new StringPair(first, second);
	}

	public String getWholeText() {
		throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Not Implemented in this version."); //$NON-NLS-1$
	}
    /**
	 * Replaces the text of the current node and all logically-adjacent text
	 * nodes with the specified text. All logically-adjacent text nodes are
	 * removed including the current node unless it was the recipient of the
	 * replacement text. <br>
	 * This method returns the node which received the replacement text. The
	 * returned node is:
	 * <ul>
	 * <li><code>null</code>, when the replacement text is the empty
	 * string; </li>
	 * <li>the current node, except when the current node is read-only; </li>
	 * <li> a new <code>Text</code> node of the same type (
	 * <code>Text</code> or <code>CDATASection</code>) as the current
	 * node inserted at the location of the replacement. </li>
	 * </ul>
	 * <br>
	 * For instance, in the above example calling
	 * <code>replaceWholeText</code> on the <code>Text</code> node that
	 * contains "bar" with "yo" in argument results in the following: <br>
	 * Where the nodes to be removed are read-only descendants of an
	 * <code>EntityReference</code>, the <code>EntityReference</code>
	 * must be removed instead of the read-only nodes. If any
	 * <code>EntityReference</code> to be removed has descendants that are
	 * not <code>EntityReference</code>, <code>Text</code>, or
	 * <code>CDATASection</code> nodes, the <code>replaceWholeText</code>
	 * method must fail before performing any modification of the document,
	 * raising a <code>DOMException</code> with the code
	 * <code>NO_MODIFICATION_ALLOWED_ERR</code>. <br>
	 * For instance, in the example below calling
	 * <code>replaceWholeText</code> on the <code>Text</code> node that
	 * contains "bar" fails, because the <code>EntityReference</code> node
	 * "ent" contains an <code>Element</code> node which cannot be removed.
	 * 
	 * @param content
	 *            The content of the replacing <code>Text</code> node.
	 * @return The <code>Text</code> node created with the specified
	 *         content.
	 * @exception DOMException
	 *                NO_MODIFICATION_ALLOWED_ERR: Raised if one of the
	 *                <code>Text</code> nodes being replaced is readonly.
	 * @since DOM Level 3
	 */
    public Text replaceWholeText(String content)
                                 throws DOMException {
		throw new DOMException(DOMException.NOT_SUPPORTED_ERR, "Not implemented"); //$NON-NLS-1$
    }
}
