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

#ifndef LIBRARY_PARSER_HXX
#define LIBRARY_PARSER_HXX

#include "library.hxx"
#include "library-parser-templates.hxx"

namespace library
{
  namespace parser
  {
    //
    //
    typedef xml_schema::parser::unsigned_int isbn;


    //
    //
    struct title: templates::title<library::title,
                  std::string> // lang
    {
      virtual void
      pre ()
      {
        title_.clear ();
        title_.lang ("");
      }

      virtual void
      _characters (std::string const& v)
      {
        title_.assign (v);
      }

      virtual void
      lang (std::string const& lang)
      {
        title_.lang (lang);
      }

      virtual library::title
      post ()
      {
        return title_;
      }

    private:
      library::title title_;
    };


    //
    //
    struct genre: templates::genre<library::genre>
    {
      virtual void
      _characters (std::string const& v)
      {
        if (v == "romance") genre_ = romance; else
        if (v == "fiction") genre_ = fiction; else
        if (v == "horror") genre_ = horror; else
        if (v == "history") genre_ = history; else
        if (v == "philosophy") genre_ = philosophy;
      }

      virtual library::genre
      post ()
      {
        return genre_;
      }

    private:
      library::genre genre_;
    };


    //
    //
    struct author: templates::author<library::author,
                   std::string, // name
                   std::string, // born
                   std::string, // died
                   std::string> // recommends
    {
      virtual void
      pre ()
      {
        author_.name ("");
        author_.born ("");
        author_.died ("");
        author_.recommends ("");
      }

      virtual void
      name (std::string const& name)
      {
        author_.name (name);
      }

      virtual void
      born (std::string const& born)
      {
        author_.born (born);
      }

      virtual void
      died (std::string const& died)
      {
        author_.died (died);
      }

      virtual void
      recommends (std::string const& recommends)
      {
        author_.recommends (recommends);
      }

      virtual library::author
      post ()
      {
        return author_;
      }

    private:
      library::author author_;
    };


    //
    //
    struct book: templates::book<library::book,
                 library::isbn,   // isbn
                 library::title,  // title
                 library::genre,  // genre
                 library::author, // author
                 bool,            // available
                 std::string>     // id
    {
      virtual void
      pre ()
      {
        book_.author ().clear ();
        book_.available (false);
        book_.id ("");
      }

      virtual void
      isbn (library::isbn const& isbn)
      {
        book_.isbn (isbn);
      }

      virtual void
      title (library::title const& title)
      {
        book_.title (title);
      }

      virtual void
      genre (library::genre const& genre)
      {
        book_.genre (genre);
      }

      virtual void
      author (library::author const& author)
      {
        book_.author ().push_back (author);
      }

      virtual void
      available (bool const& available)
      {
        book_.available (available);
      }

      virtual void
      id (std::string const& id)
      {
        book_.id (id);
      }

      virtual library::book
      post ()
      {
        return book_;
      }

    private:
      library::book book_;
    };


    //
    //
    struct catalog: templates::catalog<library::catalog, library::book>
    {
      virtual void
      pre ()
      {
        catalog_.clear ();
      }

      virtual void
      book (library::book const& book)
      {
        catalog_.push_back (book);
      }

      virtual library::catalog
      post ()
      {
        return catalog_;
      }

    private:
      library::catalog catalog_;
    };
  }
}

#endif // LIBRARY_PARSER_HXX
