'use strict';
var DOMException = require('./DOMException');
var ERR = DOMException;
var isApiWritable = require('./config').isApiWritable;

exports.NAMESPACE = {
  HTML: 'http://www.w3.org/1999/xhtml',
  XML: 'http://www.w3.org/XML/1998/namespace',
  XMLNS: 'http://www.w3.org/2000/xmlns/',
  MATHML: 'http://www.w3.org/1998/Math/MathML',
  SVG: 'http://www.w3.org/2000/svg',
  XLINK: 'http://www.w3.org/1999/xlink',
};

//
// Shortcut functions for throwing errors of various types.
//
exports.IndexSizeError = function () {
  throw new DOMException(ERR.INDEX_SIZE_ERR);
};
exports.HierarchyRequestError = function () {
  throw new DOMException(ERR.HIERARCHY_REQUEST_ERR);
};
exports.WrongDocumentError = function () {
  throw new DOMException(ERR.WRONG_DOCUMENT_ERR);
};
exports.InvalidCharacterError = function () {
  throw new DOMException(ERR.INVALID_CHARACTER_ERR);
};
exports.NoModificationAllowedError = function () {
  throw new DOMException(ERR.NO_MODIFICATION_ALLOWED_ERR);
};
exports.NotFoundError = function () {
  throw new DOMException(ERR.NOT_FOUND_ERR);
};
exports.NotSupportedError = function () {
  throw new DOMException(ERR.NOT_SUPPORTED_ERR);
};
exports.InvalidStateError = function () {
  throw new DOMException(ERR.INVALID_STATE_ERR);
};
exports.SyntaxError = function () {
  throw new DOMException(ERR.SYNTAX_ERR);
};
exports.InvalidModificationError = function () {
  throw new DOMException(ERR.INVALID_MODIFICATION_ERR);
};
exports.NamespaceError = function () {
  throw new DOMException(ERR.NAMESPACE_ERR);
};
exports.InvalidAccessError = function () {
  throw new DOMException(ERR.INVALID_ACCESS_ERR);
};
exports.TypeMismatchError = function () {
  throw new DOMException(ERR.TYPE_MISMATCH_ERR);
};
exports.SecurityError = function () {
  throw new DOMException(ERR.SECURITY_ERR);
};
exports.NetworkError = function () {
  throw new DOMException(ERR.NETWORK_ERR);
};
exports.AbortError = function () {
  throw new DOMException(ERR.ABORT_ERR);
};
exports.UrlMismatchError = function () {
  throw new DOMException(ERR.URL_MISMATCH_ERR);
};
exports.QuotaExceededError = function () {
  throw new DOMException(ERR.QUOTA_EXCEEDED_ERR);
};
exports.TimeoutError = function () {
  throw new DOMException(ERR.TIMEOUT_ERR);
};
exports.InvalidNodeTypeError = function () {
  throw new DOMException(ERR.INVALID_NODE_TYPE_ERR);
};
exports.DataCloneError = function () {
  throw new DOMException(ERR.DATA_CLONE_ERR);
};

exports.nyi = function () {
  throw new Error('NotYetImplemented');
};

exports.shouldOverride = function () {
  throw new Error('Abstract function; should be overriding in subclass.');
};

exports.assert = function (expr, msg) {
  if (!expr) {
    throw new Error('Assertion failed: ' + (msg || '') + '\n' + new Error().stack);
  }
};

exports.expose = function (src, c) {
  for (var n in src) {
    Object.defineProperty(c.prototype, n, { value: src[n], writable: isApiWritable });
  }
};

exports.merge = function (a, b) {
  for (var n in b) {
    a[n] = b[n];
  }
};

exports.escapeText = function (str) {
  return str;
};

// Compare two nodes based on their document order. This function is intended
// to be passed to sort(). Assumes that the array being sorted does not
// contain duplicates.  And that all nodes are connected and comparable.
// Clever code by ppk via jeresig.
exports.documentOrder = function (n, m) {
  /* jshint bitwise: false */
  return 3 - (n.compareDocumentPosition(m) & 6);
};

exports.toASCIILowerCase = function (s) {
  return s.replace(/[A-Z]+/g, function (c) {
    return c.toLowerCase();
  });
};

exports.toASCIIUpperCase = function (s) {
  return s.replace(/[a-z]+/g, function (c) {
    return c.toUpperCase();
  });
};
