"use strict";
var defineGetter = require("../utils").defineGetter;

module.exports = function (core) {
  var DOCUMENT_POSITION_DISCONNECTED = core.Node.DOCUMENT_POSITION_DISCONNECTED;
  var DOCUMENT_POSITION_PRECEDING = core.Node.DOCUMENT_POSITION_PRECEDING;
  var DOCUMENT_POSITION_FOLLOWING = core.Node.DOCUMENT_POSITION_FOLLOWING;
  var DOCUMENT_POSITION_CONTAINS = core.Node.DOCUMENT_POSITION_CONTAINS;
  var DOCUMENT_POSITION_CONTAINED_BY = core.Node.DOCUMENT_POSITION_CONTAINED_BY;
  var DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = core.Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;

  /**
   * Return true if node is of a type obsoleted by the WHATWG living standard
   * @param  {Node}  node
   * @return {Boolean}
   */
  function isObsoleteNodeType(node) {
    return node.nodeType === core.Node.ENTITY_NODE ||
      node.nodeType === core.Node.ENTITY_REFERENCE_NODE ||
      node.nodeType === core.Node.NOTATION_NODE ||
      node.nodeType === core.Node.CDATA_SECTION_NODE;
  }

  /**
   * Return the parent node of node, whatever its nodeType is
   * @param  {Node} node
   * @return {Node or null}
   */
  function getNodeParent(node) {

    if(!node) {
      return node;
    }

    switch (node.nodeType) {

      case core.Node.DOCUMENT_NODE:
      case core.Node.DOCUMENT_FRAGMENT_NODE:
        return null;

      case core.Node.COMMENT_NODE:
      case core.Node.DOCUMENT_TYPE_NODE:
      case core.Node.ELEMENT_NODE:
      case core.Node.PROCESSING_INSTRUCTION_NODE:
      case core.Node.TEXT_NODE:
        return node.parentNode;

      case core.Node.ATTRIBUTE_NODE:

        return node._parentNode;

      default:
        throw new Error("Unknown node type:" + node.nodeType);
    }
  }

  /**
   * Walk up the node tree and return the nodes root node
   * @param  {Node} node
   * @return {Node}
   */
  function findNodeRoot(node) {
    if (!getNodeParent(node)) {
      return node;
    }

    return findNodeRoot(getNodeParent(node));
  }

  /**
   * Walk up the node tree returning true if otherNode is an ancestor of node
   * @param  {Node}  node
   * @param  {Node}  otherNode
   * @return {Boolean}
   */
  function isAncestor(node, otherNode) {
    var parentNode = node.nodeType === node.ATTRIBUTE_NODE ? node._parentNode : node.parentNode;

    if (!parentNode) {
      return false;
    }

    if(parentNode === otherNode) {
      return true;
    }

    return isAncestor(parentNode, otherNode);
  }

  /**
   * Traverse the node tree starting at current. Return DOCUMENT_POSITION_FOLLOWING if otherNode follows node. Return
   * DOCUMENT_POSITION_PRECEDING if otherNode precedes node
   * @param  {Node} current
   * @param  {Node} node
   * @param  {Node} otherNode
   * @return {Number}
   */
  function followingOrPreceding(current, node, otherNode) {
    if (current === node) {
      return core.Node.DOCUMENT_POSITION_FOLLOWING;
    }

    if (current === otherNode) {
      return core.Node.DOCUMENT_POSITION_PRECEDING;
    }

    var i = 0, len = current._childNodes.length, child, result;

    for(; i < len; i += 1) {

      child = current._childNodes[i];

      if((result = followingOrPreceding(child, node, otherNode)) !== 0) {
        return result;
      }
    }

    return 0;
  }

  /**
   * Returns a bitmask Number composed of DOCUMENT_POSITION constants based upon the rules defined in
   * http://dom.spec.whatwg.org/#dom-node-comparedocumentposition
   * @param  {Node} other
   * @return {Number}
   */
  core.Node.prototype.compareDocumentPosition = function compareDocumentPosition (other) {
    // Let reference be the context object.
    var reference = this;

    if(!(other instanceof core.Node)) {
      throw Error("Comparing position against non-Node values is not allowed");
    }

    if (isObsoleteNodeType(reference) || isObsoleteNodeType(other)) {
      throw new Error("Obsolete node type");
    }

    // If other and reference are the same object, return zero.
    if(reference.isSameNode(other)) {
      return 0;
    }

    // If other and reference are not in the same tree, return the result of adding DOCUMENT_POSITION_DISCONNECTED,
    // DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC, and either DOCUMENT_POSITION_PRECEDING or DOCUMENT_POSITION_FOLLOWING,
    // with the constraint that this is to be consistent, together.
    if(findNodeRoot(reference) !== findNodeRoot(other)) {
      return DOCUMENT_POSITION_DISCONNECTED + DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC + DOCUMENT_POSITION_FOLLOWING;
    }

    // If other is an ancestor of reference, return the result of adding DOCUMENT_POSITION_CONTAINS to
    // DOCUMENT_POSITION_PRECEDING.
    if(isAncestor(reference, other)) {
      return DOCUMENT_POSITION_CONTAINS + DOCUMENT_POSITION_PRECEDING;
    }

    // If other is a descendant of reference, return the result of adding DOCUMENT_POSITION_CONTAINED_BY to
    // DOCUMENT_POSITION_FOLLOWING.
    if(isAncestor(other, reference)) {
      return DOCUMENT_POSITION_CONTAINED_BY + DOCUMENT_POSITION_FOLLOWING;
    }

    // If other is preceding reference return DOCUMENT_POSITION_PRECEDING, otherwise return DOCUMENT_POSITION_FOLLOWING
    return followingOrPreceding(findNodeRoot(reference), reference, other);
  };

  /**
   * The contains(other) method returns true if other is an inclusive descendant of the context object,
   * and false otherwise (including when other is null).
   * @param  {[Node]} other [the node to test]
   * @return {[boolean]}      [whether other is an inclusive descendant of this]
   */
  core.Node.prototype.contains = function (other) {
    return other instanceof core.Node &&
    (this.isSameNode(other) || !!(this.compareDocumentPosition(other) & DOCUMENT_POSITION_CONTAINED_BY));
  };

  // http://dom.spec.whatwg.org/#dom-node-parentelement
  defineGetter(core.Node.prototype, "parentElement", function () {
    return this._parentNode !== null && this._parentNode.nodeType === core.Node.ELEMENT_NODE ? this._parentNode : null;
  });
};
