/* Copyright (c) 2014 The Chromium Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file. */

/**
 * @fileoverview Caret browsing content script, runs in each frame.
 *
 * The behavior is based on Mozilla's spec whenever possible:
 *   http://www.mozilla.org/access/keyboard/proposal
 *
 * The one exception is that Esc is used to escape out of a form control,
 * rather than their proposed key (which doesn't seem to work in the
 * latest Firefox anyway).
 *
 * Some details about how Chrome selection works, which will help in
 * understanding the code:
 *
 * The Selection object (window.getSelection()) has four components that
 * completely describe the state of the caret or selection:
 *
 * base and anchor: this is the start of the selection, the fixed point.
 * extent and focus: this is the end of the selection, the part that
 *     moves when you hold down shift and press the left or right arrows.
 *
 * When the selection is a cursor, the base, anchor, extent, and focus are
 * all the same.
 *
 * There's only one time when the base and anchor are not the same, or the
 * extent and focus are not the same, and that's when the selection is in
 * an ambiguous state - i.e. it's not clear which edge is the focus and which
 * is the anchor. As an example, if you double-click to select a word, then
 * the behavior is dependent on your next action. If you press Shift+Right,
 * the right edge becomes the focus. But if you press Shift+Left, the left
 * edge becomes the focus.
 *
 * When the selection is in an ambiguous state, the base and extent are set
 * to the position where the mouse clicked, and the anchor and focus are set
 * to the boundaries of the selection.
 *
 * The only way to set the selection and give it direction is to use
 * the non-standard Selection.setBaseAndExtent method. If you try to use
 * Selection.addRange(), the anchor will always be on the left and the focus
 * will always be on the right, making it impossible to manipulate
 * selections that move from right to left.
 *
 * Finally, Chrome will throw an exception if you try to set an invalid
 * selection - a selection where the left and right edges are not the same,
 * but it doesn't span any visible characters. A common example is that
 * there are often many whitespace characters in the DOM that are not
 * visible on the page; trying to select them will fail. Another example is
 * any node that's invisible or not displayed.
 *
 * While there are probably many possible methods to determine what is
 * selectable, this code uses the method of determining if there's a valid
 * bounding box for the range or not - keep moving the cursor forwards until
 * the range from the previous position and candidate next position has a
 * valid bounding box.
 */

/**
 * Return whether a node is focusable. This includes nodes whose tabindex
 * attribute is set to "-1" explicitly - these nodes are not in the tab
 * order, but they should still be focused if the user navigates to them
 * using linear or smart DOM navigation.
 *
 * Note that when the tabIndex property of an Element is -1, that doesn't
 * tell us whether the tabIndex attribute is missing or set to "-1" explicitly,
 * so we have to check the attribute.
 *
 * @param {Object} targetNode The node to check if it's focusable.
 * @return {boolean} True if the node is focusable.
 */
function isFocusable(targetNode) {
  if (!targetNode || typeof(targetNode.tabIndex) != 'number') {
    return false;
  }

  if (targetNode.tabIndex >= 0) {
    return true;
  }

  if (targetNode.hasAttribute &&
      targetNode.hasAttribute('tabindex') &&
      targetNode.getAttribute('tabindex') == '-1') {
    return true;
  }

  return false;
}

/**
 * Determines whether or not a node is or is the descendant of another node.
 *
 * @param {Object} node The node to be checked.
 * @param {Object} ancestor The node to see if it's a descendant of.
 * @return {boolean} True if the node is ancestor or is a descendant of it.
 */
function isDescendantOfNode(node, ancestor) {
  while (node && ancestor) {
    if (node.isSameNode(ancestor)) {
      return true;
    }
    node = node.parentNode;
  }
  return false;
}



/**
 * The class handling the Caret Browsing implementation in the page.
 * Installs a keydown listener that always responds to the F7 key,
 * sets up communication with the background page, and then when caret
 * browsing is enabled, response to various key events to move the caret
 * or selection within the text content of the document. Uses the native
 * Chrome selection wherever possible, but displays its own flashing
 * caret using a DIV because there's no native caret available.
 * @constructor
 */
var CaretBrowsing = function() {};

/**
 * Is caret browsing enabled?
 * @type {boolean}
 */
CaretBrowsing.isEnabled = false;

/**
 * Keep it enabled even when flipped off (for the options page)?
 * @type {boolean}
 */
CaretBrowsing.forceEnabled = false;

/**
 * What to do when the caret appears?
 * @type {string}
 */
CaretBrowsing.onEnable;

/**
 * What to do when the caret jumps?
 * @type {string}
 */
CaretBrowsing.onJump;

/**
 * Is this window / iframe focused? We won't show the caret if not,
 * especially so that carets aren't shown in two iframes of the same
 * tab.
 * @type {boolean}
 */
CaretBrowsing.isWindowFocused = false;

/**
 * Is the caret actually visible? This is true only if isEnabled and
 * isWindowFocused are both true.
 * @type {boolean}
 */
CaretBrowsing.isCaretVisible = false;

/**
 * The actual caret element, an absolute-positioned flashing line.
 * @type {Element}
 */
CaretBrowsing.caretElement;

/**
 * The x-position of the caret, in absolute pixels.
 * @type {number}
 */
CaretBrowsing.caretX = 0;

/**
 * The y-position of the caret, in absolute pixels.
 * @type {number}
 */
CaretBrowsing.caretY = 0;

/**
 * The width of the caret in pixels.
 * @type {number}
 */
CaretBrowsing.caretWidth = 0;

/**
 * The height of the caret in pixels.
 * @type {number}
 */
CaretBrowsing.caretHeight = 0;

/**
 * The foregroundc color.
 * @type {string}
 */
CaretBrowsing.caretForeground = '#000';

/**
 * The backgroundc color.
 * @type {string}
 */
