package basics.xml.writer;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import basics.application.Binder;
import basics.filesystem.file.FileUtl;
import basics.unexpected.Failure;

public class XMLWriter
{
String         filepath   = null;
FileWriter     writer     = null;
XMLSerializer  xmlWriter  = null;
AttributesImpl attributes = new AttributesImpl();

public XMLWriter(String filepath)
{
   this.filepath = filepath;
   File file = new File(filepath);
   try
   {
      if(file.exists())
         file.delete();
   }
   catch(Exception e)
   {
      throw new Failure(e, "Can't delete file: " + filepath);
   }
   try
   {
      writer = new FileWriter(file, true);
   }
   catch(IOException e)
   {
      throw new Failure(e, "Can't create writer for file: " + filepath);
   }
   if(writer != null)
   {
      xmlWriter = new XMLSerializer(writer, 4);
      try
      {
         if(xmlWriter != null)
         {
            xmlWriter.startDocument();
            startElement("xml");
         }
         else
         {
            throw new Failure("No xml writer available.");
         }
      }
      catch(SAXException e)
      {
         throw new Failure(e);
      }
   }
}

public void close()
{
   try
   {
      if(xmlWriter != null)
      {
         endElement("xml");
         xmlWriter.endDocument();
         try
         {
            writer.close();
         }
         catch(Exception e)
         {
            throw new Failure(e, "Can't delete file: " + filepath);
         }
      }
      else
      {
         throw new Failure("No xml writer available.");
      }
   }
   catch(SAXException e)
   {
      throw new Failure(e);
   }
}

private void resetAttributes()
{
   attributes = new AttributesImpl();
}

public void addAttribute(String name, String value)
{
   attributes.addAttribute((String)null, (String)null, name, "", value);
}

/**
 * before startElement: accumulate Attribute into the internal buffer by calling addAttribute(..);
 * attributes are written when you call startElement. After writing the element the attributes
 * buffer ist reset.
 * @param qname
 */
public void startElement(String qname)
{
   try
   {
      if(xmlWriter != null)
      {
         org.xml.sax.Attributes attr = attributes;
         xmlWriter.startElement((String)null, (String)null, qname, attr);
         resetAttributes();
      }
      else
      {
         throw new Failure("No xml writer available.");
      }
   }
   catch(SAXException e)
   {
      throw new Failure(e);
   }
}

public void element(String content)
{
   try
   {
      if(xmlWriter != null)
      {
         xmlWriter.characters(content.toCharArray(), 0, content.length());
      }
      else
      {
         throw new Failure("No xml writer available.");
      }
   }
   catch(SAXException e)
   {
      throw new Failure(e);
   }
}

public void endElement(String qname)
{
   try
   {
      if(xmlWriter != null)
      {
         xmlWriter.endElement((String)null, (String)null, qname);
         resetAttributes();
      }
      else
      {
         throw new Failure("No xml writer available.");
      }
   }
   catch(SAXException e)
   {
      throw new Failure(e);
   }
}

/**
 * @param args
 */
//public static void main (String[] args)
public static void unittest()
{
   File file = Binder.getBasedir();
   String path = new File(file, "work/f2/writer.xml").getAbsolutePath();
   FileUtl.delete(path);
   XMLWriter w = new XMLWriter(path);
   w.startElement("one");
   w.addAttribute("a", "1");
   w.addAttribute("b", "22");
   w.addAttribute("c", "33.3");
   // w.startElement("one");
   w.startElement("two");
   w.element("Das ist <b>fetter</b> Text.\nZweite Zeile.");
   w.endElement("two");
   w.endElement("one");
   w.close();
}
}
