/*******************************************************************\

              Copyright (C) 2003 Joseph Coffland

    This program is free software; you can redistribute it and/or
     modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
        of the License, or (at your option) any later version.

   This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
             GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software
      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
                           02111-1307, USA.

            For information regarding this software email
                   jcofflan@users.sourceforge.net

\*******************************************************************/


#ifndef XMLSERIALIZER_H
#define XMLSERIALIZER_H

#include "XMLEventTypes.h"
#include "XMLSerializable.h"

#include <string>
#include <map>

/** 
 * A XML serializer interface similar to SAX but in reverse.
 */
class XMLSerializer : public virtual XMLEventTypes {

public:
  /**
   * The element attribute type definition.  This is just a
   * std::map.  You can create attributes as follows:
   * 
   * XMLSerializer::attributes_t attrs;<br>
   * attrs["anAttribute"] = "aValue";
   */
  typedef std::map<const std::string, std::string> attributes_t;

  /** 
   * Serialize an XMLSerializable.
   */
  virtual void serialize(const std::string targetNamespace,
			 const std::string topElementName,
			 XMLSerializable &serializable) = 0;

  /** 
   * Start the XML document.
   */
  virtual void startDocument() = 0;

  /** 
   * Start an element.
   * 
   * @param qname The fully qualified element name.
   * @param attributes The elements attributes.
   */
  virtual void startElement(const std::string qname, 
			    attributes_t &attributes) = 0;

  /** 
   * Start an attributeless element.
   * 
   * @param qname The fully qualified element name.
   */
  virtual void startElement(const std::string qname) = 0;

  /** 
   * Output character data.  This data will be escaped if
   * isEscaping() is true.  If you call setEscaping(false) and
   * use this function there is no garuntee that your XML
   * will be well-formed.  If you print characters such as <, >,
   * or & it will likely be invalid.
   * 
   * @param text The text to print.
   */
  virtual void characters(const std::string text) = 0;

  /** 
   * Close an element.  XMLSerializer implementations must
   * remember the name of the element be closed.
   */
  virtual void endElement() = 0;

  /** 
   * End the XML document.  Subsequent calls to startElement,
   * endElement, characters, etc. will throw BasicExceptions.
   */
  virtual void endDocument() = 0;

  /** 
   * Output an XML comment.  These are of the format <!-- text -->
   * 
   * @param text The comment text.
   */
  virtual void comment(const std::string text) = 0;

  /** 
   * Output an XML processing instruction.
   */
  virtual void processingInstruction(const std::string target, 
				     const std::string data) = 0;

  /** 
   * Flush the output buffer.
   */
  virtual void flush() = 0;

  /// Print an end of line character to the output stream.
  virtual void endl() = 0;

  /** 
   * Set the escaping mode.  If you turn off escaping there is no
   * garuntee that the XML will be valid!
   * 
   * @param value True for escaping.  False for no escaping.
   */
  virtual void setEscaping(const bool value) = 0;

  /// @return True if escaping is on, false otherwise.
  virtual bool isEscaping() = 0;

  /** 
   * @param value Turn pretty printing on if true, otherwise turn it off.
   */
  virtual void setPrettyPrinting(const bool value) = 0;

  /// @return True if pretty printing is on, false otherwise.
  virtual bool isPrettyPrinting() = 0;

  /// Set the pretty printing tab size in number of spaces.
  virtual void setTabSize(const int size) = 0;

  /// @return The current pretty printing tab size in number spaces.
  virtual int getTabSize() = 0;

  /// @return True if the element short form is allowed.
  virtual bool isShortFormAllowed() = 0;
  
  /** 
   * Control usage of the element short form.  Elements with no children
   * can us an XML short form.  For example the element <a></a> can also
   * be written as <a/>.
   * 
   * @param value If true element short for is allowed, otherwise not.
   */
  virtual void setShortFormAllowed(const bool value) = 0;
};

#endif