CaretBrowsing.caretBackground = '#fff';

/**
 * Is the selection collapsed, i.e. are the start and end locations
 * the same? If so, our blinking caret image is shown; otherwise
 * the Chrome selection is shown.
 * @type {boolean}
 */
CaretBrowsing.isSelectionCollapsed = false;

/**
 * The id returned by window.setInterval for our blink function, so
 * we can cancel it when caret browsing is disabled.
 * @type {number?}
 */
CaretBrowsing.blinkFunctionId = null;

/**
 * The desired x-coordinate to match when moving the caret up and down.
 * To match the behavior as documented in Mozilla's caret browsing spec
 * (http://www.mozilla.org/access/keyboard/proposal), we keep track of the
 * initial x position when the user starts moving the caret up and down,
 * so that the x position doesn't drift as you move throughout lines, but
 * stays as close as possible to the initial position. This is reset when
 * moving left or right or clicking.
 * @type {number?}
 */
CaretBrowsing.targetX = null;

/**
 * A flag that flips on or off as the caret blinks.
 * @type {boolean}
 */
CaretBrowsing.blinkFlag = true;

/**
 * Whether or not we're on a Mac - affects modifier keys.
 * @type {boolean}
 */
CaretBrowsing.isMac = (navigator.appVersion.indexOf("Mac") != -1);

/**
 * Check if a node is a control that normally allows the user to interact
 * with it using arrow keys. We won't override the arrow keys when such a
 * control has focus, the user must press Escape to do caret browsing outside
 * that control.
 * @param {Node} node A node to check.
 * @return {boolean} True if this node is a control that the user can
 *     interact with using arrow keys.
 */
CaretBrowsing.isControlThatNeedsArrowKeys = function(node) {
  if (!node) {
    return false;
  }

  if (node == document.body || node != document.activeElement) {
    return false;
  }

  if (node.constructor == HTMLSelectElement) {
    return true;
  }

  if (node.constructor == HTMLInputElement) {
    switch (node.type) {
      case 'email':
      case 'number':
      case 'password':
      case 'search':
      case 'text':
      case 'tel':
      case 'url':
      case '':
        return true;  // All of these are text boxes.
      case 'datetime':
      case 'datetime-local':
      case 'date':
      case 'month':
      case 'radio':
      case 'range':
      case 'week':
        return true;  // These are other input elements that use arrows.
    }
  }

  // Handle focusable ARIA controls.
  if (node.getAttribute && isFocusable(node)) {
    var role = node.getAttribute('role');
    switch (role) {
      case 'combobox':
      case 'grid':
      case 'gridcell':
      case 'listbox':
      case 'menu':
      case 'menubar':
      case 'menuitem':
      case 'menuitemcheckbox':
      case 'menuitemradio':
      case 'option':
      case 'radiogroup':
      case 'scrollbar':
      case 'slider':
      case 'spinbutton':
      case 'tab':
      case 'tablist':
      case 'textbox':
      case 'tree':
      case 'treegrid':
      case 'treeitem':
        return true;
    }
  }

  return false;
};

/**
 * If there's no initial selection, set the cursor just before the
 * first text character in the document.
 */
CaretBrowsing.setInitialCursor = function() {
  var sel = window.getSelection();
  if (sel.rangeCount > 0) {
    return;
  }

  var start = new Cursor(document.body, 0, '');
  var end = new Cursor(document.body, 0, '');
  var nodesCrossed = [];
  var result = TraverseUtil.getNextChar(start, end, nodesCrossed, true);
  if (result == null) {
    return;
  }
  CaretBrowsing.setAndValidateSelection(start, start);
};

/**
 * Set focus to a node if it's focusable. If it's an input element,
 * select the text, otherwise it doesn't appear focused to the user.
 * Every other control behaves normally if you just call focus() on it.
 * @param {Node} node The node to focus.
 * @return {boolean} True if the node was focused.
 */
CaretBrowsing.setFocusToNode = function(node) {
  while (node && node != document.body) {
    if (isFocusable(node) && node.constructor != HTMLIFrameElement) {
      node.focus();
      if (node.constructor == HTMLInputElement && node.select) {
        node.select();
      }
      return true;
    }
    node = node.parentNode;
  }

  return false;
};

/**
 * Set focus to the first focusable node in the given list.
 * select the text, otherwise it doesn't appear focused to the user.
 * Every other control behaves normally if you just call focus() on it.
 * @param {Array.<Node>} nodeList An array of nodes to focus.
 * @return {boolean} True if the node was focused.
 */
CaretBrowsing.setFocusToFirstFocusable = function(nodeList) {
  for (var i = 0; i < nodeList.length; i++) {
    if (CaretBrowsing.setFocusToNode(nodeList[i])) {
      return true;
    }
  }
  return false;
};

/**
 * Set the caret element's normal style, i.e. not when animating.
 */
CaretBrowsing.setCaretElementNormalStyle = function() {
  var element = CaretBrowsing.caretElement;
  element.className = 'CaretBrowsing_Caret';
  element.style.opacity = CaretBrowsing.isSelectionCollapsed ? '1.0' : '0.0';
  element.style.left = CaretBrowsing.caretX + 'px';
  element.style.top = CaretBrowsing.caretY + 'px';
  element.style.width = CaretBrowsing.caretWidth + 'px';
  element.style.height = CaretBrowsing.caretHeight + 'px';
  element.style.color = CaretBrowsing.caretForeground;
};

/**
 * Animate the caret element into the normal style.
 */
