import java.io.*;
import javax.xml.parsers.*;

import org.w3c.dom.*;

/**
 * <p>Title: wms Beautifier</p>
 * <p>Description: File to re-indent Windows Media Player skins to my liking </p>
 * <p>Copyright: Copyright (c) 2003</p>
 * <p>Company: Stardock</p>
 * @author Adam Najanowicz
 * @version 1.1
 */

public class WMSBeautifier {

  static Writer targetWriter = null;
  static int indentLevel = 0;

  public static void insertNewLine() {
    try {
      targetWriter.write("\n");
      int i = 0;
      while (i++ < indentLevel) {
        targetWriter.write("\t");
      }
    }
    catch (IOException ex) {
      System.out.println(ex.toString());
    }
  }

  public static boolean serializeNode(Node node) {
    try {
      switch (node.getNodeType()) {
        case (Node.ELEMENT_NODE):
          insertNewLine();
          targetWriter.write("<" + ( (Element) node).getNodeName());
          indentLevel++;
          NamedNodeMap attributes = ( (Element) node).getAttributes();
          int i = -1;

          //System.out.println(attributes.getLength());
          while (++i < attributes.getLength()) {
            insertNewLine();
            Attr attr = (Attr) attributes.item(i);
            targetWriter.write(attr.getName() + "=\"" + attr.getValue() + "\"");
          }

          Node child = node.getFirstChild();
          if(child != null) {
            insertNewLine();
            targetWriter.write(">");
            while (child != null) {
              serializeNode(child);
              child = child.getNextSibling();
            }
            indentLevel--;
            insertNewLine();
            targetWriter.write("</" + ( (Element) node).getNodeName() + ">");

          } else {
            insertNewLine();
            targetWriter.write("/>");
            indentLevel--;
          }

          return true;

        case (Node.COMMENT_NODE):
          insertNewLine();
          targetWriter.write("<!--" + ( (Comment) node).getNodeValue() +
                             "-->");
          return true;
        case (Node.TEXT_NODE):
          targetWriter.write( ( (Text) node).getNodeValue().trim());
          return true;
        case (Node.ENTITY_NODE):
          targetWriter.write( ( (Entity) node).getNotationName());
          return true;
        case (Node.ENTITY_REFERENCE_NODE):
          targetWriter.write( ( (EntityReference) node).getNodeType());
          return true;
      }
      System.out.println("Unsupported node type: "+ node.getClass().getName());
    }
    catch (IOException ex) {
      System.out.println(ex.toString());
    }
    return false;
  }

  public static void main(String[] args) {
    try {
      DocumentBuilderFactory parserFactory = DocumentBuilderFactory.newInstance();
      DocumentBuilder parser = parserFactory.newDocumentBuilder();
      Document domDocument = parser.parse(new java.io.File(args[0]));

      //copy the file first
      int iBytesCopied = 0;
      char[] copyArray = new char[1000024];
      Reader reader = new FileReader(args[0]);
      Writer copyWriter = new BufferedWriter(new FileWriter(new File(args[0] +".bak")));
      do {
        iBytesCopied = reader.read(copyArray);
        copyWriter.write(copyArray,0,iBytesCopied);
      }while(iBytesCopied == copyArray.length);
      copyWriter.close();
      reader.close();

      //initialize the target file
      targetWriter = new BufferedWriter(new FileWriter(new File(args[0])));
      serializeNode(domDocument.getDocumentElement());
    }
    catch (Exception ex) {
      System.out.println(ex.toString());
    }
    try {
      targetWriter.flush();
      targetWriter.close();
    }
    catch (IOException ex1) {
      System.out.println(ex1.toString());
    }
  }

}