#include "destruct.h"
#include "membertype.h"

using namespace aka2;


void aka2::element_destruct(void *e, const element_op& op) {
  switch (op.get_schematype()) {
  case sequence_id:
    sequence_destruct(e, static_cast<const sequence_op&>(op));
    break; 
  case all_id:
    all_destruct(e, static_cast<const all_op&>(op));
    break;
  case simplecontent_id: 
    simplecontent_destruct(e, static_cast<const simplecontent_op&>(op));
    break;
  case ptrmember_id:
    ptrmember_destruct(e, static_cast<const ptrmember_op&>(op));
    break;
  case simpletype_id:
  case choice_id:
  case array_id:
  default:
    ;
  }
}

void aka2::member_destruct(void *e, const named_member &mtype) {
  memberpair mpair = mtype.get_member(e);
  element_destruct(mpair.e_, mpair.op_);
}

void aka2::item_destruct(void *e, const itemtype &itype) {
  element_destruct(e, itype.get_op());
}


void aka2::attributes_destruct(void *e, const attribute_types *attrtypes) {
  if (attrtypes == 0)
    return;
  
  for (attribute_types::const_iterator it = attrtypes->begin();
       it != attrtypes->end(); ++it) {
    member_destruct(e, it->second);
  }
}

void aka2::sequence_destruct(void *e, const sequence_op &sop) {
  attributes_destruct(e, sop.get_attribute_types());
  const member_types &mtypes = sop.get_member_types();
  for (member_types::const_iterator it = mtypes.begin(); it != mtypes.end(); ++it)
    member_destruct(e, *it);
}


void aka2::all_destruct(void *e, const all_op &aop) {

  attributes_destruct(e, aop.get_attribute_types());
  const member_map &mmap = aop.get_member_map();
  for (member_map::const_iterator it = mmap.begin(); it != mmap.end(); ++it)
    member_destruct(e, it->second);

}


void aka2::simplecontent_destruct(void *e, const simplecontent_op &sop) {
  attributes_destruct(e, sop.get_attribute_types());
}


void aka2::ptrmember_destruct(void *e, const ptrmember_op &pop) {
  if (!pop.is_null(e))
    pop.destroy_member(e);
}