CaretBrowsing.animateCaretElement = function() {
  var element = CaretBrowsing.caretElement;
  element.style.left = (CaretBrowsing.caretX - 50) + 'px';
  element.style.top = (CaretBrowsing.caretY - 100) + 'px';
  element.style.width = (CaretBrowsing.caretWidth + 100) + 'px';
  element.style.height = (CaretBrowsing.caretHeight + 200) + 'px';
  element.className = 'CaretBrowsing_AnimateCaret';

  // Start the animation. The setTimeout is so that the old values will get
  // applied first, so we can animate to the new values.
  window.setTimeout(function() {
    if (!CaretBrowsing.caretElement) {
      return;
    }
    CaretBrowsing.setCaretElementNormalStyle();
    element.style['-webkit-transition'] = 'all 0.8s ease-in';
    function listener() {
      element.removeEventListener(
          'webkitTransitionEnd', listener, false);
      element.style['-webkit-transition'] = 'none';
    }
    element.addEventListener(
        'webkitTransitionEnd', listener, false);
  }, 0);
};

/**
 * Quick flash and then show the normal caret style.
 */
CaretBrowsing.flashCaretElement = function() {
  var x = CaretBrowsing.caretX - window.pageXOffset;
  var y = CaretBrowsing.caretY - window.pageYOffset;
  var height = CaretBrowsing.caretHeight;

  var vert = document.createElement('div');
  vert.className = 'CaretBrowsing_FlashVert';
  vert.style.left = (x - 6) + 'px';
  vert.style.top = (y - 100) + 'px';
  vert.style.width = '11px';
  vert.style.height = (200) + 'px';
  document.body.appendChild(vert);

  window.setTimeout(function() {
    document.body.removeChild(vert);
    if (CaretBrowsing.caretElement) {
      CaretBrowsing.setCaretElementNormalStyle();
    }
  }, 250);
};

/**
 * Create the caret element. This assumes that caretX, caretY,
 * caretWidth, and caretHeight have all been set. The caret is
 * animated in so the user can find it when it first appears.
 */
CaretBrowsing.createCaretElement = function() {
  var element = document.createElement('div');
  element.className = 'CaretBrowsing_Caret';
  document.body.appendChild(element);
  CaretBrowsing.caretElement = element;

  if (CaretBrowsing.onEnable == 'anim') {
    CaretBrowsing.animateCaretElement();
  } else if (CaretBrowsing.onEnable == 'flash') {
    CaretBrowsing.flashCaretElement();
  } else {
    CaretBrowsing.setCaretElementNormalStyle();
  }
};

/**
 * Recreate the caret element, triggering any intro animation.
 */
CaretBrowsing.recreateCaretElement = function() {
  if (CaretBrowsing.caretElement) {
    window.clearInterval(CaretBrowsing.blinkFunctionId);
    CaretBrowsing.caretElement.parentElement.removeChild(
        CaretBrowsing.caretElement);
    CaretBrowsing.caretElement = null;
    CaretBrowsing.updateIsCaretVisible();
  }
};

/**
 * Get the rectangle for a cursor position. This is tricky because
 * you can't get the bounding rectangle of an empty range, so this function
 * computes the rect by trying a range including one character earlier or
 * later than the cursor position.
 * @param {Cursor} cursor A single cursor position.
 * @return {{left: number, top: number, width: number, height: number}}
 *     The bounding rectangle of the cursor.
 */
CaretBrowsing.getCursorRect = function(cursor) {
  var node = cursor.node;
  var index = cursor.index;
  var rect = {
    left: 0,
    top: 0,
    width: 1,
    height: 0
  };
  if (node.constructor == Text) {
    var left = index;
    var right = index;
    var max = node.data.length;
    var newRange = document.createRange();
    while (left > 0 || right < max) {
      if (left > 0) {
        left--;
        newRange.setStart(node, left);
        newRange.setEnd(node, index);
        var rangeRect = newRange.getBoundingClientRect();
        if (rangeRect && rangeRect.width && rangeRect.height) {
          rect.left = rangeRect.right;
          rect.top = rangeRect.top;
          rect.height = rangeRect.height;
          break;
        }
      }
      if (right < max) {
        right++;
        newRange.setStart(node, index);
        newRange.setEnd(node, right);
        var rangeRect = newRange.getBoundingClientRect();
        if (rangeRect && rangeRect.width && rangeRect.height) {
          rect.left = rangeRect.left;
          rect.top = rangeRect.top;
          rect.height = rangeRect.height;
          break;
        }
      }
    }
  } else {
    rect.height = node.offsetHeight;
    while (node !== null) {
      rect.left += node.offsetLeft;
      rect.top += node.offsetTop;
      node = node.offsetParent;
    }
  }
  rect.left += window.pageXOffset;
  rect.top += window.pageYOffset;
  return rect;
};

/**
 * Compute the new location of the caret or selection and update
 * the element as needed.
 * @param {boolean} scrollToSelection If true, will also scroll the page
 *     to the caret / selection location.
 */
