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

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

#include "library.hxx"

using std::cerr;
using std::endl;

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

  using namespace library;

  // Read in the file.
  //
  std::auto_ptr<class catalog> l (catalog (argv[1]));


  // Let's print what we've got.
  //
  for (catalog::book::const_iterator bi (l->book ().begin ());
       bi != l->book ().end ();
       ++bi)
  {
    cerr << endl
         << "ID           : " << bi->id () << endl
         << "ISBN         : " << bi->isbn () << endl
         << "Title        : " << bi->title ()  << endl
         << "Genre        : " << bi->genre () << endl;

    for (book::author::const_iterator ai (bi->author ().begin ());
         ai != bi->author ().end ();
         ++ai)
    {
      cerr << "Author       : " << ai->name () << endl;
      cerr << "  Born       : " << ai->born () << endl;

      if (ai->died.present ())
        cerr << "  Died       : " << ai->died () << endl;

      if (ai->recommends.present ())
      {
        book const& b (dynamic_cast<book const&> (*ai->recommends ()));

        cerr << "  Recommends : " << b.title () << endl;
      }
    }

    cerr  << "Available    : " << std::boolalpha << bi->available () << endl;
  }


  // Now we are going to modify in-memory representation and serialize it
  // back to XML.
  //

  catalog::book::sequence& bs (l->book ());


  // Get rid of all unavailable books.
  //
  for (catalog::book::iterator bi (bs.begin ()); bi != bs.end ();)
  {
    if (!bi->available ())
      bi = bs.erase (bi);
    else
      ++bi;
  }


  // Insert a new book.
  //
  book b (679776443,            // ISBN
          title ("Dead Souls"), // Title
          genre::philosophy,    // Genre
          true,                 // Available
          "DS");                // ID

  b.author ().push_back (author ("Nikolai Gogol", "1809-03-31"));

  bs.insert (bs.begin (), b);


  // Because we removed all unavailable books, some IDREFs might be
  // broken. Let's fix this.
  //
  for (catalog::book::iterator bi (bs.begin ()); bi != bs.end (); ++bi)
  {
    for (book::author::iterator ai (bi->author ().begin ());
         ai != bi->author ().end ();
         ++ai)
    {
      if (ai->recommends.present ())
      {
        if (!ai->recommends ())
          ai->recommends.reset ();
      }
    }
  }


  // Prepare namespace mapping and schema location information.
  //
  xml_schema::namespace_infomap map;

  map["lib"].name = "http://www.codesynthesis.com/library";
  map["lib"].schema = "library.xsd";


  // Write it out.
  //
  catalog (std::cout, *l, map);
}
