/*******************************************************************************
 * 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.common.contentmodel.CMAttributeDeclaration;
import org.eclipse.wst.common.contentmodel.CMDataType;
import org.eclipse.wst.xml.core.commentelement.impl.CommentElementRegistry;
import org.eclipse.wst.xml.core.document.DocumentTypeAdapter;
import org.eclipse.wst.xml.core.document.JSPTag;
import org.eclipse.wst.xml.core.document.TagAdapter;
import org.eclipse.wst.xml.core.document.XMLAttr;
import org.eclipse.wst.xml.core.document.XMLCharEntity;
import org.eclipse.wst.xml.core.document.XMLDocument;
import org.eclipse.wst.xml.core.document.XMLElement;
import org.eclipse.wst.xml.core.document.XMLGenerator;
import org.eclipse.wst.xml.core.document.XMLNode;
import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Comment;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.EntityReference;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;


/** 
 */
public class XMLGeneratorImpl implements XMLGenerator {
	private static final String CDATA_CLOSE = "]]>";//$NON-NLS-1$
	private static final String CDATA_OPEN = "<![CDATA[";//$NON-NLS-1$
	private static final String COMMENT_CLOSE = "-->";//$NON-NLS-1$
	private static final String COMMENT_OPEN = "<!--";//$NON-NLS-1$
	private static final String DOCTYPE_OPEN = "<!DOCTYPE";//$NON-NLS-1$
	private static final String EMPTY_CLOSE = " />";//$NON-NLS-1$
	private static final String END_OPEN = "</";//$NON-NLS-1$

	private static XMLGeneratorImpl instance = null;
	private static final String PI_CLOSE = "?>";//$NON-NLS-1$
	private static final String PI_OPEN = "<?";//$NON-NLS-1$
	private static final String PUBLIC_ID = "PUBLIC";//$NON-NLS-1$
	private static final String SSI_PREFIX = "ssi";//$NON-NLS-1$
	//private static final String SSI_FEATURE = "SSI";//$NON-NLS-1$
	private static final String SSI_TOKEN = "#";//$NON-NLS-1$
	private static final String SYSTEM_ID = "SYSTEM";//$NON-NLS-1$
	private static final String TAG_CLOSE = ">";//$NON-NLS-1$

	/**
	 */
	public synchronized static XMLGenerator getInstance() {
		if (instance == null)
			instance = new XMLGeneratorImpl();
		return instance;
	}

	/**
	 */
	//private boolean isCommentTag(XMLElement element) {
	//	if (element == null) return false;
	//	DocumentImpl document = (DocumentImpl)element.getOwnerDocument();
	//	if (document == null) return false;
	//	DocumentTypeAdapter adapter = document.getDocumentTypeAdapter();
	//	if (adapter == null) return false;
	//	if (!adapter.hasFeature(SSI_FEATURE)) return false;
	//	String prefix = element.getPrefix();
	//	return (prefix != null && prefix.equals(SSI_PREFIX));
	//}
	/**
	 * Helper to modify the tag name in sub-classes
	 */
	private static void setTagName(Element element, String tagName) {
		if (element == null || tagName == null)
			return;
		((ElementImpl) element).setTagName(tagName);
	}

	/**
	 * XMLModelGenerator constructor
	 */
	private XMLGeneratorImpl() {
		super();
	}

	/**
	 */
	public String generateAttrName(Attr attr) {
		if (attr == null)
			return null;
		String attrName = attr.getName();
		if (attrName == null)
			return null;
		if (attrName.startsWith(JSPTag.TAG_OPEN)) {
			if (!attrName.endsWith(JSPTag.TAG_CLOSE)) {
				// close JSP
				return (attrName + JSPTag.TAG_CLOSE);
			}
		}
		if (((XMLAttr) attr).isGlobalAttr() && CMNodeUtil.getAttributeDeclaration(attr) != null) {
			switch (getAttrNameCase(attr)) {
				case DocumentTypeAdapter.UPPER_CASE :
					attrName = attrName.toUpperCase();
					break;
				case DocumentTypeAdapter.LOWER_CASE :
					attrName = attrName.toLowerCase();
					break;
				default :
					// ASIS_CASE
					break;
			}
		}
		return attrName;
	}

	/**
	 */
	public String generateAttrValue(Attr attr) {
		return generateAttrValue(attr, (char) 0); // no quote preference
	}

