/*******************************************************************************
 * Copyright (c) 2002, 2010 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.contentmodel.util;

import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;

import org.w3c.dom.Attr;
import org.w3c.dom.CDATASection;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentType;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.Text;


/**
 * This is a hacked up dom writer stolen from a Xerces sample.
 * I'd like to use an exisitng 'generic DOM' writer
 * If anyone can find such a thing then please go ahead and junk this.
 *
 * @version
 */
public class DOMWriter
{
  protected boolean formattingEnabled = true;
   protected boolean outputDoctypeEnabled = true;
   protected PrintWriter out;
   protected int indent = 0;  

   public DOMWriter() throws UnsupportedEncodingException
   {
     this(System.out);
   }

   public DOMWriter(OutputStream outputSteam)
   {
     out = new PrintWriter(outputSteam);
   }

   public DOMWriter(Writer writer)
   {
     out = new PrintWriter(writer);
   }

   public void setFormattingEnabled(boolean enabled)
   {
     formattingEnabled = enabled;
   }

   public boolean getFormattingEnabled()
   {
     return formattingEnabled;
   }

   public void setOutputDoctypeEnabled(boolean enabled)
   {
     outputDoctypeEnabled = enabled;
   }

   public class XMLVisitor
   {
     protected boolean currentElementHasChildElements = false;

     public void visitNode(Node node)
     {
       switch (node.getNodeType())
       {
         case Node.ATTRIBUTE_NODE :
         {
           visitAttr((Attr)node);
           break;
         }
         case Node.CDATA_SECTION_NODE :
         {
           visitCDATASection((CDATASection)node);
           break;
         }
         case Node.COMMENT_NODE :
         {
           visitComment((Comment)node);
           break;
         }
         case Node.DOCUMENT_NODE :
         {
           visitDocument((Document)node);
           break;
         }
         case Node.DOCUMENT_TYPE_NODE :
         {
           visitDocumentType((DocumentType)node);
           break;
         }
         case Node.ELEMENT_NODE :
         {
           visitElement((Element)node);
           break;
         }
         case Node.PROCESSING_INSTRUCTION_NODE :
         {
           visitProcessingInstruction((ProcessingInstruction)node);
           break;
         }
         case Node.TEXT_NODE :
         {
           visitText((Text)node);
           break;
         }
       }
     }

     public void visitDocument(Document document)
     {
       visitChildNodesHelper(document);
     }

     public void visitDocumentType(DocumentType doctype)
     {                       
       if (outputDoctypeEnabled)
       {
         String data = getDocumentTypeData(doctype);
         print("<!DOCTYPE " + data + ">"); //$NON-NLS-1$ //$NON-NLS-2$
       }
     }

     public void visitElement(Element element)
     {                                  
       if (!doShow(element))
         return;

       boolean parentElementHasChildNodes = currentElementHasChildElements;
       currentElementHasChildElements = hasChildElements(element);

       printIndent();
       print("<"); //$NON-NLS-1$
       print(element.getNodeName());
       visitAttributesHelper(element);

       boolean hasChildNodes = element.getChildNodes().getLength() > 0;                
       boolean isRootElement = element.getParentNode().getNodeType() == Node.DOCUMENT_NODE;
       if (hasChildNodes || isRootElement)
       {
         if (currentElementHasChildElements)
         {
           println(">"); //$NON-NLS-1$
         }
         else
         {
           print(">"); //$NON-NLS-1$
         }
         indent += 2;
         visitChildNodesHelper(element);
         indent -= 2;

         if (currentElementHasChildElements || isRootElement)
         {
           printIndent();
         }
         print("</"); //$NON-NLS-1$
         print(element.getNodeName());
         println(">"); //$NON-NLS-1$
       }
       else
       {
         println("/>"); //$NON-NLS-1$
       }

       currentElementHasChildElements = parentElementHasChildNodes;
     }

     public void visitAttr(Attr attr)
     {
       print(" "); //$NON-NLS-1$
       print(attr.getNodeName());
       print("=\""); //$NON-NLS-1$
       print(createPrintableCharacterData(attr.getValue()));
       print("\""); //$NON-NLS-1$
     }

     public void visitText(Text text)
     {
       if (currentElementHasChildElements)
       {
         printIndent();
         print(createPrintableCharacterData(text.getNodeValue()));
         println();
       }
       else
       {
         print(createPrintableCharacterData(text.getNodeValue()));
       }
     }

     public void visitCDATASection(CDATASection cdataSection)
     {
     }

     public void visitComment(Comment comment)
     {
       printIndent();
       print("<!--"); //$NON-NLS-1$
       print(comment.getNodeValue());
       println("-->"); //$NON-NLS-1$
     }

     public void visitProcessingInstruction(ProcessingInstruction pi)
     {
       printIndent();
       print("<?"); //$NON-NLS-1$
       print(pi.getNodeName());
       print(" "); //$NON-NLS-1$
       print(pi.getNodeValue());
       println("?>"); //$NON-NLS-1$
     }
             

