/*******************************************************************************
 * 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.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.eclipse.wst.xml.core.internal.contentmodel.CMAttributeDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMDataType;
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()));
	}
}