	/**
	 */
	public String generateAttrValue(Attr attr, char quote) {
		if (attr == null)
			return null;
		String name = attr.getName();
		SourceValidator validator = new SourceValidator(attr);
		String value = validator.convertSource(((XMLNode) attr).getValueSource());
		if (value == null || value.length() == 0) {
			if (name != null && name.startsWith(JSPTag.TAG_OPEN))
				return null;
			if (isBooleanAttr(attr)) {
				if (((AttrImpl) attr).isXMLAttr()) {
					// generate the name as value
					value = attr.getName();
				} else {
					// not to generate '=' and value for HTML boolean
					return null;
				}
			}
		}
		return generateAttrValue(value, quote);
	}

	/**
	 */
	public String generateAttrValue(String value, char quote) {
		// assume the valid is already validated not to include both quotes
		if (quote == '"') {
			if ((value != null) && (value.indexOf('"') >= 0))
				quote = '\''; // force
		} else if (quote == '\'') {
			if ((value != null) && (value.indexOf('\'') >= 0))
				quote = '"'; // force
		} else { // no preference
			if ((value != null) && (value.indexOf('"') < 0))
				quote = '"';
			else
				quote = '\'';
		}

		int length = (value == null ? 0 : value.length());
		StringBuffer buffer = new StringBuffer(length + 2);
		buffer.append(quote);
		if (value != null)
			buffer.append(value);
		buffer.append(quote);
		return buffer.toString();
	}

	/**
	 * generateCDATASection method
	 * 
	 * @return java.lang.String
	 * @param comment
	 *            org.w3c.dom.CDATASection
	 */
	public String generateCDATASection(CDATASection cdata) {
		if (cdata == null)
			return null;

		String data = cdata.getData();
		int length = (data != null ? data.length() : 0);
		StringBuffer buffer = new StringBuffer(length + 16);
		buffer.append(CDATA_OPEN);
		if (data != null)
			buffer.append(data);
		buffer.append(CDATA_CLOSE);
		return buffer.toString();
	}

	/**
	 * generateChild method
	 * 
	 * @return java.lang.String
	 * @param org.w3c.dom.Node
	 */
	public String generateChild(Node parentNode) {
		if (parentNode == null)
			return null;
		if (!parentNode.hasChildNodes())
			return null;

		StringBuffer buffer = new StringBuffer();
		for (Node child = parentNode.getFirstChild(); child != null; child = child.getNextSibling()) {
			String childSource = generateSource(child);
			if (childSource != null)
				buffer.append(childSource);
		}
		return buffer.toString();
	}

	/**
	 */
	public String generateCloseTag(Node node) {
		if (node == null)
			return null;

		switch (node.getNodeType()) {
			case Node.ELEMENT_NODE : {
				ElementImpl element = (ElementImpl) node;
				if (element.isCommentTag()) {
					if (element.isJSPTag())
						return JSPTag.COMMENT_CLOSE;
					return COMMENT_CLOSE;
				}
				if (element.isJSPTag())
					return JSPTag.TAG_CLOSE;
				if (element.isEmptyTag())
					return EMPTY_CLOSE;
				return TAG_CLOSE;
			}
			case Node.COMMENT_NODE : {
				CommentImpl comment = (CommentImpl) node;
				if (comment.isJSPTag())
					return JSPTag.COMMENT_CLOSE;
				return COMMENT_CLOSE;
			}
			case Node.DOCUMENT_TYPE_NODE :
				return TAG_CLOSE;
			case Node.PROCESSING_INSTRUCTION_NODE :
				return PI_CLOSE;
			case Node.CDATA_SECTION_NODE :
				return CDATA_CLOSE;
			default :
				break;
		}

		return null;
	}

	/**
	 * generateComment method
	 * 
	 * @return java.lang.String
	 * @param comment
	 *            org.w3c.dom.Comment
	 */
	public String generateComment(Comment comment) {
		if (comment == null)
			return null;

		String data = comment.getData();
		int length = (data != null ? data.length() : 0);
		StringBuffer buffer = new StringBuffer(length + 8);
		CommentImpl impl = (CommentImpl) comment;
		if (!impl.isJSPTag())
			buffer.append(COMMENT_OPEN);
		else
			buffer.append(JSPTag.COMMENT_OPEN);
		if (data != null)
			buffer.append(data);
		if (!impl.isJSPTag())
			buffer.append(COMMENT_CLOSE);
		else
			buffer.append(JSPTag.COMMENT_CLOSE);
		return buffer.toString();
	}

