/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



package com.sun.star.xml.security.uno;

import org.w3c.dom.Node;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Attr;
import org.w3c.dom.NodeList;
import java.io.IOException;
import java.io.FileOutputStream;

/* uno classes */
import com.sun.star.xml.sax.XDocumentHandler;
import com.sun.star.xml.sax.XAttributeList;

/*
 * The SAXEventPrinter class is used to print out received
 * SAX event stream.
 */
class SAXEventPrinter implements XDocumentHandler
{
	/*
	 * how many spaces as the indent of line
	 */
	private int m_nIndent;
	
	/*
	 * whether a NEW LINE character need to be appended to 
	 * each line
	 */
	private boolean m_bIsFormatted;
	
	/*
	 * the output stream to write
	 */
	private FileOutputStream m_fileOutputStream;
	
	SAXEventPrinter(FileOutputStream fileOutputStream, boolean isFormatted)
	{
		m_nIndent = 0;
		m_fileOutputStream = fileOutputStream;
		m_bIsFormatted = isFormatted;
	}
	
	protected static void outputIndent(int m_nIndent, FileOutputStream fileOutputStream)
		throws IOException
	{
		for (int i=0; i<m_nIndent; ++i)
		{
			fileOutputStream.write(" ".getBytes());
		}
	}
	
	/*
	 * displays the tree of a Node.
	 */
	protected static void display(Node node, int indent, FileOutputStream fileOutputStream, boolean isFormatted)
		throws IOException
	{
		if (node != null)
		{
			int type = node.getNodeType();
			String message;
			NodeList children;
			int i, length;
			
			switch (type)
			{
			case Node.DOCUMENT_NODE:
				children = node.getChildNodes();
				length = children.getLength(); 
				for (i=0; i<length; ++i)
				{
					display(children.item(i), indent+2, fileOutputStream, isFormatted);
				}
				
				break;
				
			case Node.ELEMENT_NODE:
				message = new String("<"+node.getNodeName());
				NamedNodeMap attrs = node.getAttributes();
				
				length = attrs.getLength();
				for (i=0; i<length; ++i)
				{
					Attr attr = (Attr)attrs.item(i);
					message += " "+attr.getNodeName()+"=\""+attr.getNodeValue()+"\"";
				}
				
				message += ">";
				
				if (isFormatted)
				{
					outputIndent(indent, fileOutputStream);
				}
				
				fileOutputStream.write(message.getBytes("UTF-8"));
				
				if (isFormatted)
				{
					fileOutputStream.write("\n".getBytes());
				}
				
				children = node.getChildNodes();
				length = children.getLength();
				for (i=0; i<length; ++i)
				{
					display(children.item(i), indent+2, fileOutputStream, isFormatted);
				}
				
				if (isFormatted)
				{
					outputIndent(indent, fileOutputStream);
				}
				
				fileOutputStream.write("</".getBytes());
				fileOutputStream.write(node.getNodeName().getBytes("UTF-8"));
				fileOutputStream.write(">".getBytes());
				
				if (isFormatted)
				{
					fileOutputStream.write("\n".getBytes());
				}
				
				break;
				
			case Node.TEXT_NODE:
				message = node.getNodeValue();
				if (message != null )
				{
					if (isFormatted)
					{
						outputIndent(indent, fileOutputStream);
					}
					
					fileOutputStream.write(node.getNodeValue().getBytes("UTF-8"));
					
					if (isFormatted)
					{
						fileOutputStream.write("\n".getBytes());
					}
				}
				break;
				
			case Node.PROCESSING_INSTRUCTION_NODE:
				if (isFormatted)
				{
					outputIndent(indent, fileOutputStream);
				}
				
				fileOutputStream.write("<?".getBytes());
				fileOutputStream.write(node.getNodeName().getBytes("UTF-8"));
				fileOutputStream.write(node.getNodeValue().getBytes("UTF-8"));
				fileOutputStream.write("?>".getBytes());
				
				if (isFormatted)
				{
					fileOutputStream.write("\n".getBytes());
				}
				
				break;
			default:
				break;
			}
		}
	}

	/*
	 * XDocumentHandler
	 */
	public void  startDocument ()	
	{
	}
	
	public void endDocument()
	{
	}
	
	public void startElement (String str, com.sun.star.xml.sax.XAttributeList xattribs)
	{
		try
		{
			String message;
			
			message = new String("<"+str);
			if (xattribs !=null)
			{
				int length = xattribs.getLength();
				for (short i=0; i<length; ++i)
				{
					message += " "+xattribs.getNameByIndex(i)+"=\""+xattribs.getValueByIndex(i)+"\"";
				}
			}
			message += ">";
			
			if (m_bIsFormatted)
			{
				outputIndent(m_nIndent, m_fileOutputStream);
			}
			
			m_fileOutputStream.write(message.getBytes("UTF-8"));
			
			if (m_bIsFormatted)
			{
				m_fileOutputStream.write("\n".getBytes());
			}
			
			m_nIndent += 2;
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}

	public void endElement(String str)
	{
		try
		{
			m_nIndent -= 2;
			if (m_bIsFormatted)
			{
				outputIndent(m_nIndent, m_fileOutputStream);
			}
			
			m_fileOutputStream.write("</".getBytes());
			m_fileOutputStream.write(str.getBytes("UTF-8"));
			m_fileOutputStream.write(">".getBytes());
			
			if (m_bIsFormatted)
			{
				m_fileOutputStream.write("\n".getBytes());
			}
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}
	
	public void characters(String str)
	{
		try
		{
			if (m_bIsFormatted)
			{
				outputIndent(m_nIndent, m_fileOutputStream);
			}
			
			m_fileOutputStream.write(str.getBytes("UTF-8"));
			
			if (m_bIsFormatted)
			{
				m_fileOutputStream.write("\n".getBytes());
			}
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}
	
	public void ignorableWhitespace(String str)
	{
	}
	
	public void processingInstruction(String aTarget, String aData)
	{
		try
		{
			if (m_bIsFormatted)
			{
				outputIndent(m_nIndent, m_fileOutputStream);
			}
			
			m_fileOutputStream.write("<?".getBytes());
			m_fileOutputStream.write(aTarget.getBytes("UTF-8"));
			m_fileOutputStream.write("?>".getBytes());
			
			if (m_bIsFormatted)
			{
				m_fileOutputStream.write("\n".getBytes());
			}
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
	}

	public void setDocumentLocator (com.sun.star.xml.sax.XLocator xLocator ) 
		throws com.sun.star.xml.sax.SAXException
	{
	}
}
