#include "serializer.h"
#include <iostream>
#include "classes/membertype.h"

using namespace aka2;

serializer::serializer(int tab) {
  for (int index = 0; index < tab; ++index)
    indent_str_ += ' ';
}

void serializer::serialize(const document &doc, std::ostream &ostm) {
  serialize_internal(doc.get_root(), doc.get_name(), 
		     doc.get_op(), ostm);
}


void serializer::new_line(std::ostream &ostm) {
  ostm << std::endl;
  for (int i = indent_; i != 0; --i)
    ostm << indent_str_;
}

bool serializer::is_sequence_empty(const void *e, const member_types &mtypes) {

  for (member_types::const_iterator it = mtypes.begin();
       it != mtypes.end(); ++it) {
    if (!is_member_empty(e, *it))
      return false;
  }
  return true;
}


bool serializer::is_all_empty(const void *e, const member_map &mmap) {
  for (member_map::const_iterator it = mmap.begin();
       it != mmap.end(); ++it) {
    if (!is_member_empty(e, it->second))
      return false;
  }
  return true;
}

bool serializer::is_member_empty(const void *e, const member_type &mtype) {

  const_memberpair mpair = mtype.get_member(e);

  switch (mtype.get_schematype()) {
    case simpletype_id:
    case simplecontent_id:
      return false;
    case array_id: {
      const array_op &aop = static_cast<const array_op&>(mpair.op_);
      if (aop.size(mpair.e_) != 0)
	return false;
      break;
    }
    case sequence_id: {
      const sequence_op &sop = static_cast<const sequence_op&>(mpair.op_);
      if (!is_sequence_empty(mpair.e_, sop.get_member_types()))
	return false;
      break;
    }
    case choice_id: {
      const choice_op &cop = static_cast<const choice_op&>(mpair.op_);
      if (cop.size(mpair.e_) != 0)
	return false;
      break;
    }
    case all_id: {
      const all_op &aop = static_cast<const all_op&>(mpair.op_);
      if (!is_all_empty(mpair.e_, aop.get_member_map()))
	return false;
      break;
    }
    case ptrmember_id: {
      const ptrmember_op &pop = static_cast<const ptrmember_op&>(mpair.op_);
      if (!pop.is_null(mpair.e_))
	return false;
      break;
    }
    default:
      assert(!"Must not reach here.");
  }
  return true;
}