     public boolean hasChildElements(Node node)
     {
       boolean result = false;
       NodeList children = node.getChildNodes();
       for (int i = 0; i < children.getLength(); i++)
       {
         if (children.item(i).getNodeType() == Node.ELEMENT_NODE)
         {
           result = true;
           break;
         }
       }
       return result;
     }

     public void visitChildNodesHelper(Node node)
     {
       NodeList children = node.getChildNodes();
       for (int i = 0; i < children.getLength(); i++)
       {
         visitNode(children.item(i));
       }
     }

     public void visitAttributesHelper(Node node)
     {
       NamedNodeMap map = node.getAttributes();
       for (int i = 0; i < map.getLength(); i++ )
       {
         visitNode(map.item(i));
       }
     }
   }

  /** an ugly hack until I restruct this code a little
   *  
   */  
  protected boolean doShow(Element element)    
  {
    return true;
  }
                                               
  /** converts DOM text values to 'printable' values 
   *  - converts '&' to '&amp;'
   */
  protected String createPrintableCharacterData(String string)
  {              
    String result = ""; //$NON-NLS-1$
    int index = 0;                             
    while (true)
    {                                                 
      int ampersandIndex = string.indexOf("&", index); //$NON-NLS-1$
      if (ampersandIndex != -1)
      {
        result += string.substring(index, ampersandIndex);
        result += "&amp;"; //$NON-NLS-1$
        index = ampersandIndex + 1; 
      }
      else
      {
        break;
      }
    } 
    result += string.substring(index);
    return result;
  }


  /** Prints the specified node, recursively. */
  public void print(Node node)
  {
    // is there anything to do?
    if (node != null)
    {
      XMLVisitor visitor = new XMLVisitor();
      visitor.visitNode(node);
    }
    out.flush();
  }

  /** a temporary hack to workaround our inability to create a DocumentType tag*/
  public void print(Document document, String grammarURL)
  {
    String systemId = null;
    if (grammarURL.endsWith("dtd")) //$NON-NLS-1$
    {
      int lastSlashIndex = Math.max(grammarURL.lastIndexOf("/"), grammarURL.lastIndexOf("\\")); //$NON-NLS-1$ //$NON-NLS-2$
      if (lastSlashIndex != -1)
      {
        systemId = grammarURL.substring(lastSlashIndex + 1);
      }
    }
    print(document, "UTF-8", grammarURL, null, systemId); //$NON-NLS-1$

  }

  /** a temporary hack to workaround our inability to create a DocumentType tag*/
  public void print(Document document, String encoding, String grammarFileName, String publicId, String systemId)
  {
    out.println("<?xml version=\"1.0\"" + " encoding=\"" + encoding + "\"?>");   //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
    if (grammarFileName.endsWith(".dtd")) //$NON-NLS-1$
    {
      String docTypeLine = "<!DOCTYPE " + document.getDocumentElement().getNodeName() + " "; //$NON-NLS-1$ //$NON-NLS-2$
      if (publicId != null) 
      {
        docTypeLine += "PUBLIC \"" + publicId + "\" "; //$NON-NLS-1$ //$NON-NLS-2$
        if (systemId != null)
        {
          docTypeLine += "\"" + systemId + "\" "; //$NON-NLS-1$ //$NON-NLS-2$
        }
        docTypeLine += ">"; //$NON-NLS-1$
        out.println(docTypeLine);
      }
      else if (systemId != null)
      {
        docTypeLine += "SYSTEM \"" + systemId + "\" >"; //$NON-NLS-1$ //$NON-NLS-2$
        out.println(docTypeLine);
      }
    }
    print(document);
  }  

  public static String getDocumentTypeData(DocumentType doctype)
  {
    String data = doctype.getName();
    if (doctype.getPublicId() != null)
    {
      data += " PUBLIC \"" + doctype.getPublicId() + "\""; //$NON-NLS-1$ //$NON-NLS-2$
      String systemId = doctype.getSystemId();
      if (systemId == null)
      {
        systemId = ""; //$NON-NLS-1$
      }
      data += " \"" + systemId + "\"";      //$NON-NLS-1$ //$NON-NLS-2$
    }
    else
    {
      data += " SYSTEM \"" + doctype.getSystemId() + "\""; //$NON-NLS-1$ //$NON-NLS-2$
    }
    return data;
  }     

  public void println()
  {
    if (formattingEnabled)
    {
      out.println();
    }
  }

  public void println(String string)
  {
    if (formattingEnabled)
    {
      out.println(string);
    }
    else
    {
      out.print(string);
    }
  }

  public void printIndent()
  {             
    if (formattingEnabled)
    {
      for (int i = 0; i < indent; i++)
      {
        out.print(" "); //$NON-NLS-1$
      }
    }
  }       

  public void print(String string)
  {
    out.print(string);
  }
}

