#include "qname.h"
#include <cassert>
#include "namespace_statics.h"


using namespace aka2;

void qname::validate_name() const {
  if (name_.find_first_of(':') != std::string::npos)
    throw error("Qualified name has ':' in it's name field.", __FILE__, __LINE__);
}

void qname::set(const std::string &uri, const std::string &name) {
  uri_id_ = namespaces_.get_namespace_id(uri);
  if (uri_id_ == unregistered_token)
    uri_id_ = any_namespaces_.get_namespace_id(uri);
  name_ = name;
  validate_name();
}

void qname::set(const id_type uri_id, const std::string &name) {
  uri_id_ = uri_id;
  name_ = name;
  validate_name();
}

void qname::set(const std::string &rawname, const prefix_map &pfs) {
  std::string::size_type pos = rawname.find_first_of(':');

  if (pos == std::string::npos) { // local, not qualified.
    uri_id_ = empty_token;
    name_ = rawname;
  }
  else {
    std::string prefix = rawname.substr(0, pos);
    uri_id_ = pfs.get_prefix_id(prefix);
    if (uri_id_ == unregistered_token)
      throw error("namespace prefix(\"" + prefix + "\") is not registered.",
		  __FILE__, __LINE__);
    name_ = rawname.substr(pos + 1, rawname.length() - pos);
  }
  validate_name();
}

void qname::set(const std::string &rawname) {
  set(rawname, pfs_);
}


std::string qname::qualified(const prefix_map &pfs) const{
  assert(uri_id_ != unregistered_token);

  if (is_qualified()) {
    const std::string &prefix = pfs.get_prefix(uri_id_);
    prefix_cache_ = prefix.c_str();
    std::string qualified = prefix + ':' + name_;
    return qualified;
  }
  else
    return name_;
}

std::string qname::qualified() const{
  return qualified(pfs_);
}

std::string &qname::local() {
  return name_;
}

const std::string &qname::local() const {
  return name_;
}

const std::string &qname::prefix(const prefix_map &pfs) const {
  return pfs.get_prefix(uri_id_);
}

const std::string &qname::prefix() const {
  return pfs_.get_prefix(uri_id_);
}

bool qname::empty() const {
  return (uri_id_ == empty_token) && name_.empty();
}
