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

#include <akaxiso/classes/item.h>
#include <sstream> /* {g++2.96} */

namespace aka2 {

  struct member_types;
  struct member_map;
  class member_type;
  class named_member;


  /** marshalling text/value.  */
  struct value_op {
    virtual ~value_op() {} 
    virtual void write_text(const void* elm, 
                            std::ostream &ostm,
                            const global_attributes &gattrs) const = 0;
    virtual void read_text(void* elm, std::istringstream &istm, 
                           const global_attributes &gattrs) const = 0;
  };


  struct member_types_getter {
    virtual ~member_types_getter() {}
    virtual const member_types &get_member_types() const = 0;
  };

  struct member_map_getter {
    virtual ~member_map_getter() {}
    virtual const member_map &get_member_map() const = 0;
  };


  /** Traits for SchemaTypes */
  struct simpletype_op : public element_op,
                         public value_op {
    virtual ~simpletype_op() {}
  };

  struct ptrmember_op : public element_op {
    virtual ~ptrmember_op() {}

    virtual void set_null(void *elm) const = 0; 
    virtual void *create_member(void *elm) const = 0;
    virtual void destroy_member(void *elm) const = 0;
    virtual bool is_null(const void *elm) const = 0;

    virtual void *dereference(void *elm) const = 0;
    virtual const void *dereference(const void *elm) const = 0;
    virtual const element_op& get_value_op() const = 0;
  };

  struct simplecontent_op : public element_op {
    virtual ~simplecontent_op() {}
    virtual const member_type& get_valuetype() const = 0;
  };


  struct sequence_op : public element_op, public member_types_getter {
    virtual ~sequence_op() {}
  };

  
  struct all_op : public element_op, public member_map_getter {};


  class item_iterator {
  public:
    virtual ~item_iterator(){}
    virtual bool has_next() const = 0;
    virtual const item *next() = 0;
  };

  struct choice_op : public element_op {
    virtual ~choice_op(){}
    virtual const itemtypes &get_itemtypes() const = 0;
    virtual size_t size(const void *container) const = 0;
    virtual void push(void *container, item &item) const = 0;
    virtual item_iterator* get_iterator(const void *container) const = 0;

    bool empty(const void *container) const {
      return size(container) == 0;
    }
  };


  class array_iterator {
  public:
    virtual ~array_iterator() {}
    virtual bool has_next() const = 0;
    virtual const void *next() = 0;
  };

  struct array_op : public element_op {
    virtual ~array_op(){}
    virtual const element_op& get_item_op() const = 0;
    virtual size_t size(const void *container) const = 0;
    virtual void push(void *container, void *element) const = 0;
    virtual array_iterator* get_iterator(const void *container) const = 0;
    bool empty(const void *container) const {
      return size(container) == 0;
    }
  };

} // namespace aka2

#endif /* AKAXISO_TRAITS_H__ */