CaretBrowsing.updateCaretOrSelection = function(scrollToSelection) {
  var previousX = CaretBrowsing.caretX;
  var previousY = CaretBrowsing.caretY;

  var sel = window.getSelection();
  if (sel.rangeCount == 0) {
    if (CaretBrowsing.caretElement) {
      CaretBrowsing.isSelectionCollapsed = false;
      CaretBrowsing.caretElement.style.opacity = '0.0';
    }
    return;
  }

  var range = sel.getRangeAt(0);
  if (!range) {
    if (CaretBrowsing.caretElement) {
      CaretBrowsing.isSelectionCollapsed = false;
      CaretBrowsing.caretElement.style.opacity = '0.0';
    }
    return;
  }

  if (CaretBrowsing.isControlThatNeedsArrowKeys(document.activeElement)) {
    var node = document.activeElement;
    CaretBrowsing.caretWidth = node.offsetWidth;
    CaretBrowsing.caretHeight = node.offsetHeight;
    CaretBrowsing.caretX = 0;
    CaretBrowsing.caretY = 0;
    while (node.offsetParent) {
      CaretBrowsing.caretX += node.offsetLeft;
      CaretBrowsing.caretY += node.offsetTop;
      node = node.offsetParent;
    }
    CaretBrowsing.isSelectionCollapsed = false;
  } else if (range.startOffset != range.endOffset ||
             range.startContainer != range.endContainer) {
    var rect = range.getBoundingClientRect();
    if (!rect) {
      return;
    }
    CaretBrowsing.caretX = rect.left + window.pageXOffset;
    CaretBrowsing.caretY = rect.top + window.pageYOffset;
    CaretBrowsing.caretWidth = rect.width;
    CaretBrowsing.caretHeight = rect.height;
    CaretBrowsing.isSelectionCollapsed = false;
  } else {
    var rect = CaretBrowsing.getCursorRect(
        new Cursor(range.startContainer,
                   range.startOffset,
                   TraverseUtil.getNodeText(range.startContainer)));
    CaretBrowsing.caretX = rect.left;
    CaretBrowsing.caretY = rect.top;
    CaretBrowsing.caretWidth = rect.width;
    CaretBrowsing.caretHeight = rect.height;
    CaretBrowsing.isSelectionCollapsed = true;
  }

  if (!CaretBrowsing.caretElement) {
    CaretBrowsing.createCaretElement();
  } else {
    var element = CaretBrowsing.caretElement;
    if (CaretBrowsing.isSelectionCollapsed) {
      element.style.opacity = '1.0';
      element.style.left = CaretBrowsing.caretX + 'px';
      element.style.top = CaretBrowsing.caretY + 'px';
      element.style.width = CaretBrowsing.caretWidth + 'px';
      element.style.height = CaretBrowsing.caretHeight + 'px';
    } else {
      element.style.opacity = '0.0';
    }
  }

  var elem = range.startContainer;
  if (elem.constructor == Text)
    elem = elem.parentElement;
  var style = window.getComputedStyle(elem);
  var bg = axs.utils.getBgColor(style, elem);
  var fg = axs.utils.getFgColor(style, elem, bg);
  CaretBrowsing.caretBackground = axs.utils.colorToString(bg);
  CaretBrowsing.caretForeground = axs.utils.colorToString(fg);

  if (scrollToSelection) {
    // Scroll just to the "focus" position of the selection,
    // the part the user is manipulating.
    var rect = CaretBrowsing.getCursorRect(
        new Cursor(sel.focusNode, sel.focusOffset,
                   TraverseUtil.getNodeText(sel.focusNode)));

    var yscroll = window.pageYOffset;
    var pageHeight = window.innerHeight;
    var caretY = rect.top;
    var caretHeight = Math.min(rect.height, 30);
    if (yscroll + pageHeight < caretY + caretHeight) {
      window.scroll(0, (caretY + caretHeight - pageHeight + 100));
    } else if (caretY < yscroll) {
      window.scroll(0, (caretY - 100));
    }
  }

  if (Math.abs(previousX - CaretBrowsing.caretX) > 500 ||
      Math.abs(previousY - CaretBrowsing.caretY) > 100) {
    if (CaretBrowsing.onJump == 'anim') {
      CaretBrowsing.animateCaretElement();
    } else if (CaretBrowsing.onJump == 'flash') {
      CaretBrowsing.flashCaretElement();
    }
  }
};

/**
 * Return true if the selection directionality is ambiguous, which happens
 * if, for example, the user double-clicks in the middle of a word to select
 * it. In that case, the selection should extend by the right edge if the
 * user presses right, and by the left edge if the user presses left.
 * @param {Selection} sel The selection.
 * @return {boolean} True if the selection directionality is ambiguous.
 */
CaretBrowsing.isAmbiguous = function(sel) {
  return (sel.anchorNode != sel.baseNode ||
          sel.anchorOffset != sel.baseOffset ||
          sel.focusNode != sel.extentNode ||
          sel.focusOffset != sel.extentOffset);
};

/**
 * Create a Cursor from the anchor position of the selection, the
 * part that doesn't normally move.
 * @param {Selection} sel The selection.
 * @return {Cursor} A cursor pointing to the selection's anchor location.
 */
CaretBrowsing.makeAnchorCursor = function(sel) {
  return new Cursor(sel.anchorNode, sel.anchorOffset,
                    TraverseUtil.getNodeText(sel.anchorNode));
};

/**
 * Create a Cursor from the focus position of the selection.
 * @param {Selection} sel The selection.
 * @return {Cursor} A cursor pointing to the selection's focus location.
 */
CaretBrowsing.makeFocusCursor = function(sel) {
  return new Cursor(sel.focusNode, sel.focusOffset,
                    TraverseUtil.getNodeText(sel.focusNode));
};

/**
 * Create a Cursor from the left boundary of the selection - the boundary
 * closer to the start of the document.
 * @param {Selection} sel The selection.
 * @return {Cursor} A cursor pointing to the selection's left boundary.
 */
CaretBrowsing.makeLeftCursor = function(sel) {
  var range = sel.rangeCount == 1 ? sel.getRangeAt(0) : null;
  if (range &&
      range.endContainer == sel.anchorNode &&
      range.endOffset == sel.anchorOffset) {
    return CaretBrowsing.makeFocusCursor(sel);
  } else {
    return CaretBrowsing.makeAnchorCursor(sel);
  }
};

/**
 * Create a Cursor from the right boundary of the selection - the boundary
 * closer to the end of the document.
 * @param {Selection} sel The selection.
 * @return {Cursor} A cursor pointing to the selection's right boundary.
 */
CaretBrowsing.makeRightCursor = function(sel) {
  var range = sel.rangeCount == 1 ? sel.getRangeAt(0) : null;
  if (range &&
      range.endContainer == sel.anchorNode &&
      range.endOffset == sel.anchorOffset) {
    return CaretBrowsing.makeAnchorCursor(sel);
  } else {
    return CaretBrowsing.makeFocusCursor(sel);
  }
};

