/**
 * Copyright (c) 2008 Oracle 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:
 *    Oracle Corporation - initial API and implementation
 */
package org.eclipse.jst.jsf.apache.trinidad.tagsupport.converter.operations;

import java.io.ByteArrayInputStream;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.eclipse.jst.pagedesigner.dtmanager.converter.ITransformOperation;
import org.eclipse.jst.pagedesigner.dtmanager.converter.operations.TransformOperationFactory;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

/**
 * ITransformOperation implementation specifically for the "outputFormatted" JSF
 * Element.
 * 
 * <br><b>Note:</b> requires ITransformOperation.setTagConverterContext(...) to
 * have been called to provide a valid ITagConverterContext instance prior to
 * a call to the transform(...) method.
 * 
 * @author Ian Trimble - Oracle
 */
public class OutputFormattedOperation extends AbstractTrinidadTransformOperation {

	/*
	 * NOTICE (especially if looking for missing whitespace):
	 * Because this operation can potentially return a mix of child Element
	 * and Text nodes inside a span Element, it can suffer from bug #221629
	 * (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=221629).
	 * This operation is not the cause of the above-mentioned bug.
	 */

	private static final String STYLECLASS_INSTRUCTION = "AFInstructionText"; //$NON-NLS-1$
	private static final String STYLECLASS_PAGESTAMP = "OraPageStampText"; //$NON-NLS-1$
	private static final String STYLECLASS_INCONTEXTBRANDING = "p_InContextBrandingText"; //$NON-NLS-1$

	/* (non-Javadoc)
	 * @see org.eclipse.jst.pagedesigner.dtmanager.converter.operations.AbstractTransformOperation#transform(org.w3c.dom.Element, org.w3c.dom.Element)
	 */
	@Override
	public Element transform(Element srcElement, Element curElement) {
		//create outer span element and set class attribute
		Element spanElement = createElement("span"); //$NON-NLS-1$
		ITransformOperation operation =
			TransformOperationFactory.getInstance().getTransformOperation(
					TransformOperationFactory.OP_CopyAttributeWithRenameOperation,
					new String[]{"inlineStyle", "style"}); //$NON-NLS-1$  //$NON-NLS-2$
		operation.transform(srcElement, spanElement);

		String styleClass = srcElement.getAttribute("styleClass"); //$NON-NLS-1$
		if (styleClass == null || styleClass.length() < 1) {
			String styleUsage = srcElement.getAttribute("styleUsage"); //$NON-NLS-1$
			if (styleUsage != null && styleUsage.length() > 8) {
				if (styleUsage.equals("instruction")) { //$NON-NLS-1$
					styleClass = STYLECLASS_INSTRUCTION;
				} else if (styleUsage.equals("pageStamp")) { //$NON-NLS-1$
					styleClass = STYLECLASS_PAGESTAMP;
				} else if (styleUsage.equals("inContextBranding")) { //$NON-NLS-1$
					styleClass = STYLECLASS_INCONTEXTBRANDING;
				}
			}
		}
		if (styleClass != null && styleClass.length() > 0) {
			appendAttribute(spanElement, "class", styleClass); //$NON-NLS-1$
		}

		//deal with value
		String value = srcElement.getAttribute("value"); //$NON-NLS-1$
		if (value != null && value.length() > 0) {
			StringBuffer wrappedValue = new StringBuffer();
			wrappedValue.append("<?xml version=\"1.0\"?><value>"); //$NON-NLS-1$
			wrappedValue.append(value);
			wrappedValue.append("</value>"); //$NON-NLS-1$
			InputStream inputStream = new ByteArrayInputStream(wrappedValue.toString().getBytes());
			Element valueElement = getValueDocumentElement(inputStream);
			if (valueElement != null) {
				if (!appendValueNodes(spanElement, valueElement)) {
					//remove any children added before appendValueNodes failed
					NodeList childNodes = spanElement.getChildNodes();
					for (int i = 0; i < childNodes.getLength(); i++) {
						spanElement.removeChild(childNodes.item(i));
					}
					//set as simple text
					appendChildText(value, spanElement);
				}
			} else {
				//set as simple text
				appendChildText(value, spanElement);
			}
		}

		return spanElement;
	}

	private Element getValueDocumentElement(InputStream inputStream) {
		Element element = null;
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		//TODO: entity expansion should be set to false for ".jsp", true for ".jspx"
		factory.setExpandEntityReferences(true);
		try {
			DocumentBuilder builder = factory.newDocumentBuilder();
			Document document = builder.parse(inputStream);
			element = document.getDocumentElement();
		} catch(Exception e) {
			//fail on any exception - text with markup will be rendered instead
		}
		return element;
	}

	private boolean appendValueNodes(Node parentNode, Node currentNode) {
		boolean success = true;
		try {
			NodeList childNodes = currentNode.getChildNodes();
			for (int i = 0; i < childNodes.getLength(); i++) {
				Node childNode = childNodes.item(i);
				if (childNode instanceof Element) {
					//TODO: elements should be filtered to only create elements specified for this tag
					Element newElement = (Element)parentNode.appendChild(
						parentNode.getOwnerDocument().createElement(
								childNode.getNodeName()));
					NamedNodeMap attrMap = childNode.getAttributes();
					if (attrMap != null) {
						for (int j = 0; j < attrMap.getLength(); j++) {
							Attr attr = (Attr)attrMap.item(j);
							//TODO: attributes should be filtered to only create attributes specified for this tag
							newElement.setAttribute(
									attr.getName(), attr.getValue());
						}
					}
					success &= appendValueNodes(newElement, childNode);
				} else if (childNode instanceof Text) {
					parentNode.appendChild(
							parentNode.getOwnerDocument().createTextNode(
									childNode.getTextContent()));
				}
			}
		} catch(Exception e) {
			//fail on any exception - text with markup will be rendered instead
			success = false;
		}
		return success;
	}

}
