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

#include <akaxiso/classes/qname.h>
#include <akaxiso/classes/occurrence.h>
#include <akaxiso/classes/node_ptr.h>
#include <map>

namespace aka2 {

  struct element_op;
  struct itemtype : public element_props {
    itemtype() {}
    itemtype(element_op &op) 
      : element_props(op){ }
    bool equals(const void *lhs, const void *rhs) const;
    bool is_element() const { return name_.local()[0] != '&'; }
  };

  typedef std::map<qname, itemtype, qname_less> itemtypes;

  class item {
  public:
    item() : props_(0) {}
    item(void *e, const element_props &props)
      : nodeptr_(node(e, props.op())), props_(&props) {  }
    item(const item &i) 
      : nodeptr_(i.nodeptr_), props_(i.props_) { }
    ~item(){}

    const item& operator=(const item& rhs);
    const qname &get_name() const { return props_->get_name(); }
    node get_node() { return nodeptr_.get_node(); }
    const_node get_node() const { return nodeptr_.get_node(); }
    bool is_element() const { return props_->get_name().local()[0] != '&'; }
    const element_props &get_props() const { return *props_; }
  protected:
    void assign(const item &rhs);
    node_ptr nodeptr_;
    const element_props *props_;
  };


  bool item_of(const aka2::item &i, const std::string &tagname);
  
  template<class T>
  T& item_cast(aka2::item &i) {
    node nd = i.get_node();
    return *static_cast<T*>(nd.ptr());
  } 
  
  template<class T>
  const T& item_cast(const aka2::item &i) {
    const_node cnd = i.get_node();
    return *static_cast<const T*>(cnd.ptr());
  } 

}




#endif