/**
 * Try to set the window's selection to be between the given start and end
 * cursors, and return whether or not it was successful.
 * @param {Cursor} start The start position.
 * @param {Cursor} end The end position.
 * @return {boolean} True if the selection was successfully set.
 */
CaretBrowsing.setAndValidateSelection = function(start, end) {
  var sel = window.getSelection();
  sel.setBaseAndExtent(start.node, start.index, end.node, end.index);

  if (sel.rangeCount != 1) {
    return false;
  }

  return (sel.anchorNode == start.node &&
          sel.anchorOffset == start.index &&
          sel.focusNode == end.node &&
          sel.focusOffset == end.index);
};

/**
 * Note: the built-in function by the same name is unreliable.
 * @param {Selection} sel The selection.
 * @return {boolean} True if the start and end positions are the same.
 */
CaretBrowsing.isCollapsed = function(sel) {
  return (sel.anchorOffset == sel.focusOffset &&
          sel.anchorNode == sel.focusNode);
};

/**
 * Determines if the modifier key is held down that should cause
 * the cursor to move by word rather than by character.
 * @param {Event} evt A keyboard event.
 * @return {boolean} True if the cursor should move by word.
 */
CaretBrowsing.isMoveByWordEvent = function(evt) {
  if (CaretBrowsing.isMac) {
    return evt.altKey;
  } else {
    return evt.ctrlKey;
  }
};

/**
 * Moves the cursor forwards to the next valid position.
 * @param {Cursor} cursor The current cursor location.
 *     On exit, the cursor will be at the next position.
 * @param {Array.<Node>} nodesCrossed Any HTML nodes crossed between the
 *     initial and final cursor position will be pushed onto this array.
 * @return {?string} The character reached, or null if the bottom of the
 *     document has been reached.
 */
CaretBrowsing.forwards = function(cursor, nodesCrossed) {
  var previousCursor = cursor.clone();
  var result = TraverseUtil.forwardsChar(cursor, nodesCrossed);

  // Work around the fact that TraverseUtil.forwardsChar returns once per
  // char in a block of text, rather than once per possible selection
  // position in a block of text.
  if (result && cursor.node != previousCursor.node && cursor.index > 0) {
    cursor.index = 0;
  }

  return result;
};

/**
 * Moves the cursor backwards to the previous valid position.
 * @param {Cursor} cursor The current cursor location.
 *     On exit, the cursor will be at the previous position.
 * @param {Array.<Node>} nodesCrossed Any HTML nodes crossed between the
 *     initial and final cursor position will be pushed onto this array.
 * @return {?string} The character reached, or null if the top of the
 *     document has been reached.
 */
CaretBrowsing.backwards = function(cursor, nodesCrossed) {
  var previousCursor = cursor.clone();
  var result = TraverseUtil.backwardsChar(cursor, nodesCrossed);

  // Work around the fact that TraverseUtil.backwardsChar returns once per
  // char in a block of text, rather than once per possible selection
  // position in a block of text.
  if (result &&
      cursor.node != previousCursor.node &&
      cursor.index < cursor.text.length) {
    cursor.index = cursor.text.length;
  }

  return result;
};

/**
 * Called when the user presses the right arrow. If there's a selection,
 * moves the cursor to the end of the selection range. If it's a cursor,
 * moves past one character.
 * @param {Event} evt The DOM event.
 * @return {boolean} True if the default action should be performed.
 */
CaretBrowsing.moveRight = function(evt) {
  CaretBrowsing.targetX = null;

  var sel = window.getSelection();
  if (!evt.shiftKey && !CaretBrowsing.isCollapsed(sel)) {
    var right = CaretBrowsing.makeRightCursor(sel);
    CaretBrowsing.setAndValidateSelection(right, right);
    return false;
  }

  var start = CaretBrowsing.isAmbiguous(sel) ?
              CaretBrowsing.makeLeftCursor(sel) :
              CaretBrowsing.makeAnchorCursor(sel);
  var end = CaretBrowsing.isAmbiguous(sel) ?
            CaretBrowsing.makeRightCursor(sel) :
            CaretBrowsing.makeFocusCursor(sel);
  var previousEnd = end.clone();
  var nodesCrossed = [];
  while (true) {
    var result;
    if (CaretBrowsing.isMoveByWordEvent(evt)) {
      result = TraverseUtil.getNextWord(previousEnd, end, nodesCrossed);
    } else {
      previousEnd = end.clone();
      result = CaretBrowsing.forwards(end, nodesCrossed);
    }

    if (result === null) {
      return CaretBrowsing.moveLeft(evt);
    }

    if (CaretBrowsing.setAndValidateSelection(
            evt.shiftKey ? start : end, end)) {
      break;
    }
  }

  if (!evt.shiftKey) {
    nodesCrossed.push(end.node);
    CaretBrowsing.setFocusToFirstFocusable(nodesCrossed);
  }

  return false;
};

/**
 * Called when the user presses the left arrow. If there's a selection,
 * moves the cursor to the start of the selection range. If it's a cursor,
 * moves backwards past one character.
 * @param {Event} evt The DOM event.
 * @return {boolean} True if the default action should be performed.
 */
