/* -*- 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/builtin_xiso.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>
#include <akaxiso/classes/preconditions.h>

namespace aka2 {

  /** ur-type document */
  inline void doctype(const std::string &name) {
    system_document_factory().register_document_type(name, any_op::dispatcher_);
  }

  /** Ordinally document */
  template<class L>
  inline void doctype(const std::string &name, const L &) {
    L::initialize();
    system_document_factory().register_document_type(name, L::dispatcher_, L::occ_);
  }

  /** Fixed, default type document */
  template<class L>
  inline void doctype(const std::string &name, const L &, const std::string &defval) {
    system_document_factory().register_document_type(name, L::dispatcher_, 
						     L::occ_,
						     defval);
  }

  bool element_equals(const void *lhs, const void *rhs, const element_op& op);
  void element_construct(const node &nd);

  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(node(&e, L::dispatcher_));
  }
  template<class T>
  inline void construct_element(T &e) {
    element_construct(node(&e, xiso::leaf<T>::dispatcher_));
  }

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

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

  template<class T, class L>
  inline T* replicate_element(const T &src, const L &) {
    void *ret = L::dispatcher_.replicate(&src);
    return static_cast<T*>(ret);
  }

  template<class T>
  inline T* replicate_element(const T &src) {
    void *ret = xiso::leaf<T>::dispatcher_.replicate(&src);
    return static_cast<T*>(ret);
  }

} // 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__ */
