#include "any_array_handler.h"
#include "../classes/any_op.h"

using namespace aka2;


any_array_handler::any_array_handler(const qname &tagname, any_array &anys, 
				     int depth, const element_props &props,
				     parser_context &context)  
  : handler(context, depth, tagname) , anys_(anys), occ_(props.get_occurrence()), props_(props), any_(0) {
}

any_array_handler::~any_array_handler() {
  abort();
}

parse_result any_array_handler::query_element(const qname &tagname, const attribute_values &attrs){

  if (!props_.is_element()) {
    bool res = seek_forward(tagname, attrs); // hit found, then return true.
    if (res) {
      if (occ_.in_range(anys_.size()))
	return skip;
      else {
	context_.report_wrong_occurrence(occ_, anys_.size(), __FILE__, __LINE__);
	return error;
      }
    }
  }
  else {
    if (tagname != props_.get_name())
      return occ_.in_range(anys_.size()) ? skip : error;
  }

  any_ = new any();
  create_any_handler(tagname, *any_, depth_ + 1);
  return ok;
}


parse_result any_array_handler::query_next(const qname &tagname, const attribute_values &attrs){
  assert(!"Must not be called.");
  return ok;
}


parse_result any_array_handler::end_element(const qname &tagname){
  if (occ_.in_range(anys_.size()))
    return ok;
  context_.report_wrong_occurrence(occ_, anys_.size(), __FILE__, __LINE__);
  return error;
}


bool any_array_handler::parse_entity(const std::string &entity) {
  return true;
}

node any_array_handler::get_node() {
  return node(&anys_, aka2::any_array_op::dispatcher_);
}

void any_array_handler::receive_child(const node &child) {
  anys_.push_back(*any_);
  delete any_;
  any_ = 0;
}

bool any_array_handler::can_skip() {
  return occ_.in_range(anys_.size());
}

void any_array_handler::abort() {
  if (any_ != 0) {
    delete any_;
    any_ = 0;
  }
}