CaretBrowsing.moveLeft = function(evt) {
  CaretBrowsing.targetX = null;

  var sel = window.getSelection();
  if (!evt.shiftKey && !CaretBrowsing.isCollapsed(sel)) {
    var left = CaretBrowsing.makeLeftCursor(sel);
    CaretBrowsing.setAndValidateSelection(left, left);
    return false;
  }

  var start = CaretBrowsing.isAmbiguous(sel) ?
              CaretBrowsing.makeLeftCursor(sel) :
              CaretBrowsing.makeFocusCursor(sel);
  var end = CaretBrowsing.isAmbiguous(sel) ?
            CaretBrowsing.makeRightCursor(sel) :
            CaretBrowsing.makeAnchorCursor(sel);
  var previousStart = start.clone();
  var nodesCrossed = [];
  while (true) {
    var result;
    if (CaretBrowsing.isMoveByWordEvent(evt)) {
      result = TraverseUtil.getPreviousWord(
          start, previousStart, nodesCrossed);
    } else {
      previousStart = start.clone();
      result = CaretBrowsing.backwards(start, nodesCrossed);
    }

    if (result === null) {
      break;
    }

    if (CaretBrowsing.setAndValidateSelection(
            evt.shiftKey ? end : start, start)) {
      break;
    }
  }

  if (!evt.shiftKey) {
    nodesCrossed.push(start.node);
    CaretBrowsing.setFocusToFirstFocusable(nodesCrossed);
  }

  return false;
};


/**
 * Called when the user presses the down arrow. If there's a selection,
 * moves the cursor to the end of the selection range. If it's a cursor,
 * attempts to move to the equivalent horizontal pixel position in the
 * subsequent line of text. If this is impossible, go to the first character
 * of the next line.
 * @param {Event} evt The DOM event.
 * @return {boolean} True if the default action should be performed.
 */
CaretBrowsing.moveDown = function(evt) {
  var sel = window.getSelection();
  if (!evt.shiftKey && !CaretBrowsing.isCollapsed(sel)) {
    var right = CaretBrowsing.makeRightCursor(sel);
    CaretBrowsing.setAndValidateSelection(right, right);
    return false;
  }

  var start = CaretBrowsing.isAmbiguous(sel) ?
              CaretBrowsing.makeLeftCursor(sel) :
              CaretBrowsing.makeAnchorCursor(sel);
  var end = CaretBrowsing.isAmbiguous(sel) ?
            CaretBrowsing.makeRightCursor(sel) :
            CaretBrowsing.makeFocusCursor(sel);
  var endRect = CaretBrowsing.getCursorRect(end);
  if (CaretBrowsing.targetX === null) {
    CaretBrowsing.targetX = endRect.left;
  }
  var previousEnd = end.clone();
  var leftPos = end.clone();
  var rightPos = end.clone();
  var bestPos = null;
  var bestY = null;
  var bestDelta = null;
  var bestHeight = null;
  var nodesCrossed = [];
  var y = -1;
  while (true) {
    if (null === CaretBrowsing.forwards(rightPos, nodesCrossed)) {
      if (CaretBrowsing.setAndValidateSelection(
            evt.shiftKey ? start : leftPos, leftPos)) {
        break;
      } else {
        return CaretBrowsing.moveLeft(evt);
      }
      break;
    }
    var range = document.createRange();
    range.setStart(leftPos.node, leftPos.index);
    range.setEnd(rightPos.node, rightPos.index);
    var rect = range.getBoundingClientRect();
    if (rect && rect.width < rect.height) {
      y = rect.top + window.pageYOffset;

      // Return the best match so far if we get half a line past the best.
      if (bestY != null && y > bestY + bestHeight / 2) {
        if (CaretBrowsing.setAndValidateSelection(
                evt.shiftKey ? start : bestPos, bestPos)) {
          break;
        } else {
          bestY = null;
        }
      }

      // Stop here if we're an entire line the wrong direction
      // (for example, we reached the top of the next column).
      if (y < endRect.top - endRect.height) {
        if (CaretBrowsing.setAndValidateSelection(
                evt.shiftKey ? start : leftPos, leftPos)) {
          break;
        }
      }

      // Otherwise look to see if this current position is on the
      // next line and better than the previous best match, if any.
      if (y >= endRect.top + endRect.height) {
        var deltaLeft = Math.abs(CaretBrowsing.targetX - rect.left);
        if ((bestDelta == null || deltaLeft < bestDelta) &&
            (leftPos.node != end.node || leftPos.index != end.index)) {
          bestPos = leftPos.clone();
          bestY = y;
          bestDelta = deltaLeft;
          bestHeight = rect.height;
        }
        var deltaRight = Math.abs(CaretBrowsing.targetX - rect.right);
        if (bestDelta == null || deltaRight < bestDelta) {
          bestPos = rightPos.clone();
          bestY = y;
          bestDelta = deltaRight;
          bestHeight = rect.height;
        }

        // Return the best match so far if the deltas are getting worse,
        // not better.
        if (bestDelta != null &&
            deltaLeft > bestDelta &&
            deltaRight > bestDelta) {
          if (CaretBrowsing.setAndValidateSelection(
                  evt.shiftKey ? start : bestPos, bestPos)) {
            break;
          } else {
            bestY = null;
          }
        }
      }
    }
    leftPos = rightPos.clone();
  }

  if (!evt.shiftKey) {
    CaretBrowsing.setFocusToNode(leftPos.node);
  }

  return false;
};

/**
 * Called when the user presses the up arrow. If there's a selection,
 * moves the cursor to the start of the selection range. If it's a cursor,
 * attempts to move to the equivalent horizontal pixel position in the
 * previous line of text. If this is impossible, go to the last character
 * of the previous line.
 * @param {Event} evt The DOM event.
 * @return {boolean} True if the default action should be performed.
 */
