// file      : xsd/cxx/parser.hxx
// author    : Boris Kolpackov <boris@codesynthesis.com>
// copyright : Copyright (c) 2005 Code Synthesis Tools CC
// license   : GNU GPL v2 + exceptions; see accompanying LICENSE file

#ifndef XSD_CXX_PARSER_HXX
#define XSD_CXX_PARSER_HXX

#include <xsd/cxx/xml/dom/elements.hxx>

namespace xsd
{
  namespace cxx
  {
    template <typename C>
    class parser
    {
    public:
      parser (xml::dom::element<C> const& e)
          : e_ (e.dom_element ()->getChildNodes ()), ei_ (0),
            a_ (e.dom_element ()->getAttributes ()), ai_ (0)
      {
        find_next_element ();
      }

      bool
      more_elements () const
      {
        return e_->getLength () > ei_;
      }

      xml::dom::element<C>
      next_element ()
      {
        xml::dom::element<C> r (
          dynamic_cast<xercesc::DOMElement*> (e_->item (ei_++)));

        find_next_element ();

        //std::cerr << "element: " << r.namespace_ () << "#" << r.name ()
        //          << std::endl;

        return r;
      }

      bool
      more_attributes () const
      {
        return a_->getLength () > ai_;
      }

      xml::dom::attribute<C>
      next_attribute ()
      {
        return xml::dom::attribute<C> (
          dynamic_cast<xercesc::DOMAttr*> (a_->item (ai_++)));
      }

    private:
      void
      find_next_element ()
      {
        using xercesc::DOMNode;

        for (; ei_ < e_->getLength () &&
               e_->item (ei_)->getNodeType () != DOMNode::ELEMENT_NODE;
             ++ei_);
      }

    private:
      parser (parser const&);

      parser&
      operator= (parser const&);

    private:
      xercesc::DOMNodeList const* e_;
      unsigned long ei_; // Index of the next DOMElement.

      xercesc::DOMNamedNodeMap const* a_;
      unsigned long ai_;
    };
  }
}

#endif  // XSD_CXX_PARSER_HXX