	/**
	 * generateDoctype method
	 * 
	 * @return java.lang.String
	 * @param docType
	 *            org.w3c.dom.DocumentType
	 */
	public String generateDoctype(DocumentType docType) {
		if (docType == null)
			return null;

		String name = docType.getName();
		int length = (name != null ? name.length() : 0);
		StringBuffer buffer = new StringBuffer(length + 16);
		buffer.append(DOCTYPE_OPEN);
		buffer.append(' ');
		if (name != null)
			buffer.append(name);
		DocumentTypeImpl dt = (DocumentTypeImpl) docType;
		String publicID = dt.getPublicId();
		String systemID = dt.getSystemId();
		if (publicID != null) {
			buffer.append(' ');
			buffer.append(PUBLIC_ID);
			buffer.append(' ');
			buffer.append('"');
			buffer.append(publicID);
			buffer.append('"');
			if (systemID != null) {
				buffer.append(' ');
				buffer.append('"');
				buffer.append(systemID);
				buffer.append('"');
			}
		} else {
			if (systemID != null) {
				buffer.append(' ');
				buffer.append(SYSTEM_ID);
				buffer.append(' ');
				buffer.append('"');
				buffer.append(systemID);
				buffer.append('"');
			}
		}
		buffer.append('>');
		return buffer.toString();
	}

	/**
	 * generateElement method
	 * 
	 * @return java.lang.String
	 * @param element
	 *            Element
	 */
	public String generateElement(Element element) {
		if (element == null)
			return null;

		// if empty tag is preferrable, generate as empty tag
		ElementImpl impl = (ElementImpl) element;
		if (impl.preferEmptyTag())
			impl.setEmptyTag(true);

		StringBuffer buffer = new StringBuffer();
		String startTag = generateStartTag(element);
		if (startTag != null)
			buffer.append(startTag);
		String child = generateChild(element);
		if (child != null)
			buffer.append(child);
		String endTag = generateEndTag(element);
		if (endTag != null)
			buffer.append(endTag);
		return buffer.toString();
	}

	/**
	 * generateEndTag method
	 * 
	 * @return java.lang.String
	 * @param element
	 *            org.w3c.dom.Element
	 */
	public String generateEndTag(Element element) {
		if (element == null)
			return null;

		ElementImpl impl = (ElementImpl) element;

		// first check if tag adapter exists
		TagAdapter adapter = (TagAdapter) impl.getExistingAdapter(TagAdapter.class);
		if (adapter != null) {
			String endTag = adapter.getEndTag(impl);
			if (endTag != null)
				return endTag;
		}

		if (impl.isEmptyTag())
			return null;
		if (!impl.isContainer())
			return null;
		if (impl.isJSPTag())
			return JSPTag.TAG_CLOSE;

		String tagName = generateTagName(element);
		int length = (tagName != null ? tagName.length() : 0);
		StringBuffer buffer = new StringBuffer(length + 4);
		buffer.append(END_OPEN);
		if (tagName != null)
			buffer.append(tagName);
		buffer.append('>');
		return buffer.toString();
	}

	/**
	 * generateEntityRef method
	 * 
	 * @return java.lang.String
	 * @param entityRef
	 *            org.w3c.dom.EntityReference
	 */
	public String generateEntityRef(EntityReference entityRef) {
		if (entityRef == null)
			return null;

		String name = entityRef.getNodeName();
		int length = (name != null ? name.length() : 0);
		StringBuffer buffer = new StringBuffer(length + 4);
		buffer.append('&');
		if (name != null)
			buffer.append(name);
		buffer.append(';');
		return buffer.toString();
	}

	/**
	 * generatePI method
	 * 
	 * @return java.lang.String
	 * @param pi
	 *            org.w3c.dom.ProcessingInstruction
	 */
	public String generatePI(ProcessingInstruction pi) {
		if (pi == null)
			return null;

		String target = pi.getTarget();
		String data = pi.getData();
		int length = (target != null ? target.length() : 0);
		if (data != null)
			length += data.length();
		StringBuffer buffer = new StringBuffer(length + 8);
		buffer.append(PI_OPEN);
		if (target != null)
			buffer.append(target);
		buffer.append(' ');
		if (data != null)
			buffer.append(data);
		buffer.append(PI_CLOSE);
		return buffer.toString();
	}