CaretBrowsing.moveUp = function(evt) {
  var sel = window.getSelection();
  if (!evt.shiftKey && !CaretBrowsing.isCollapsed(sel)) {
    var left = CaretBrowsing.makeLeftCursor(sel);
    CaretBrowsing.setAndValidateSelection(left, left);
    return false;
  }

  var start = CaretBrowsing.isAmbiguous(sel) ?
              CaretBrowsing.makeLeftCursor(sel) :
              CaretBrowsing.makeFocusCursor(sel);
  var end = CaretBrowsing.isAmbiguous(sel) ?
            CaretBrowsing.makeRightCursor(sel) :
            CaretBrowsing.makeAnchorCursor(sel);
  var startRect = CaretBrowsing.getCursorRect(start);
  if (CaretBrowsing.targetX === null) {
    CaretBrowsing.targetX = startRect.left;
  }
  var previousStart = start.clone();
  var leftPos = start.clone();
  var rightPos = start.clone();
  var bestPos = null;
  var bestY = null;
  var bestDelta = null;
  var bestHeight = null;
  var nodesCrossed = [];
  var y = 999999;
  while (true) {
    if (null === CaretBrowsing.backwards(leftPos, nodesCrossed)) {
      CaretBrowsing.setAndValidateSelection(
          evt.shiftKey ? end : rightPos, rightPos);
      break;
    }
    var range = document.createRange();
    range.setStart(leftPos.node, leftPos.index);
    range.setEnd(rightPos.node, rightPos.index);
    var rect = range.getBoundingClientRect();
    if (rect && rect.width < rect.height) {
      y = rect.top + window.pageYOffset;

      // Return the best match so far if we get half a line past the best.
      if (bestY != null && y < bestY - bestHeight / 2) {
        if (CaretBrowsing.setAndValidateSelection(
                evt.shiftKey ? end : bestPos, bestPos)) {
          break;
        } else {
          bestY = null;
        }
      }

      // Exit if we're an entire line the wrong direction
      // (for example, we reached the bottom of the previous column.)
      if (y > startRect.top + startRect.height) {
        if (CaretBrowsing.setAndValidateSelection(
                evt.shiftKey ? end : rightPos, rightPos)) {
          break;
        }
      }

      // Otherwise look to see if this current position is on the
      // next line and better than the previous best match, if any.
      if (y <= startRect.top - startRect.height) {
        var deltaLeft = Math.abs(CaretBrowsing.targetX - rect.left);
        if (bestDelta == null || deltaLeft < bestDelta) {
          bestPos = leftPos.clone();
          bestY = y;
          bestDelta = deltaLeft;
          bestHeight = rect.height;
        }
        var deltaRight = Math.abs(CaretBrowsing.targetX - rect.right);
        if ((bestDelta == null || deltaRight < bestDelta) &&
            (rightPos.node != start.node || rightPos.index != start.index)) {
          bestPos = rightPos.clone();
          bestY = y;
          bestDelta = deltaRight;
          bestHeight = rect.height;
        }

        // Return the best match so far if the deltas are getting worse,
        // not better.
        if (bestDelta != null &&
            deltaLeft > bestDelta &&
            deltaRight > bestDelta) {
          if (CaretBrowsing.setAndValidateSelection(
                  evt.shiftKey ? end : bestPos, bestPos)) {
            break;
          } else {
            bestY = null;
          }
        }
      }
    }
    rightPos = leftPos.clone();
  }

  if (!evt.shiftKey) {
    CaretBrowsing.setFocusToNode(rightPos.node);
  }

  return false;
};

/**
 * Set the document's selection to surround a control, so that the next
 * arrow key they press will allow them to explore the content before
 * or after a given control.
 * @param {Node} control The control to escape from.
 */
CaretBrowsing.escapeFromControl = function(control) {
  control.blur();

  var start = new Cursor(control, 0, '');
  var previousStart = start.clone();
  var end = new Cursor(control, 0, '');
  var previousEnd = end.clone();

  var nodesCrossed = [];
  while (true) {
    if (null === CaretBrowsing.backwards(start, nodesCrossed)) {
      break;
    }

    var r = document.createRange();
    r.setStart(start.node, start.index);
    r.setEnd(previousStart.node, previousStart.index);
    if (r.getBoundingClientRect()) {
      break;
    }
    previousStart = start.clone();
  }
  while (true) {
    if (null === CaretBrowsing.forwards(end, nodesCrossed)) {
      break;
    }
    if (isDescendantOfNode(end.node, control)) {
      previousEnd = end.clone();
      continue;
    }

    var r = document.createRange();
    r.setStart(previousEnd.node, previousEnd.index);
    r.setEnd(end.node, end.index);
    if (r.getBoundingClientRect()) {
      break;
    }
  }

  if (!isDescendantOfNode(previousStart.node, control)) {
    start = previousStart.clone();
  }

  if (!isDescendantOfNode(previousEnd.node, control)) {
    end = previousEnd.clone();
  }

  CaretBrowsing.setAndValidateSelection(start, end);

  window.setTimeout(function() {
    CaretBrowsing.updateCaretOrSelection(true);
  }, 0);
};

/**
 * Toggle whether caret browsing is enabled or not.
 */
CaretBrowsing.toggle = function() {
  if (CaretBrowsing.forceEnabled) {
    CaretBrowsing.recreateCaretElement();
    return;
  }

  CaretBrowsing.isEnabled = !CaretBrowsing.isEnabled;
  var obj = {};
  obj['enabled'] = CaretBrowsing.isEnabled;
  chrome.storage.sync.set(obj);
  CaretBrowsing.updateIsCaretVisible();
};

/**
 * Event handler, called when a key is pressed.
 * @param {Event} evt The DOM event.
 * @return {boolean} True if the default action should be performed.
 */
