/*globals YAHOO */

/*jslint white: true, onevar: true, browser: true, on: true, undef: true,
         eqeqeq: true, plusplus: true, bitwise: true, regexp: true,
         newcap: true, immed: true, indent: 2, nomen: false */

function getCaretPosition(el) {
  var positionStart, positionEnd, range;
  if (document.selection) {
    // IE specific code because they don't have a nice way to get
    // selectionStart and selectionEnd.
    positionStart = 0;
    range = document.selection.createRange();
    positionEnd = range.text.length;
    range.moveStart("character", -el.value.length);
    positionStart = range.text.length - positionEnd;
    positionEnd = positionStart + positionEnd;
  } else {
    positionStart = el.selectionStart;
    positionEnd = el.selectionEnd;
  }
  return {"start"   : positionStart,
          "end"     : positionEnd,
          "isRange" : positionStart !== positionEnd};
}

function setCaretPosition(el, position) {
  var range;
  if (document.selection) {
    // IE specific code because they don't have a nice way to get
    // selectionStart and selectionEnd.
    range = document.selection.createRange();
    range.moveStart("character", position);
    range.moveEnd("character", 0);
    range.select();
  } else {
    el.selectionEnd = el.selectionStart = position;
  }
}

function moveCaret_keyDown(e, leftElId, rightElId) {
  var keyCode, el, maxLength, caretPosition, moveToEl;
  keyCode = e.keyCode ? e.keyCode : e.which;
  // The following keyCodes always pass
  switch (keyCode) {
    case 9:  // tab
    case 13: // enter
    case 16: // shift
    case 17: // ctrl
    case 18: // alt
    case 20: // capslock
    case 27: // esc
    case 33: // page up
    case 34: // page down
    case 35: // end
    case 36: // home
    case 38: // up arrow
    case 40: // down arrow
    case 46: // delete
      return true;
  }
  el = YAHOO.util.Event.getTarget(e);
  maxLength = parseInt(el.getAttribute("maxlength"), 10);
  caretPosition = getCaretPosition(el);
  // The following keyCodes may move between boxes
  switch (keyCode) {
    case 8:  // backspace
    case 37: // left arrow
      // Moving Left - If at the beginning move to leftElId if exists
      if (!caretPosition.isRange && caretPosition.start === 0) {
        moveToEl = document.getElementById(leftElId);
      }
  }
  if (!moveToEl) {
    return true;
  }
  moveToEl.focus();
  maxLength = parseInt(moveToEl.getAttribute("maxlength"), 10);
  setCaretPosition(moveToEl, maxLength);
}

function moveCaret_keyUp(e, leftElId, rightElId) {
  var keyCode, el, maxLength, caretPosition, moveToEl;
  keyCode = e.keyCode ? e.keyCode : e.which;
  // The following keyCodes always pass
  switch (keyCode) {
    case 9:  // tab
    case 13: // enter
    case 16: // shift
    case 17: // ctrl
    case 18: // alt
    case 20: // capslock
    case 27: // esc
    case 33: // page up
    case 34: // page down
    case 35: // end
    case 36: // home
    case 38: // up arrow
    case 40: // down arrow
    case 46: // delete
      return true;
  }
  el = YAHOO.util.Event.getTarget(e);
  maxLength = parseInt(el.getAttribute("maxlength"), 10);
  caretPosition = getCaretPosition(el);
  // Moving Right - If at the end move to rightEl if exists
  if (!caretPosition.isRange && caretPosition.start === maxLength) {
    moveToEl = document.getElementById(rightElId);
  }
  if (!moveToEl) {
    return true;
  }
  moveToEl.focus();
  setCaretPosition(moveToEl, 0);
}
