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

#include <akaxiso/classes/item.h>
#include <akaxiso/classes/member.h>
#include <akaxiso/classes/occurence.h>

#include <vector>

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;
    }
  };

}

#endif
