/* -*- c++ -*- */
#ifndef TYPE_REGISTORY_H__
#define TYPE_REGISTORY_H__

#include <map>
#include <akaxiso/akaxiso.h>
#include <set>

namespace osixaka {
  extern aka::prefix_map cppattrs_;

  class cppname : public aka::qname {
  public:
    cppname(){}
    explicit cppname(const aka::qname &name);
    cppname(const std::string &rawname) { set(rawname); }
    void set(const std::string &uri, const std::string &name);
    void set(const std::string &rawname);
    std::string qualified() const;
  };

  typedef std::set<std::string> namespaces;

  class resolver {
  public:
    bool exists(const aka::qname &name) const;
    void insert(const aka::qname &name, const aka::qname &type);
    const aka::qname resolve(const aka::qname &name) const;
  protected:
    typedef std::map<aka::qname, aka::qname, aka::qname_less> name_pairs;
    name_pairs pairs_;
  };


  class cpp_resolver : public resolver {
  public:
    void insert(const aka::qname &name, const cppname &type);
    const cppname resolve(const aka::qname &name) const;
  };

  class simpleType_resolver : public cpp_resolver {
  public:
    void initialize();
  };

  class array_resolver : public cpp_resolver {
  public:
    void initialize();
  };

  extern namespaces namespaces_;
  extern resolver elements_;

  extern simpleType_resolver builtinTypes_;
  extern cpp_resolver complexTypes_;
  extern array_resolver arrays_;
  bool type_exists(const aka::qname &type);

  cppname get_cpptype(const aka::qname &xmltype);
  std::string get_leaf_name(const aka::qname &xmltype);
  class contents;
}

std::ostream &operator<<(std::ostream &ostm, const osixaka::cppname &name);


#endif