CaretBrowsing.onKeyDown = function(evt) {
  if (evt.defaultPrevented) {
    return;
  }

  if (evt.keyCode == 118) {  // F7
    CaretBrowsing.toggle();
  }

  if (!CaretBrowsing.isEnabled) {
    return true;
  }

  if (evt.target && CaretBrowsing.isControlThatNeedsArrowKeys(
      /** @type (Node) */(evt.target))) {
    if (evt.keyCode == 27) {
      CaretBrowsing.escapeFromControl(/** @type {Node} */(evt.target));
      evt.preventDefault();
      evt.stopPropagation();
      return false;
    } else {
      return true;
    }
  }

  // If the current selection doesn't have a range, try to escape out of
  // the current control. If that fails, return so we don't fail whe
  // trying to move the cursor or selection.
  var sel = window.getSelection();
  if (sel.rangeCount == 0) {
    if (document.activeElement) {
      CaretBrowsing.escapeFromControl(document.activeElement);
      sel = window.getSelection();
    }

    if (sel.rangeCount == 0) {
      return true;
    }
  }

  if (CaretBrowsing.caretElement) {
    CaretBrowsing.caretElement.style.visibility = 'visible';
    CaretBrowsing.blinkFlag = true;
  }

  var result = true;
  switch (evt.keyCode) {
    case 37:
      result = CaretBrowsing.moveLeft(evt);
      break;
    case 38:
      result = CaretBrowsing.moveUp(evt);
      break;
    case 39:
      result = CaretBrowsing.moveRight(evt);
      break;
    case 40:
      result = CaretBrowsing.moveDown(evt);
      break;
  }

  if (result == false) {
    evt.preventDefault();
    evt.stopPropagation();
  }

  window.setTimeout(function() {
    CaretBrowsing.updateCaretOrSelection(result == false);
  }, 0);

  return result;
};

/**
 * Event handler, called when the mouse is clicked. Chrome already
 * sets the selection when the mouse is clicked, all we need to do is
 * update our cursor.
 * @param {Event} evt The DOM event.
 * @return {boolean} True if the default action should be performed.
 */
CaretBrowsing.onClick = function(evt) {
  if (!CaretBrowsing.isEnabled) {
    return true;
  }
  window.setTimeout(function() {
    CaretBrowsing.targetX = null;
    CaretBrowsing.updateCaretOrSelection(false);
  }, 0);
  return true;
};

/**
 * Called at a regular interval. Blink the cursor by changing its visibility.
 */
CaretBrowsing.caretBlinkFunction = function() {
  if (CaretBrowsing.caretElement) {
    if (CaretBrowsing.blinkFlag) {
      CaretBrowsing.caretElement.style.backgroundColor =
          CaretBrowsing.caretForeground;
      CaretBrowsing.blinkFlag = false;
    } else {
      CaretBrowsing.caretElement.style.backgroundColor =
          CaretBrowsing.caretBackground;
      CaretBrowsing.blinkFlag = true;
    }
  }
};

/**
 * Update whether or not the caret is visible, based on whether caret browsing
 * is enabled and whether this window / iframe has focus.
 */
CaretBrowsing.updateIsCaretVisible = function() {
  CaretBrowsing.isCaretVisible =
      (CaretBrowsing.isEnabled && CaretBrowsing.isWindowFocused);
  if (CaretBrowsing.isCaretVisible && !CaretBrowsing.caretElement) {
    CaretBrowsing.setInitialCursor();
    CaretBrowsing.updateCaretOrSelection(true);
    if (CaretBrowsing.caretElement) {
      CaretBrowsing.blinkFunctionId = window.setInterval(
          CaretBrowsing.caretBlinkFunction, 500);
    }
  } else if (!CaretBrowsing.isCaretVisible &&
             CaretBrowsing.caretElement) {
    window.clearInterval(CaretBrowsing.blinkFunctionId);
    if (CaretBrowsing.caretElement) {
      CaretBrowsing.isSelectionCollapsed = false;
      CaretBrowsing.caretElement.parentElement.removeChild(
          CaretBrowsing.caretElement);
      CaretBrowsing.caretElement = null;
    }
  }
};

/**
 * Called when the prefs get updated.
 */
CaretBrowsing.onPrefsUpdated = function() {
  chrome.storage.sync.get(null, function(result) {
    if (!CaretBrowsing.forceEnabled) {
      CaretBrowsing.isEnabled = result['enabled'];
    }
    CaretBrowsing.onEnable = result['onenable'];
    CaretBrowsing.onJump = result['onjump'];
    CaretBrowsing.recreateCaretElement();
  });
};

/**
 * Called when this window / iframe gains focus.
 */
CaretBrowsing.onWindowFocus = function() {
  CaretBrowsing.isWindowFocused = true;
  CaretBrowsing.updateIsCaretVisible();
};

/**
 * Called when this window / iframe loses focus.
 */
CaretBrowsing.onWindowBlur = function() {
  CaretBrowsing.isWindowFocused = false;
  CaretBrowsing.updateIsCaretVisible();
};

/**
 * Initializes caret browsing by adding event listeners and extension
 * message listeners.
 */
CaretBrowsing.init = function() {
  CaretBrowsing.isWindowFocused = document.hasFocus();

  document.addEventListener('keydown', CaretBrowsing.onKeyDown, false);
  document.addEventListener('click', CaretBrowsing.onClick, false);
  window.addEventListener('focus', CaretBrowsing.onWindowFocus, false);
  window.addEventListener('blur', CaretBrowsing.onWindowBlur, false);
};

window.setTimeout(function() {

  // Make sure the script only loads once.
  if (!window['caretBrowsingLoaded']) {
    window['caretBrowsingLoaded'] = true;
    CaretBrowsing.init();

    if (document.body.getAttribute('caretbrowsing') == 'on') {
      CaretBrowsing.forceEnabled = true;
      CaretBrowsing.isEnabled = true;
      CaretBrowsing.updateIsCaretVisible();
    }

    chrome.storage.onChanged.addListener(function() {
      CaretBrowsing.onPrefsUpdated();
    });
    CaretBrowsing.onPrefsUpdated();
  }

}, 0);