	/**
	 * generateSource method
	 * 
	 * @return java.lang.String
	 * @param node
	 *            org.w3c.dom.Node
	 */
	public String generateSource(Node node) {
		switch (node.getNodeType()) {
			case Node.ELEMENT_NODE :
				return generateElement((Element) node);
			case Node.TEXT_NODE :
				return generateText((Text) node);
			case Node.COMMENT_NODE :
				return generateComment((Comment) node);
			case Node.DOCUMENT_TYPE_NODE :
				return generateDoctype((DocumentType) node);
			case Node.PROCESSING_INSTRUCTION_NODE :
				return generatePI((ProcessingInstruction) node);
			case Node.CDATA_SECTION_NODE :
				return generateCDATASection((CDATASection) node);
			case Node.ENTITY_REFERENCE_NODE :
				return generateEntityRef((EntityReference) node);
			default :
				// DOCUMENT
				break;
		}
		return generateChild(node);
	}

	/**
	 * generateStartTag method
	 * 
	 * @return java.lang.String
	 * @param element
	 *            Element
	 */
	public String generateStartTag(Element element) {
		if (element == null)
			return null;

		ElementImpl impl = (ElementImpl) element;

		if (impl.isJSPTag()) {
			// check if JSP content type and JSP Document
			XMLDocument document = (XMLDocument) element.getOwnerDocument();
			if (document != null && document.isJSPType()) {
				if (document.isJSPDocument() && !impl.hasChildNodes()) {
					impl.setJSPTag(false);
				}
			} else {
				impl.setJSPTag(false);
			}
		}
		if (impl.isCommentTag() && impl.getExistingAdapter(TagAdapter.class) == null) {
			CommentElementRegistry registry = CommentElementRegistry.getInstance();
			registry.setupCommentElement(impl);
		}

		// first check if tag adapter exists
		TagAdapter adapter = (TagAdapter) impl.getExistingAdapter(TagAdapter.class);
		if (adapter != null) {
			String startTag = adapter.getStartTag(impl);
			if (startTag != null)
				return startTag;
		}

		StringBuffer buffer = new StringBuffer();

		if (impl.isCommentTag()) {
			if (impl.isJSPTag())
				buffer.append(JSPTag.COMMENT_OPEN);
			else
				buffer.append(COMMENT_OPEN);
			String tagName = generateTagName(element);
			if (tagName != null)
				buffer.append(tagName);
		} else if (impl.isJSPTag()) {
			buffer.append(JSPTag.TAG_OPEN);
			String tagName = generateTagName(element);
			if (tagName != null)
				buffer.append(tagName);
			if (impl.isContainer())
				return buffer.toString(); // JSP container
		} else {
			buffer.append('<');
			String tagName = generateTagName(element);
			if (tagName != null)
				buffer.append(tagName);
		}

		NamedNodeMap attributes = element.getAttributes();
		int length = attributes.getLength();
		for (int i = 0; i < length; i++) {
			AttrImpl attr = (AttrImpl) attributes.item(i);
			if (attr == null)
				continue;
			buffer.append(' ');
			String attrName = generateAttrName(attr);
			if (attrName != null)
				buffer.append(attrName);
			String attrValue = generateAttrValue(attr);
			if (attrValue != null) {
				// attr name only for HTML boolean and JSP
				buffer.append('=');
				buffer.append(attrValue);
			}
		}

		String closeTag = generateCloseTag(element);
		if (closeTag != null)
			buffer.append(closeTag);

		return buffer.toString();
	}

