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

import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionContainer;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegionList;
import org.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap;
import org.eclipse.wst.xml.core.internal.provisional.IXMLCharEntity;
import org.eclipse.wst.xml.core.internal.provisional.IXMLNamespace;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMAttr;
import org.eclipse.wst.xml.core.internal.regions.DOMRegionContext;
import org.w3c.dom.Attr;
import org.w3c.dom.DOMException;
import org.w3c.dom.Element;
import org.w3c.dom.Node;


/**
 * AttrImpl class
 */
public class AttrImpl extends NodeImpl implements IDOMAttr {
	private ITextRegion equalRegion = null;

	private String name = null;
	private ITextRegion nameRegion = null;
	private String namespaceURI = null;
	private ElementImpl ownerElement = null;
	private ITextRegion valueRegion = null;
	private String valueSource = null;

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

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

		if (that != null) {
			this.name = that.name;
			this.valueSource = that.getValueSource();
		}
	}

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

	/**
	 */
	protected CMAttributeDeclaration getDeclaration() {
		ElementImpl element = (ElementImpl) getOwnerElement();
		if (element == null)
			return null;
		CMElementDeclaration elementDecl = element.getDeclaration();
		if (elementDecl == null)
			return null;
		CMNamedNodeMap attributes = elementDecl.getAttributes();
		if (attributes == null)
			return null;
		return (CMAttributeDeclaration) attributes.getNamedItem(getName());
	}

	/**
	 * getEndOffset method
	 * 
	 * @return int
	 */
	public int getEndOffset() {
		if (this.ownerElement == null)
			return 0;
		int offset = this.ownerElement.getStartOffset();
		if (this.valueRegion != null) {
			return (offset + this.valueRegion.getEnd());
		}
		if (this.equalRegion != null) {
			return (offset + this.equalRegion.getEnd());
		}
		if (this.nameRegion != null) {
			return (offset + this.nameRegion.getEnd());
		}
		return 0;
	}


	public ITextRegion getEqualRegion() {
		return this.equalRegion;
	}

	/**
	 */
	public String getLocalName() {
		if (this.name == null)
			return null;
		int index = this.name.indexOf(':');
		if (index < 0)
			return this.name;
		return this.name.substring(index + 1);
	}

	/**
	 * getName method
	 * 
	 * @return java.lang.String
	 */
	public String getName() {
		if (this.name == null)
			return new String();
		return this.name;
	}


	public ITextRegion getNameRegion() {
		return this.nameRegion;
	}

	public int getNameRegionEndOffset() {
		if (this.ownerElement == null)
			return 0;
		// assuming the firstStructuredDocumentRegion is the one that contains
		// attributes
		IStructuredDocumentRegion flatNode = this.ownerElement.getFirstStructuredDocumentRegion();
		if (flatNode == null)
			return 0;
		return flatNode.getEndOffset(this.nameRegion);
	}

	public int getNameRegionStartOffset() {
		if (this.ownerElement == null)
			return 0;
		// assuming the firstStructuredDocumentRegion is the one that contains
		// attributes
		IStructuredDocumentRegion flatNode = this.ownerElement.getFirstStructuredDocumentRegion();
		if (flatNode == null)
			return 0;
		return flatNode.getStartOffset(this.nameRegion);
	}

	public String getNameRegionText() {
		if (this.ownerElement == null)
			return null;
		// assuming the firstStructuredDocumentRegion is the one that contains
		// attributes
		IStructuredDocumentRegion flatNode = this.ownerElement.getFirstStructuredDocumentRegion();
		if (flatNode == null)
			return null;
		return flatNode.getText(this.nameRegion);
	}

	public int getNameRegionTextEndOffset() {
		if (this.ownerElement == null)
			return 0;
		// assuming the firstStructuredDocumentRegion is the one that contains
		// attributes
		IStructuredDocumentRegion flatNode = this.ownerElement.getFirstStructuredDocumentRegion();
		if (flatNode == null)
			return 0;
		return flatNode.getTextEndOffset(this.nameRegion);
	}

	/**
	 */
	public String getNamespaceURI() {
		String nsAttrName = null;
		String prefix = getPrefix();
		if (prefix != null && prefix.length() > 0) {
			if (prefix.equals(IXMLNamespace.XMLNS)) {
				// fixed URI
				return IXMLNamespace.XMLNS_URI;
			}
			nsAttrName = IXMLNamespace.XMLNS_PREFIX + prefix;
		}
		else {
			String name = getName();
			if (name != null && name.equals(IXMLNamespace.XMLNS)) {
				// fixed URI
				return IXMLNamespace.XMLNS_URI;
			}
			// does not inherit namespace from owner element
			// if (this.ownerElement != null) return
			// this.ownerElement.getNamespaceURI();
			return this.namespaceURI;
		}

		for (Node node = this.ownerElement; node != null; node = node.getParentNode()) {
			if (node.getNodeType() != ELEMENT_NODE)
				break;
			Element element = (Element) node;
			Attr attr = element.getAttributeNode(nsAttrName);
			if (attr != null)
				return attr.getValue();
		}

		return this.namespaceURI;
	}

	/**
	 * getNodeName method
	 * 
	 * @return java.lang.String
	 */
	public String getNodeName() {
		return getName();
	}

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

	/**
	 * getNodeValue method
	 * 
	 * @return java.lang.String
	 */
	public String getNodeValue() {
		return getValue();
	}

	/**
	 * getOwnerElement method
	 * 
	 * @return org.w3c.dom.Element
	 */
	public Element getOwnerElement() {
		return this.ownerElement;
	}

	/**
	 */
	public String getPrefix() {
		if (this.name == null)
			return null;
		int index = this.name.indexOf(':');
		if (index <= 0)
			return null;
		// exclude JSP tag in name
		if (this.name.charAt(0) == '<')
			return null;
		return this.name.substring(0, index);
	}

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

	/**
	 * getStartOffset method
	 * 
	 * @return int
	 */
	public int getStartOffset() {
		if (this.ownerElement == null)
			return 0;
		int offset = this.ownerElement.getStartOffset();
		if (this.nameRegion != null) {
			return (offset + this.nameRegion.getStart());
		}
		if (this.equalRegion != null) {
			return (offset + this.equalRegion.getStart());
		}
		if (this.valueRegion != null) {
			return (offset + this.valueRegion.getStart());
		}
		return 0;
	}

	/**
	 * getValue method
	 * 
	 * @return java.lang.String
	 */
	public String getValue() {
		return getValue(getValueSource());
	}

	/**
	 * Returns value for the source
	 */
	private String getValue(String source) {
		if (source == null)
			return new String();
		if (source.length() == 0)
			return source;
		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();
	}

	public ITextRegion getValueRegion() {
		return this.valueRegion;
	}

	/**
	 * ISSUE: what should behavior be if this.value == null? It's an "error"
	 * to be in that state, but seems to occur relatively easily ... probably
	 * due to threading bugs ... but this just shows its needs to be spec'd.
	 * 
	 */
	public int getValueRegionStartOffset() {
		if (this.ownerElement == null)
			return 0;
		// assuming the firstStructuredDocumentRegion is the one that contains
		// the valueRegion -- should make smarter?
		IStructuredDocumentRegion structuredDocumentRegion = this.ownerElement.getFirstStructuredDocumentRegion();
		if (structuredDocumentRegion == null)
			return 0;
		// ensure we never pass null to getStartOffset.
		if (this.valueRegion == null) {
			return 0;
		}
		return structuredDocumentRegion.getStartOffset(this.valueRegion);
	}

	public String getValueRegionText() {
		if (this.ownerElement == null)
			return null;
		// assuming the firstStructuredDocumentRegion is the one that contains
		// attributes
		IStructuredDocumentRegion flatNode = this.ownerElement.getFirstStructuredDocumentRegion();
		if (flatNode == null)
			return null;
		if (this.valueRegion == null)
			return null;
		return flatNode.getText(this.valueRegion);
	}

	/**
	 */
	public String getValueSource() {
		if (this.valueSource != null)
			return this.valueSource;
		// DW: 4/16/2003 due to change in structuredDocument ... we need a
		// flatnode to
		// get at region values. For now I'll assume this is always the first
		// flatnode .. may need to make smarter later (e.g. to search for
		// the flatnode that this.valueRegion belongs to.
		// DW: 4/30/2003 For some reason, this method is getting called a lot
		// Not sure if its a threading problem, or a fundamental error
		// elsewhere.
		// It needs more investigation, but in the use cases I've seen,
		// doesn't
		// seem to hurt to simply return null in those cases. I saw this null
		// case,
		// when tryint go format an XML file.
		if (this.ownerElement == null)
			return null;
		IStructuredDocumentRegion ownerRegion = this.ownerElement.getFirstStructuredDocumentRegion();
		if (ownerRegion == null)
			return null;
		if (this.valueRegion != null)
			return StructuredDocumentRegionUtil.getAttrValue(ownerRegion, this.valueRegion);
		return new String();
	}

	private String getValueSource(ElementImpl ownerElement) {
		if (this.valueSource != null)
			return this.valueSource;
		// DW: 4/16/2003 due to change in structuredDocument ... we need a
		// flatnode to
		// get at region values. For now I'll assume this is always the first
		// flatnode .. may need to make smarter later (e.g. to search for
		// the flatnode that this.valueRegion belongs to.
		if (this.valueRegion != null)
			return StructuredDocumentRegionUtil.getAttrValue(ownerElement.getStructuredDocumentRegion(), this.valueRegion);
		return new String();
	}

	/**
	 */
	private String getValueSource(String value) {
		if (value == null)
			return null;
		if (value.length() == 0)
			return value;
		StringBuffer buffer = null;
		int offset = 0;
		int length = value.length();
		int amp = value.indexOf('&');
		while (amp >= 0) {
			if (buffer == null)
				buffer = new StringBuffer(length + 4);
			if (amp > offset)
				buffer.append(value.substring(offset, amp));
			buffer.append(IXMLCharEntity.AMP_REF);
			offset = amp + 1;
			amp = value.indexOf('&', offset);
		}
		if (buffer == null)
			return value;
		if (length > offset)
			buffer.append(value.substring(offset));
		return buffer.toString();
	}

	/**
	 * Check if Attr has JSP in value
	 */
	public boolean hasNestedValue() {
		if (this.valueRegion == null)
			return false;
		if (!(this.valueRegion instanceof ITextRegionContainer))
			return false;
		ITextRegionList regions = ((ITextRegionContainer) this.valueRegion).getRegions();
		if (regions == null)
			return false;
		Iterator e = regions.iterator();
		while (e.hasNext()) {
			ITextRegion region = (ITextRegion) e.next();
			if (region == null)
				continue;
			String regionType = region.getType();
			if (regionType == DOMRegionContext.XML_TAG_OPEN || isNestedLanguageOpening(regionType))
				return true;
		}
		return false;
	}

	/**
	 * Check if Attr has only name but not equal sign nor value
	 */
	public boolean hasNameOnly() {
		return (this.nameRegion != null && this.equalRegion == null && this.valueRegion == null);
	}

	/**
	 */
	protected final boolean hasPrefix() {
		if (this.name == null)
			return false;
		if (this.name.indexOf(':') <= 0)
			return false;
		// exclude JSP tag in name
		if (this.name.charAt(0) == '<')
			return false;
		return true;
	}

	/**
	 */
	protected final boolean ignoreCase() {
		if (this.ownerElement != null) {
			if (this.ownerElement.ignoreCase()) {
				return !hasPrefix();
			}
		}
		else {
			DocumentImpl document = (DocumentImpl) getOwnerDocument();
			if (document != null && document.ignoreCase()) {
				// even in case insensitive document, if having prefix, it's
				// case sensitive
				return !hasPrefix();
			}
		}
		return false;
	}

	/**
	 */
	public boolean isGlobalAttr() {
		if (hasPrefix())
			return false;
		if (this.ownerElement == null)
			return false;
		return this.ownerElement.isGlobalTag();
	}

	/**
	 */
	public final boolean isXMLAttr() {
		if (this.ownerElement != null) {
			if (!this.ownerElement.isXMLTag()) {
				return hasPrefix();
			}
		}
		else {
			DocumentImpl document = (DocumentImpl) getOwnerDocument();
			if (document != null && !document.isXMLType()) {
				// even in non-XML document, if having prefix, it's XML tag
				return hasPrefix();
			}
		}
		return true;
	}

	/**
	 * matchName method
	 * 
	 * @return boolean
	 * @param name
	 *            java.lang.String
	 */
	protected boolean matchName(String name) {
		if (name == null)
			return (this.name == null);
		if (this.name == null)
			return false;
		if (this.name.length() != name.length())
			return false;
		if (this.name.equals(name))
			return true;
		return this.name.equalsIgnoreCase(name) && ignoreCase();
	}


	/**
	 * notifyValueChanged method
	 */
	protected void notifyNameChanged() {
		if (this.ownerElement == null)
			return;
		DocumentImpl document = (DocumentImpl) this.ownerElement.getContainerDocument();
		if (document == null)
			return;
		DOMModelImpl model = (DOMModelImpl) document.getModel();
		if (model == null)
			return;
		model.nameChanged(this);
	}

	/**
	 * notifyValueChanged method
	 */
	protected void notifyValueChanged() {
		if (this.ownerElement == null)
			return;
		DocumentImpl document = (DocumentImpl) this.ownerElement.getContainerDocument();
		if (document == null)
			return;
		DOMModelImpl model = (DOMModelImpl) document.getModel();
		if (model == null)
			return;
		model.valueChanged(this);
	}

	/**
	 * removeRegions method
	 */
	void removeRegions() {
		this.nameRegion = null;
		this.valueRegion = null;
		this.equalRegion = null;
	}

	/**
	 */
	void resetRegions() {
		this.valueSource = getValueSource();
		removeRegions();
	}

	/**
	 */
	void resetRegions(ElementImpl ownerElement) {
		this.valueSource = getValueSource(ownerElement);
		removeRegions();
	}

	void setEqualRegion(ITextRegion equalRegion) {
		this.equalRegion = equalRegion;
	}

	/**
	 * setName method
	 * 
	 * @param name
	 *            java.lang.String
	 */
	protected void setName(String name) {
		String value = null;
		int startOffset = 0;
		if (this.ownerElement != null) {
			value = getValue();
			startOffset = this.ownerElement.getStartOffset();
			this.ownerElement.notify(CHANGE, this, value, null, startOffset);
		}
		this.name = name;
		if (this.ownerElement != null) {
			this.ownerElement.notify(CHANGE, this, null, value, startOffset);
		}
	}

	void setNameRegion(ITextRegion nameRegion) {
		this.nameRegion = nameRegion;
	}

	protected void setNamespaceURI(String namespaceURI) {
		this.namespaceURI = namespaceURI;
	}

	/**
	 * setNodeValue method
	 * 
	 * @param nodeValue
	 *            java.lang.String
	 */
	public void setNodeValue(String nodeValue) throws DOMException {
		setValue(nodeValue);
	}

	/**
	 * setOwnerElement method
	 * 
	 * @param ownerElement
	 *            org.w3c.dom.Element
	 */
	protected void setOwnerElement(Element ownerElement) {
		this.ownerElement = (ElementImpl) ownerElement;
	}

	/**
	 */
	public void setPrefix(String prefix) throws DOMException {
		if (this.ownerElement != null && !this.ownerElement.isDataEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}
		int prefixLength = (prefix != null ? prefix.length() : 0);
		String localName = getLocalName();
		if (prefixLength == 0) {
			setName(localName);
			return;
		}
		if (localName == null)
			localName = new String();
		int localLength = localName.length();
		StringBuffer buffer = new StringBuffer(prefixLength + 1 + localLength);
		buffer.append(prefix);
		buffer.append(':');
		buffer.append(localName);
		setName(buffer.toString());

		notifyNameChanged();
	}

	/**
	 * setValue method
	 * 
	 * @param value
	 *            java.lang.String
	 */
	public void setValue(String value) {
		// Remember: as we account for "floaters" in
		// future, remember that some are created
		// in the natural process of implementing
		// DOM apis.
		// this "self notification" of about/changed,
		// is added for this case, because it known to
		// be called from properties pages. Should be a
		// added to all DOM Modifiying APIs eventually.
		try {
			getModel().aboutToChangeModel();
			setValueSource(getValueSource(value));
		}
		finally {
			getModel().changedModel();
		}
	}

	void setValueRegion(ITextRegion valueRegion) {
		this.valueRegion = valueRegion;
		if (valueRegion != null)
			this.valueSource = null;
	}

	public void setValueSource(String source) {
		if (this.ownerElement != null && !this.ownerElement.isDataEditable()) {
			throw new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, new String());
		}
		this.valueSource = source;

		notifyValueChanged();
	}

	/**
	 * Subclasses must override
	 * 
	 * @param regionType
	 * @return
	 */
	protected boolean isNestedLanguageOpening(String regionType) {
		boolean result = false;
		return result;
	}
}
