// file      : xsd/examples/cxx/tree/mixed/driver.cxx
// author    : Boris Kolpackov <boris@codesynthesis.com>
// copyright : not copyrighted - public domain

#include <memory>   // std::auto_ptr
#include <iostream>

#include <xercesc/dom/DOM.hpp>

#include <xsd/cxx/xml/string.hxx> // Keeps us sane when working with Xerces.

#include "text.hxx"

using std::cout;
using std::cerr;
using std::endl;
using std::auto_ptr;

int
main (int argc, char* argv[])
{
  if (argc != 2)
  {
    cerr << "usage: " << argv[0] << " text.xml" << endl;
    return 1;
  }

  using namespace xercesc;

  int r (0);

  // The Xerces-C++ DOM types that will be associated with the
  // document tree "out-live" the call to the parsing function.
  // Therefore we need to initialize the Xerces-C++ runtime
  // ourselves.
  //
  XMLPlatformUtils::Initialize ();

  try
  {
    auto_ptr<text_type> t (
      text (argv[1],
            xml_schema::flags::keep_dom |
            xml_schema::flags::dont_initialize));

    // Note that DOM association is preserved in copies but only if they
    // are "complete", i.e., made from the root of the tree.
    //
    text_type copy (*t);

    // Print text.
    //
    {
      namespace xml = xsd::cxx::xml;

      unsigned long ref (0);
      DOMNode* root (copy._node ());

      for (DOMNode* n (root->getFirstChild ());
           n != 0;
           n = n->getNextSibling ())
      {
        switch (n->getNodeType ())
        {
        case DOMNode::TEXT_NODE:
          {
            cout << xml::transcode<char> (n->getTextContent ());
            break;
          }
        case DOMNode::ELEMENT_NODE:
          {
            cout << xml::transcode<char> (n->getTextContent ())
                 << "[" << ref << "]";
            ++ref;
            break;
          }
        }
      }
    }

    // Print references.
    //
    {
      unsigned long r (0);

      for (text_type::a::const_iterator i (copy.a ().begin ());
           i != copy.a ().end ();
           ++i, ++r)
      {
        cout << "[" << r << "] "  << i->href () << endl;
      }
    }
  }
  catch (xml_schema::exception const& e)
  {
    cerr << e << endl;
    r = 1;
  }

  XMLPlatformUtils::Terminate ();

  return r;
}
