/*******************************************************************************
 * Copyright (c) 2007 IBM Corporation.
 * 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
 *******************************************************************************/
package org.eclipse.cosmos.provisional.dr.drs.service.handler.cmdbf;

import java.io.PrintWriter;

import org.eclipse.cosmos.provisional.dr.drs.service.handler.common.IParameters;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class XMLtoNodeListFormatter extends AbstractFormatter implements
		IFormatter {

	public void render(PrintWriter output, IParameters input,
			Element graphResponse) throws Exception {
			StringBuffer buffer = new StringBuffer("{ identifier: \"object\",  label: \"title\",  items:["); //$NON-NLS-1$
			buffer.append(renderElement(graphResponse, true,getId(graphResponse)));
			buffer.append("]}"); //$NON-NLS-1$
			output.println(buffer.toString());			
	}

	protected Object getId(Object value){
		return idResolver.getId(value);
	}
	
	protected StringBuffer renderElement(Element elem, boolean rootElement, Object id) {
		NodeList children = elem.getChildNodes();
		StringBuffer buffer = new StringBuffer();
		StringBuffer childBuffer = new StringBuffer();
		String childrenStr = ""; //$NON-NLS-1$
		StringBuffer textContent = null;
		int count = 0;
		for (int x = 0; x < children.getLength(); x++) {
			Node node = children.item(x);
			if (node.getNodeType() == Element.ELEMENT_NODE) {				
				Object nodeId = getId(node);
				childBuffer.append(renderElement((Element) node, false, nodeId));
				if (childrenStr == "") //$NON-NLS-1$
					childrenStr += "["; //$NON-NLS-1$
				if (count > 0) {
					childrenStr += ","; //$NON-NLS-1$
				}
				childrenStr += "{_reference:\"" + nodeId + "\"}"; //$NON-NLS-1$ //$NON-NLS-2$
				count++;
			}
			if (node.getNodeType() == Element.TEXT_NODE){
				
				String nodeValue = node.getNodeValue();
				//TODO: need to encode text to JSON.  []()
/*				if (nodeValue.trim().length() > 0){
					if (textContent == null) textContent = new StringBuffer();
					textContent.append(nodeValue);
				}
				*/
			}
		}
		if (!rootElement){
			buffer.append(",{title:\"" + elem.getNodeName() + "\",nodeClass:\"element\",object:\"" + id + "\""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		}
		else{
			buffer.append("{title:\"" + elem.getNodeName() + "\",nodeClass:\"rootElement\",object:\"" + id + "\""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		}
		buffer.append(", store:\"["); //$NON-NLS-1$
		buffer.append("{name:'node', properties:["); //$NON-NLS-1$
		buffer.append("{name:'nodeName', value:'").append(elem.getNodeName()).append("'}"); //$NON-NLS-1$ //$NON-NLS-2$
		buffer.append(",{name:'prefix', value:'").append(elem.getPrefix()).append("'}"); //$NON-NLS-1$ //$NON-NLS-2$
		buffer.append(",{name:'namespaceURI', value:'").append(elem.getNamespaceURI()).append("'}"); //$NON-NLS-1$ //$NON-NLS-2$
		buffer.append(",{name:'baseURI', value:'").append(elem.getBaseURI()).append("'}"); //$NON-NLS-1$ //$NON-NLS-2$
		buffer.append(",{name:'localName', value:'").append(elem.getLocalName()).append("'}"); //$NON-NLS-1$ //$NON-NLS-2$
		NamedNodeMap attributes = elem.getAttributes();
		if (attributes.getLength() > 0){
			buffer.append("]},"); //$NON-NLS-1$
			buffer.append("{name:'attributes', properties:["); //$NON-NLS-1$
			
			//add properties to the element
			for (int x = 0; x < attributes.getLength(); x++){
				Node attribute = attributes.item(x);
				if (x > 0)
					buffer.append(","); //$NON-NLS-1$
				buffer.append("{name:'"+attribute.getNodeName()+"', value:'").append(attribute.getNodeValue()).append("'}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			}
		}
		if (textContent != null){
			buffer.append("]},"); //$NON-NLS-1$
			buffer.append("{name:'text content', properties:[");			 //$NON-NLS-1$
			buffer.append("{name:'content', value:'").append(textContent).append("'}"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		buffer.append("]}]\""); //$NON-NLS-1$
		if (childrenStr != "") { //$NON-NLS-1$
			childrenStr += "]"; //$NON-NLS-1$
			buffer.append(", children:").append(childrenStr); //$NON-NLS-1$
			buffer.append("}"); //$NON-NLS-1$
			buffer.append(childBuffer);
		} else
			buffer.append("}"); //$NON-NLS-1$
		return buffer;
	}
	
}
