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

/** @file content_model.h */

#include <akaxiso/configuration.h>
#include <akaxiso/classes/simpletype.h>
#include <akaxiso/classes/builtin.h>
#include <akaxiso/classes/attribute.h>
#include <akaxiso/classes/array.h>
#include <akaxiso/classes/sequence.h>
#include <akaxiso/classes/choice.h>
#include <akaxiso/classes/all.h>
#include <akaxiso/classes/simplecontent.h>
#include <akaxiso/classes/document.h>
#include <akaxiso/classes/any.h>

namespace aka2 {

  inline void xmlns(const std::string &prefix, const std::string &uri) {
    aka2::namespaces().register_namespace_uri(uri); 
    aka2::system_global_attributes().associate_namespace_prefix(prefix, uri); 
  }

  template<class L>
  inline void doctype(const std::string &name, const L &, 
          const occurrence &occurs = occurrence()) {
    L::initialize();
    system_document_factory().register_document_type(name, L::dispatcher_, occurs);
  }


  bool element_equals(const void *lhs, const void *rhs, const element_op& op);
  bool element_construct(const void *e, const element_op& op);
  bool element_destruct(const void *e, const element_op& op);
  void element_copy(void *dest, const void *src, const element_op& op);

  template<class T, class L>
  inline bool equals(const T &lhs, const T &rhs, const L &) {
    return element_equals(&lhs, &rhs, L::dispatcher_);
  }

  template<class T>
  inline bool equals(const T &lhs, const T &rhs) {
    return element_equals(&lhs, &rhs, xiso::leaf<T>::dispatcher_);
  }

  template<class T, class L>
  inline void construct_element(T &e, const L &) {
    element_construct(&e, L::dispatcher_);
  }
  template<class T>
  inline void construct_element(T &e) {
    element_construct(&e, xiso::leaf<T>::dispatcher_);
  }

  template<class T, class L>
  inline void destruct_element(T &e, const L &) {
    element_destruct(&e, L::dispatcher_);
  }

  template<class T>
  inline void destruct_element(T &e) {
    element_destruct(&e, xiso::leaf<T>::dispatcher_);
  }

  template<class T, class L>
  inline void copy_element(T &dest, const T &src, const L &) {
    element_copy(&dest, &src, L::dispatcher_);
  }

  template<class T>
  inline void copy_element(T &dest, const T &src) {
    element_copy(&dest, &src, xiso::leaf<T>::dispatcher_);
  }

  template<class T, class L>
  inline T* replicate_element(const T &src, const L &) {
    T* t = new T;
    element_copy(t, &src, L::dispatcher_);
    return t;
  }

  template<class T>
  inline T* replicate_element(const T &src) {
    T* t = new T;
    element_copy(t, &src, xiso::leaf<T>::dispatcher_);
    return t;
  }

} // namespace aka2

/**
 * @namespace aka2
 * @brief     Adaptable tookKit for Abstracted data model (version 2).
*/

/**
 * @namespace xiso
 * @brief     XML type-Infomation for serializable objects.
*/

#endif /* AKAXISO_CONTENT_MODEL_H__ */