	/**
	 */
	public String generateTagName(Element element) {
		if (element == null)
			return null;
		XMLElement xe = (XMLElement) element;
		String tagName = element.getTagName();
		if (tagName == null)
			return null;
		if (xe.isJSPTag()) {
			if (tagName.equals(JSPTag.JSP_EXPRESSION))
				return JSPTag.EXPRESSION_TOKEN;
			if (tagName.equals(JSPTag.JSP_DECLARATION))
				return JSPTag.DECLARATION_TOKEN;
			if (tagName.equals(JSPTag.JSP_DIRECTIVE))
				return JSPTag.DIRECTIVE_TOKEN;
			if (tagName.startsWith(JSPTag.JSP_DIRECTIVE)) {
				int offset = JSPTag.JSP_DIRECTIVE.length() + 1; // after '.'
				return (JSPTag.DIRECTIVE_TOKEN + tagName.substring(offset));
			}
			return (xe.isCommentTag()) ? tagName : null;
		} else if (tagName.startsWith(JSPTag.TAG_OPEN)) {
			if (!tagName.endsWith(JSPTag.TAG_CLOSE)) {
				// close JSP
				return (tagName + JSPTag.TAG_CLOSE);
			}
		} else if (xe.isCommentTag()) {
			String prefix = element.getPrefix();
			if (prefix.equals(SSI_PREFIX)) {
				return (SSI_TOKEN + element.getLocalName());
			}
		} else {
			if (!xe.isJSPTag() && xe.isGlobalTag() && // global tag
						CMNodeUtil.getElementDeclaration(xe) != null) {
				String newName = tagName;
				switch (getTagNameCase(xe)) {
					case DocumentTypeAdapter.UPPER_CASE :
						newName = tagName.toUpperCase();
						break;
					case DocumentTypeAdapter.LOWER_CASE :
						newName = tagName.toLowerCase();
						break;
				}
				if (newName != tagName) {
					tagName = newName;
					setTagName(element, tagName);
				}
			}
		}
		return tagName;
	}

	/**
	 * generateText method
	 * 
	 * @return java.lang.String
	 * @param text
	 *            org.w3c.dom.Text
	 */
	public String generateText(Text text) {
		if (text == null)
			return null;
		TextImpl impl = (TextImpl) text;
		String source = impl.getTextSource();
		if (source != null)
			return source;
		return generateTextData(text, impl.getData());
	}

	/**
	 */
	public String generateTextData(Text text, String data) {
		if (data == null)
			return null;
		if (text == null)
			return null;
		TextImpl impl = (TextImpl) text;
		if (impl.isJSPContent() || impl.isCDATAContent()) {
			return new SourceValidator(impl).convertSource(data);
		}
		String source = data;

		// convert special characters to character entities
		StringBuffer buffer = null;
		int offset = 0;
		int length = data.length();
		for (int i = 0; i < length; i++) {
			String name = getCharName(data.charAt(i));
			if (name == null)
				continue;
			if (buffer == null)
				buffer = new StringBuffer(length + 8);
			if (i > offset)
				buffer.append(data.substring(offset, i));
			buffer.append('&');
			buffer.append(name);
			buffer.append(';');
			offset = i + 1;
		}
		if (buffer != null) {
			if (length > offset)
				buffer.append(data.substring(offset));
			source = buffer.toString();
		}

		if (source == null || source.length() == 0)
			return null;
		return source;
	}

	/**
	 */
	private int getAttrNameCase(Attr attr) {
		DocumentImpl document = (DocumentImpl) attr.getOwnerDocument();
		if (document == null)
			return DocumentTypeAdapter.STRICT_CASE;
		DocumentTypeAdapter adapter = document.getDocumentTypeAdapter();
		if (adapter == null)
			return DocumentTypeAdapter.STRICT_CASE;
		return adapter.getAttrNameCase();
	}

	/**
	 */
	private String getCharName(char c) {
		switch (c) {
			case '<' :
				return XMLCharEntity.LT_NAME;
			case '>' :
				return XMLCharEntity.GT_NAME;
			case '&' :
				return XMLCharEntity.AMP_NAME;
			case '"' :
				return XMLCharEntity.QUOT_NAME;
		}
		return null;
	}

	/**
	 */
	private int getTagNameCase(Element element) {
		DocumentImpl document = (DocumentImpl) element.getOwnerDocument();
		if (document == null)
			return DocumentTypeAdapter.STRICT_CASE;
		DocumentTypeAdapter adapter = document.getDocumentTypeAdapter();
		if (adapter == null)
			return DocumentTypeAdapter.STRICT_CASE;
		return adapter.getTagNameCase();
	}

	/**
	 */
	private boolean isBooleanAttr(Attr attr) {
		if (attr == null)
			return false;
		CMAttributeDeclaration decl = CMNodeUtil.getAttributeDeclaration(attr);
		if (decl == null)
			return false;
		CMDataType type = decl.getAttrType();
		if (type == null)
			return false;
		String values[] = type.getEnumeratedValues();
		if (values == null)
			return false;
		return (values.length == 1 && values[0].equals(decl.getAttrName()));
	}
}
